//+------------------------------------------------------------------+ //| Main.mqh | //| Copyright 2025, Niquel Mendoza. | //| https://www.mql5.com/es/users/nique_372 | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Niquel Mendoza." #property link "https://www.mql5.com/es/users/nique_372" #property strict //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "..\\..\\..\\DefGlobal.mqh" //--- // Notas: // 1. Solo se permite dibujar el bloque.. como tal no agregados... si es necesario lo podria agregar.. por ahora creo que no // 2. Llamo a las funciones Timeframe, ChartId, Subwin por que estos pueden ser volatiles.. no son fijos auqnue estos ultimos no pero pronto... //#define USE_TICK //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define ICTLIB_CUSTOMBLOCK_FVG_ID 0 //--- #ifdef USE_TICK #define ICTLIB_BLOCK_HIDE(bloque) HIDE_OBJECT(bloque.name, ICTCustomBlocksTick_ChartId(m_handle)); \ HIDE_OBJECT(bloque.name_mitad_line, ICTCustomBlocksTick_ChartId(m_handle)); #else #define ICTLIB_BLOCK_HIDE(bloque) HIDE_OBJECT(bloque.name, ICTCustomBlocksBar_ChartId(m_handle)); \ HIDE_OBJECT(bloque.name_mitad_line, ICTCustomBlocksBar_ChartId(m_handle)); #endif //--- class CCustomFvg : public IIctLibCustomBlock { private: MqlRates m_rates[]; public: CCustomFvg(void) {} ~CCustomFvg(void) {} //--- void OnSummary() const override final { Print(" Handle: ", m_handle); } void Init(const IctLibBloqueInitConfig& config) override final; void Draw(const Bloques& bloque, const ENUM_ORDERBLOCKS_TYPE type, const bool show_objetcs, const datetime extra_time); void OnGetBlocks(bool& prev_data_calculated, const datetime extra_time, const bool show_concepts) override final; //--- inline int Id() const override final { return ICTLIB_CUSTOMBLOCK_FVG_ID; } // Id para distinguir de otros bloques custom inline bool UpdateConcepts() const override final { return false; } // Actuliza los conceptos (rectangulos) inline uint8_t ModifyFlags() const override final { return ICTCOMPONENT_ALL_FLAGS_MODIFY; } // Banderas de modificacion (en este caso todas) }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CCustomFvg::OnGetBlocks(bool& prev_data_calculated, const datetime extra_time, const bool show_concepts) { //--- #ifdef USE_TICK ResetLastError(); if(CopyRates(m_symbol_info.symbol, ICTCustomBlocksTick_Timeframe(m_handle), 1, 3, m_rates) != 3) { LogError("No se pudo obtener data", FUNCION_ACTUAL); return; } #else ResetLastError(); if(CopyRates(m_symbol_info.symbol, ICTCustomBlocksBar_Timeframe(m_handle), 1, 3, m_rates) != 3) { LogError("No se pudo obtener data", FUNCION_ACTUAL); return; } #endif //--- if(!prev_data_calculated) // SI no se calculo la data previa (entonces en teroia deberiamos de hacelro, en este caso NO.. para este ejemplo) { prev_data_calculated = true; // Ponemos que ya se calculo // return false;// Omitimos esta llamada } // En caso se soporte se debera de veriicar que no haya sido mitigado para eso puede incluir el modeulo Functions.. // Y llamar a las funciones mitigados alcista o mitigados bajista... para verificar que el bloque a añadir No este mitigado //--- const int one_vela = 2; const int two_vela = 1; const int tree_vela = 0; //--- static Bloques blocke; //--- if(m_rates[tree_vela].low > m_rates[one_vela].high && m_rates[two_vela].close > m_rates[two_vela].open) { blocke.price1 = m_rates[one_vela].high; blocke.price2 = m_rates[tree_vela].low; blocke.time1 = m_rates[two_vela].time; blocke.name = m_bull_code + TimeToString(blocke.time1); blocke.name_mitad_line = blocke.name + "-50"; blocke.mitad_price = GetPriceCoeficiente(blocke.price1, blocke.price2, 0.5); if(m_handler.Add(blocke, BULL_OB)) Draw(blocke, BULL_OB, show_concepts, extra_time); } else if(m_rates[one_vela].low > m_rates[tree_vela].high && m_rates[two_vela].open > m_rates[two_vela].close) { blocke.price1 = m_rates[one_vela].low; blocke.price2 = m_rates[tree_vela].high; blocke.time1 = m_rates[two_vela].time; blocke.name = m_bear_code + TimeToString(blocke.time1); blocke.name_mitad_line = blocke.name + "-50"; blocke.mitad_price = GetPriceCoeficiente(blocke.price1, blocke.price2, 0.5); if(m_handler.Add(blocke, BEAR_OB)) Draw(blocke, BEAR_OB, show_concepts, extra_time); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CCustomFvg::Init(const IctLibBloqueInitConfig &config) { //--- m_obj_code = config.obj_code; m_handle = config.handle; //--- m_symbol_info = config.symbol_info; m_handler = config.handler; //--- m_name_bull_toltip = config.name_bull_toltip; m_name_bear_toltip = config.name_bear_toltip; m_name_bull_toltip_50 = config.name_bull_toltip_50; m_name_bear_toltip_50 = config.name_bear_toltip_50; m_bull_code = config.bull_code; m_bear_code = config.bear_code; //--- m_clr_bloque_alcista = config.clr_bloque_alcista; m_clr_bloque_bajista = config.clr_bloque_bajista; m_style_block = config.style_block; m_fill = config.fill; m_width = config.width; //--- m_mostrar_la_mitad = config.mostrar_la_mitad; m_line_style_mitad = config.line_style_mitad; m_width_line_mitad = config.width_line_mitad; m_clr_mitad_bloque_alcista = config.clr_mitad_bloque_alcista; m_clr_mitad_bloque_bajista = config.clr_mitad_bloque_bajista; //--- ArraySetAsSeries(m_rates, true); ArrayResize(m_rates, 0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CCustomFvg::Draw(const Bloques& bloque, const ENUM_ORDERBLOCKS_TYPE type, const bool show_objetcs, const datetime extra_time) { #ifdef USE_TICK //--- if(!ICTCustomBlocksTick_GetInittialStateObj(m_handle)) // Si por default no dibujar no lo hacemos return; //--- if(type == BULL_OB) { TSN::CNativeoGObjs::RectangleCreate(ICTCustomBlocksTick_ChartId(m_handle), bloque.name, ICTCustomBlocksTick_Subwin(m_handle), bloque.time1, bloque.price1, extra_time, bloque.price2, m_clr_bloque_alcista, m_width, m_fill, true, false, m_style_block, m_name_bull_toltip); if(m_mostrar_la_mitad) { TSN::CNativeoGObjs::TrendCreate(ICTCustomBlocksTick_ChartId(m_handle), bloque.name_mitad_line, ICTCustomBlocksTick_Subwin(m_handle), bloque.time1, bloque.mitad_price, extra_time, bloque.mitad_price, m_clr_mitad_bloque_alcista, m_line_style_mitad, m_width_line_mitad, true, false, m_name_bull_toltip_50); } } else { TSN::CNativeoGObjs::RectangleCreate(ICTCustomBlocksTick_ChartId(m_handle), bloque.name, ICTCustomBlocksTick_Subwin(m_handle), bloque.time1, bloque.price1, extra_time, bloque.price2, m_clr_bloque_bajista, m_width, m_fill, true, false, m_style_block, m_name_bear_toltip); if(m_mostrar_la_mitad) { TSN::CNativeoGObjs::TrendCreate(ICTCustomBlocksTick_ChartId(m_handle), bloque.name_mitad_line, ICTCustomBlocksTick_Subwin(m_handle), bloque.time1, bloque.mitad_price, extra_time, bloque.mitad_price, m_clr_mitad_bloque_bajista, m_line_style_mitad, m_width_line_mitad, true, false, m_name_bear_toltip_50); } } #else //--- if(!ICTCustomBlocksBar_GetInittialStateObj(m_handle)) // Si por default no dibujar no lo hacemos return; //--- if(type == BULL_OB) { TSN::CNativeoGObjs::RectangleCreate(ICTCustomBlocksBar_ChartId(m_handle), bloque.name, ICTCustomBlocksBar_Subwin(m_handle), bloque.time1, bloque.price1, extra_time, bloque.price2, m_clr_bloque_alcista, m_width, m_fill, true, false, m_style_block, m_name_bull_toltip); if(m_mostrar_la_mitad) { TSN::CNativeoGObjs::TrendCreate(ICTCustomBlocksBar_ChartId(m_handle), bloque.name_mitad_line, ICTCustomBlocksBar_Subwin(m_handle), bloque.time1, bloque.mitad_price, extra_time, bloque.mitad_price, m_clr_mitad_bloque_alcista, m_line_style_mitad, m_width_line_mitad, true, false, m_name_bull_toltip_50); } } else { TSN::CNativeoGObjs::RectangleCreate(ICTCustomBlocksBar_ChartId(m_handle), bloque.name, ICTCustomBlocksBar_Subwin(m_handle), bloque.time1, bloque.price1, extra_time, bloque.price2, m_clr_bloque_bajista, m_width, m_fill, true, false, m_style_block, m_name_bear_toltip); if(m_mostrar_la_mitad) { TSN::CNativeoGObjs::TrendCreate(ICTCustomBlocksBar_ChartId(m_handle), bloque.name_mitad_line, ICTCustomBlocksBar_Subwin(m_handle), bloque.time1, bloque.mitad_price, extra_time, bloque.mitad_price, m_clr_mitad_bloque_bajista, m_line_style_mitad, m_width_line_mitad, true, false, m_name_bear_toltip_50); } } #endif //--- if(!show_objetcs) { ICTLIB_BLOCK_HIDE(bloque) } } //+------------------------------------------------------------------+