| //+------------------------------------------------------------------+
|
| //| 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)
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|