2025-12-21 22:00:56 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| 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"
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
2026-10-23 21:51:38 -05:00 | | | class CEstrategia : public TSN::CStrategyBase
|
2025-12-21 22:00:56 -05:00 | | | {
|
| | | private:
|
| | | double asia_mitad;
|
| | | double diff_mitad;
|
| | | double entry_price;
|
| | | double rr_tp_sl;
|
| | | int hora_inicio_ny, min_inicio_ny;
|
| | | ENUM_TYPE_TP_SL type_tp_sl;
|
| | | bool is_trade;
|
| | | datetime fin_ny;
|
| | | ENUM_POSITION_TYPE last_open;
|
| | | bool is_open;
|
| | |
|
| | | //---
|
| | | void OpenOrder(ENUM_POSITION_TYPE type);
|
| | |
|
| | | public:
|
| | | CEstrategia(ulong magic_number_, string symbol_, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0, int subiwn_ = 0, ulong max_deviation_ = NO_MAX_DEVIATION_DEFINED);
|
| | |
|
| | |
|
| | | void SetNy(int hora_init_ny, int min_init_ny);
|
| | | void SetGen(double rr_, ENUM_TYPE_TP_SL type_tp_sl_) { this.rr_tp_sl = rr_; this.type_tp_sl = type_tp_sl_; }
|
2026-02-14 17:50:28 -05:00 | | | void OnNewBar(const datetime curr_time) override final;
|
| | | void OnTick(const datetime curr_time) override final {}
|
2025-12-21 22:00:56 -05:00 | | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | CEstrategia::CEstrategia(ulong magic_number_, string symbol_, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0, int subiwn_ = 0, ulong max_deviation_ = NO_MAX_DEVIATION_DEFINED)
|
2026-02-01 13:11:51 -05:00 | | | : CStrategyBase(magic_number_, symbol_, timeframe_, chart_id_, subiwn_, max_deviation_, "ETN2")
|
2025-12-21 22:00:56 -05:00 | | | {
|
| | | is_open = false;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | void CEstrategia::SetNy(int hora_init_ny, int min_init_ny)
|
| | | {
|
| | | this.hora_inicio_ny = hora_init_ny;
|
| | | this.min_inicio_ny = min_init_ny;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | void CEstrategia::OpenOrder(ENUM_POSITION_TYPE type)
|
| | | {
|
| | | ResetLastError();
|
| | | SymbolInfoTick(this.m_symbol, m_tick);
|
| | |
|
| | | if(type == POSITION_TYPE_SELL)
|
| | | {
|
| | | double tp = 0, sl = 0;
|
| | | this.last_open = POSITION_TYPE_SELL;
|
| | |
|
| | | if(type_tp_sl == TP_SL_BY_STRATEGY_RR)
|
| | | {
|
| | | //--- primer paso tp
|
| | | tp = sesion_asia.GetMinSession() - diff_mitad;
|
| | | double diff_tp = entry_price - tp;
|
| | | //--- segundo paso sl
|
| | | sl = entry_price + (diff_tp / 2.0); //Relacion riesgo 1 : 2 para empezar con el sl
|
| | | double sl_diff = MathAbs(sl - entry_price);
|
| | | //--- recalculamos el tp para que quede 1:3
|
| | | tp = entry_price - (sl_diff * rr_tp_sl);
|
| | | }
|
| | | else
|
| | | {
|
| | | tp = GetTP(entry_price, POSITION_TYPE_SELL, m_tick.time);
|
| | | sl = GetSL(entry_price, POSITION_TYPE_SELL, m_tick.time);
|
| | | }
|
| | |
|
2026-11-01 22:12:14 -05:00 | | | risk.SetStopLoss(m_symbol, sl - entry_price);
|
2025-12-21 22:00:56 -05:00 | | | double l = m_LOT_SIZE > 0.00 ? m_LOT_SIZE : risk.GetLote(ORDER_TYPE_SELL_LIMIT, entry_price, m_max_deviation, 0);
|
| | | datetime expiration = HoraYMinutoADatetime(hora_inicio_ny, min_inicio_ny, m_tick.time); //Pones la expiracion en el inicio de ni
|
| | | fin_ny = expiration;
|
| | |
|
| | | if(!m_trade.SellLimit(l, entry_price, this.m_symbol, sl, tp, ORDER_TIME_SPECIFIED, expiration, "Ea sell limit") )
|
| | | LogError(StringFormat("Error al abrir sell limit, ultimo error = %d", GetLastError()), FUNCION_ACTUAL);
|
| | | }
|
| | | else
|
| | | if(type == POSITION_TYPE_BUY)
|
| | | {
|
| | | this.last_open = POSITION_TYPE_BUY;
|
| | | double tp = 0, sl = 0;
|
| | |
|
| | | if(type_tp_sl == TP_SL_BY_STRATEGY_RR)
|
| | | {
|
| | | //--- primer paso tp
|
| | | tp = sesion_asia.GetMaxSession() + diff_mitad;
|
| | | double diff_tp = MathAbs(tp - entry_price);
|
| | | //--- segundo paso sl
|
| | | sl = entry_price - (diff_tp / 2.0); //Relacion riesgo 1 : 2 para empezar con el sl
|
| | | double sl_diff = MathAbs(entry_price - sl);
|
| | | //--- recalculamos el tp para que quede 1:3
|
| | | tp = entry_price + (sl_diff * rr_tp_sl);
|
| | | }
|
| | | else
|
| | | {
|
| | | tp = GetTP(entry_price, POSITION_TYPE_BUY, m_tick.time);
|
| | | sl = GetSL(entry_price, POSITION_TYPE_BUY, m_tick.time);
|
| | | }
|
| | |
|
2026-11-01 22:12:14 -05:00 | | | risk.SetStopLoss(m_symbol, entry_price - sl);
|
2025-12-21 22:00:56 -05:00 | | | double l = m_LOT_SIZE > 0.00 ? m_LOT_SIZE : risk.GetLote(ORDER_TYPE_BUY_LIMIT, entry_price, m_max_deviation, 0);
|
| | | datetime expiration = HoraYMinutoADatetime(hora_inicio_ny, min_inicio_ny, m_tick.time); //Pones la expiracion en el inicio de ni
|
| | | fin_ny = expiration;
|
| | |
|
| | | if(!m_trade.BuyLimit(l, entry_price, this.m_symbol, sl, tp, ORDER_TIME_SPECIFIED, expiration, "Ea buy limit"))
|
| | | LogError(StringFormat("Error al abrir buy limit, ultimo error = %d", GetLastError()), FUNCION_ACTUAL);
|
| | | }
|
| | | is_open = true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
2026-02-14 17:50:28 -05:00 | | | void CEstrategia::OnNewBar(const datetime curr_time)
|
2025-12-21 22:00:56 -05:00 | | | {
|
| | | if(trading_session.IsInitSession()) //Paso 1 abrir operaciones
|
| | | {
|
| | | LogInfo("Inicio la sesion, poniendo las ordenes..", FUNCION_ACTUAL);
|
| | | LogInfo(StringFormat("Maximo %.*f | Minimo %.*f", m_digits, sesion_asia.GetMaxSession(), m_digits, sesion_asia.GetMinSession()), FUNCION_ACTUAL);
|
| | |
|
| | | this.asia_mitad = sesion_asia.GetMinSession() + (sesion_asia.GetRangeSession() / 2.0);
|
| | | double close_prev = iClose(this.m_symbol, this.m_timeframe, 1);
|
| | | LogInfo(StringFormat("La mitad de asia %.*f | El cierre anterior %.*f", m_digits, this.asia_mitad, m_digits, close_prev), FUNCION_ACTUAL);
|
| | |
|
| | | this.diff_mitad = (sesion_asia.GetRangeSession() / 2.0);
|
| | |
|
| | | if(close_prev > asia_mitad)
|
| | | {
|
| | | this.entry_price = sesion_asia.GetMaxSession();
|
| | | OpenOrder(POSITION_TYPE_SELL);
|
| | | }
|
| | | else
|
| | | if(close_prev < asia_mitad)
|
| | | {
|
| | | this.entry_price = sesion_asia.GetMinSession();
|
| | | OpenOrder(POSITION_TYPE_BUY);
|
| | | }
|
| | | }
|
| | | else
|
| | | if(trading_session.IsEndSession()) //Paso 2 modificar la orden si ha cambiado de posicion
|
| | | {
|
| | | LogInfo("Fin de la sesion, revisando si se cambio de direccion", FUNCION_ACTUAL);
|
| | | double close_prev = iClose(this.m_symbol, this.m_timeframe, 1);
|
| | |
|
| | | if(close_prev > asia_mitad && last_open == POSITION_TYPE_BUY) //Si la posicion inicial era buy limit y se detecta venta cambiamos
|
| | | {
|
| | | this.entry_price = sesion_asia.GetMaxSession();
|
| | | LogInfo("La direccion del mercado a cambiado de compra - venta ", FUNCION_ACTUAL);
|
2026-10-23 21:51:38 -05:00 | | | TSN::CRmFunctions::CloseAllOrders(TSN::ALL_FLAGS_LIMITS, m_trade, m_magic_number);
|
2025-12-21 22:00:56 -05:00 | | | OpenOrder(POSITION_TYPE_SELL);
|
| | |
|
| | | }
|
| | | else
|
| | | if(close_prev < asia_mitad && last_open == POSITION_TYPE_SELL)
|
| | | {
|
| | | this.entry_price = sesion_asia.GetMinSession();
|
| | | LogInfo("La direccion del mercado a cambiado de venta - compra", FUNCION_ACTUAL);
|
2026-10-23 21:51:38 -05:00 | | | TSN::CRmFunctions::CloseAllOrders(TSN::ALL_FLAGS_LIMITS, m_trade, m_magic_number);
|
2025-12-21 22:00:56 -05:00 | | | OpenOrder(POSITION_TYPE_BUY);
|
| | | }
|
| | | }
|
| | |
|
| | | if(!is_open) //Si no hay posiciones abiertas no ejecutamos el codigo que esta delante de esta condicion
|
| | | return;
|
| | |
|
| | | if(curr_time >= fin_ny) //Verificamos si la sesion de ny finaliza para cerrar todas las ordenes abiertas
|
| | | {
|
| | | risk.CloseAllPositions();
|
| | | is_open = false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|