| //+------------------------------------------------------------------+
|
| //| 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"
|
| // Source: https://www.youtube.com/watch?v=o0v4KQxZbpU&t=183s
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| class CEstrategia : public TSN::CStrategyBase
|
| {
|
| private:
|
| bool m_operate;
|
| ENUM_EASYSB_STATE m_state;
|
| double m_max_9;
|
| double m_min_9;
|
|
|
| //---
|
| void Clean();
|
| void OpenOrder(ENUM_POSITION_TYPE type);
|
|
|
| public:
|
|
|
| CEstrategia(ulong magic_number_, string symbol_, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0,
|
| int subwindow_ = 0, ulong max_deviation_ = NO_MAX_DEVIATION_DEFINED);
|
| ~CEstrategia(void);
|
|
|
| //---
|
| void OnNewBar(const datetime curr_time) override;
|
| void OnNewWeek(const datetime curr_time) override;
|
| void OnInterupcion();
|
| void OnTick(const datetime curr_time) override {}
|
| };
|
|
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| CEstrategia::CEstrategia(ulong magic_number_, string symbol_, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0, int subwindow_ = 0, ulong max_deviation_ = 0)
|
| : CStrategyBase(magic_number_, symbol_, timeframe_, chart_id_, subwindow_, max_deviation_, "TTRdes sb")
|
| {
|
| CBasicEvents::RegisterEvent(&this, BASICEVENT_REG_FLAG_ON_NEW_WEEK);
|
| Clean();
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| 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);
|
| }
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| void CEstrategia::OnNewWeek(const datetime curr_time)
|
| {
|
| g_bos_choch.DeleteAll();
|
| g_bloque1.DeleteAll();
|
| g_bloque2.DeleteAll();
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| void CEstrategia::Clean(void)
|
| {
|
| m_state = EASYSB_STATE_BUSCAR_MANIPULACION;
|
| m_max_9 = 0.000;
|
| m_min_9 = 0.000;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| void CEstrategia::OnInterupcion()
|
| {
|
| g_bloque1.SetParo();
|
| g_bloque2.SetParo();
|
| g_bos_choch.SetParo();
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| void CEstrategia::OnNewBar(const datetime curr_time)
|
| {
|
| if(risk.GetPositionsTotal() > 0)
|
| return;
|
|
|
|
|
| //---
|
| if(g_sesion.EnSesion())
|
| {
|
| //--- Al inciar la sesion
|
| if(g_sesion.IsInitSession())
|
| {
|
| LogInfo("Inicio de sesion", FUNCION_ACTUAL);
|
| m_max_9 = ::iHigh(m_symbol, PERIOD_H1, 1);
|
| m_min_9 = ::iLow(m_symbol, PERIOD_H1, 1);
|
| m_operate = false;
|
| }
|
|
|
| //---
|
| if(m_operate)
|
| return;
|
|
|
| //---
|
| // NOTA: noramltle el stado se setea cuando cumple la condicion y reicne en la siguinte call (osea la siuinte vela) es donde comenzamos
|
| // en teoria se podira hacer ahora "mismo" con un do while(false) pero es para seguir las reglas
|
| //--- Ahora si logica de la estrategia
|
| switch(m_state)
|
| {
|
| //--- Inicamte indecismos no sabemos que bsucamos solo sbucamos una maniapcion ya hi decidimos direccion
|
| case EASYSB_STATE_BUSCAR_MANIPULACION:
|
| {
|
| const double prev_high = ::iHigh(m_symbol, m_timeframe, 1);
|
| const double prev_low = ::iLow(m_symbol, m_timeframe, 1);
|
|
|
| if(prev_high > m_max_9) // manipula el high
|
| {
|
| m_state = EASYSB_STATE_BUSCAR_CONFIRMACION_BOS_BAJISTA;
|
| }
|
| else
|
| if(m_min_9 > prev_low) // manipula el low
|
| {
|
| m_state = EASYSB_STATE_BUSCAR_CONFIRMACION_BOS_ALCISTA;
|
| }
|
| break;
|
| }
|
|
|
| //--- Busqueda de la confirmacion
|
| case EASYSB_STATE_BUSCAR_CONFIRMACION_BOS_ALCISTA:
|
| {
|
| if(g_bos_choch.NuevaRopturaAlAlza())
|
| {
|
| m_state = EASYSB_STATE_BUSCAR_PDA_ALCISTA; // pda alcista
|
| }
|
| break;
|
| }
|
| case EASYSB_STATE_BUSCAR_CONFIRMACION_BOS_BAJISTA:
|
| {
|
| if(g_bos_choch.NuevaRopturaAlaBaja())
|
| {
|
| m_state = EASYSB_STATE_BUSCAR_PDA_BAJISTA; // pda bajista
|
| }
|
| break;
|
| }
|
|
|
| //--- Entrada final
|
| case EASYSB_STATE_BUSCAR_PDA_ALCISTA:
|
| {
|
| if(g_bloque1.SizeAlcistasMitigados() > 0 || g_bloque2.SizeAlcistasMitigados() > 0)
|
| OpenOrder(POSITION_TYPE_BUY);
|
| break;
|
| }
|
| case EASYSB_STATE_BUSCAR_PDA_BAJISTA:
|
| {
|
| if(g_bloque1.SizeBajistasMitigados() > 0 || g_bloque2.SizeBajistasMitigados() > 0)
|
| OpenOrder(POSITION_TYPE_SELL);
|
| break;
|
| }
|
| default:
|
| break;
|
| }
|
|
|
| }
|
| else
|
| if(g_sesion.IsEndSession())
|
| {
|
| LogInfo("Fin de sesion", FUNCION_ACTUAL);
|
| Clean();
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //+------------------------------------------------------------------+
|
| //| 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();
|
| m_operate = true;
|
| }
|
| //+------------------------------------------------------------------+
|