//+------------------------------------------------------------------+ //| Main.mqh | //| Copyright 2025, Niquel Mendoza. | //| https://www.mql5.com/es/users/nique_372/news | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Niquel Mendoza." #property link "https://www.mql5.com/es/users/nique_372/news" #property strict //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "Defines.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CEstrategia : public TSN::CStrategyBase { private: ENUM_CRT_STATE m_state; bool m_draw_line; // dibuja la linea de roptura del modelo crt ENUM_TIMEFRAMES m_timeframe_htf_crt; int8_t m_index_controler_fast_htf_crt; CrtModel m_current_crt_model; int m_secods_in_period_htf; //--- void CheckCrt(); //--- void Clean(); //--- void OpenOrder(ENUM_POSITION_TYPE type); public: CEstrategia(ulong magic_number_, string symbol_, bool draw_line, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0, int subwindow_ = 0, ulong max_deviation_ = NO_MAX_DEVIATION_DEFINED); ~CEstrategia(void); //--- void Set(ENUM_TIMEFRAMES timeframe_crt_htf); //--- void OnNewBar(const datetime curr_time) override final; void OnTick(const datetime curr_time) override final { } //--- void OnNewWeek(const datetime curr_time) override final; //--- void OnInterupcion() override final; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CEstrategia::CEstrategia(ulong magic_number_, string symbol_, bool draw_line, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0, int subwindow_ = 0, ulong max_deviation_ = NO_MAX_DEVIATION_DEFINED) : CStrategyBase(magic_number_, symbol_, timeframe_, chart_id_, subwindow_, max_deviation_, "TradingLabCrt"), m_timeframe_htf_crt(WRONG_VALUE), m_index_controler_fast_htf_crt(INVALID_INDEX), m_draw_line(draw_line) { //--- CBasicEvents::RegisterEvent(&this, BASICEVENT_REG_FLAG_ON_NEW_WEEK); Clean(); //--- m_current_crt_model.name = string(s_rand.nextUInt32()) + "_line_rop_"; // id propio if(m_draw_line) TSN::CNativeoGObjs::TrendCreate(m_chart_id, m_current_crt_model.name, m_subwindow, 0, 0, 0, 0, clrRed, STYLE_SOLID, 1, true, false, "LineaRop"); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CEstrategia::~CEstrategia(void) { if(CBasicEvents::IsActive()) // CONSULTAMOS si aun esta activo { // Si esta activo entonces nos desuscribirremos CBasicEvents::UnregisterEvent(&this, BASICEVENT_REG_FLAG_ON_NEW_WEEK); } //--- Linea de roptura (solo si se dibujo) if(m_draw_line) ::ObjectDelete(m_chart_id, m_current_crt_model.name); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::Set(ENUM_TIMEFRAMES timeframe_crt_htf) { g_new_bar_manager.GetPosExecute(timeframe_crt_htf, m_index_controler_fast_htf_crt); m_timeframe_htf_crt = timeframe_crt_htf; m_secods_in_period_htf = TSN::CTimeframe::PeriodSecondsFast(timeframe_crt_htf); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::OnInterupcion() { g_fvg.SetParo(); g_ob.SetParo(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::OnNewWeek(const datetime curr_time) { g_fvg.DeleteAll(); g_ob.DeleteAll(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::Clean(void) { m_state = CRT_STATE_ESPERAR_MODELO; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::CheckCrt(void) { //--- m_current_crt_model.direction = WRONG_VALUE; m_current_crt_model.price_to_superate = 0.00; //--- const double prev_prev_high = iHigh(m_symbol, m_timeframe_htf_crt, 2); const double prev_prev_low = iLow(m_symbol, m_timeframe_htf_crt, 2); //--- const double prev_high = iHigh(m_symbol, m_timeframe_htf_crt, 1); const double prev_low = iLow(m_symbol, m_timeframe_htf_crt, 1); const double prev_close = iClose(m_symbol, m_timeframe_htf_crt, 1); const double prev_open = iOpen(m_symbol, m_timeframe_htf_crt, 1); //--- if(prev_close > prev_open) // Buscar manipuacion de bajo modelo compra { if(prev_prev_low > prev_low && prev_open > prev_prev_low && prev_prev_high > prev_high) { m_current_crt_model.direction = CRT_DIR_ARRIBA; m_current_crt_model.price_to_superate = prev_high; // Roptura de este precio if(m_draw_line) { const datetime prev_time = iTime(m_symbol, m_timeframe_htf_crt, 1); ObjectMove(m_chart_id, m_current_crt_model.name, 0, prev_time, prev_high); ObjectMove(m_chart_id, m_current_crt_model.name, 1, prev_time + (m_secods_in_period_htf * 2), prev_high); } } } else if(prev_close < prev_open) // Buscar manipuacion de alto modelo venta { if(prev_high > prev_prev_high && prev_prev_high > prev_open && prev_low > prev_prev_low) { m_current_crt_model.direction = CRT_DIR_ABAJO; m_current_crt_model.price_to_superate = prev_low; // Roptura de este precio if(m_draw_line) { const datetime prev_time = iTime(m_symbol, m_timeframe_htf_crt, 1); ObjectMove(m_chart_id, m_current_crt_model.name, 0, prev_time, prev_low); ObjectMove(m_chart_id, m_current_crt_model.name, 1, prev_time + (m_secods_in_period_htf * 2), prev_low); } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::OnNewBar(const datetime curr_time) { //--- if(risk.GetPositionsTotal() > 0) return; //--- if(CNewBarManager_IsNewBar(g_new_bar_manager, m_index_controler_fast_htf_crt)) { Clean(); //--- CheckCrt(); //--- if(m_current_crt_model.direction != WRONG_VALUE) m_state = CRT_STATE_BUSCAR_ROPTURA; LogInfo(StringFormat("Direccion buscada: %s", EnumToString(m_current_crt_model.direction)), FUNCION_ACTUAL); } //--- Un paso por llamada. El modelo (arriba) y la roptura se evaluan en la misma llamada, el pda en las siguientes switch(m_state) { //--- Hay modelo: esperamos la roptura del high/low previo del htf case CRT_STATE_BUSCAR_ROPTURA: { const double prev_close = iClose(m_symbol, m_timeframe, 1); if(m_current_crt_model.direction == CRT_DIR_ARRIBA && prev_close > m_current_crt_model.price_to_superate) // COmpra, roptura del high previo para 1er paso { LogInfo("Roptura del high concretada", FUNCION_ACTUAL); m_state = CRT_STATE_BUSCAR_PDA_ALCISTA; } else if(m_current_crt_model.direction == CRT_DIR_ABAJO && m_current_crt_model.price_to_superate > prev_close) // Venta, roptura del low { LogInfo("Roptura del low concretada", FUNCION_ACTUAL); m_state = CRT_STATE_BUSCAR_PDA_BAJISTA; } break; } //--- Roptura concretada: buscamos que un pda sea tocado dentro de una sesion case CRT_STATE_BUSCAR_PDA_ALCISTA: { if(g_sesiones.GetSesionActualIdx() != INVALID_SESION && g_pdas.PdaBullIsTouched()) OpenOrder(POSITION_TYPE_BUY); break; } case CRT_STATE_BUSCAR_PDA_BAJISTA: { if(g_sesiones.GetSesionActualIdx() != INVALID_SESION && g_pdas.PdaBearIsTouched()) OpenOrder(POSITION_TYPE_SELL); break; } default: break; } } //+------------------------------------------------------------------+ //| Open Order Default | //+------------------------------------------------------------------+ void CEstrategia::OpenOrder(ENUM_POSITION_TYPE type) { SymbolInfoTick(m_symbol, m_tick); if(type == POSITION_TYPE_BUY) { double entry = m_tick.ask; double sl = GetSL(entry, type, m_tick.time); double tp = GetTP(entry, type, m_tick.time); risk.SetStopLoss(m_symbol, entry - sl); double l = m_LOT_SIZE > 0.00 ? m_LOT_SIZE : risk.GetLote(ORDER_TYPE_BUY, entry, m_max_deviation, 0); m_trade.Buy(l, m_symbol, entry, sl, tp, "Ea buy"); } else if(type == POSITION_TYPE_SELL) { double entry = m_tick.bid; double sl = GetSL(entry, type, m_tick.time); double tp = GetTP(entry, type, m_tick.time); risk.SetStopLoss(m_symbol, sl - entry); double l = m_LOT_SIZE > 0.00 ? m_LOT_SIZE : risk.GetLote(ORDER_TYPE_SELL, entry, m_max_deviation, 0); m_trade.Sell(l, m_symbol, entry, sl, tp, "Ea sell"); } Clean(); } //+------------------------------------------------------------------+