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