//+------------------------------------------------------------------+ //| StrategyAO.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 #ifndef MQLARTICLES_STRATEGY_DRV_AO_MAIN_MQH #define MQLARTICLES_STRATEGY_DRV_AO_MAIN_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "..\\..\\Core\\Base.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CStrategyAO : public CStrategyBase { protected: //--- Atr para auto-optimizacion (simulacion) int m_simulation_atr_handle; double m_simulation_atr_arr[]; bool m_in_simulate_mode; bool CopyDataAtrSimulate(int start, int count); //--- Hooks virtual bool OnSimulationStart() { return true; } virtual void OnSimulationEnd() { } public: CStrategyAO(ulong magic_number_, string symbol_, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0, int subwindow_ = 0, ulong max_deviation_ = NO_MAX_DEVIATION_DEFINED, string name = "Strategy"); ~CStrategyAO(void); //--- using CStrategyBase::GetSL; using CStrategyBase::GetTP; double GetSL(double entry_price, ENUM_POSITION_TYPE position_type, datetime curr_time, int index); double GetTP(double entry_price, ENUM_POSITION_TYPE position_type, datetime curr_time, int index); //--- Funciones de seteo void SetAtrTP_SLOptimizer(int handle); //--- Funciones para la simulacion de la estrategia - para la autooptimizacion virtual bool SimulateBar(int index, double open, double high, double low, double close, datetime time, long tick_volume, const float &genes[], OptimizationOrderTime &trades[]) { return false; } // En la simulacion de una vela bool OnInitSimulate(int start, int count); // Al inicio de la simuation (vela start numero de velas) void OnEndSimulate();// Al finalizar la simulacion //--- Getters extra inline bool InSimulation() const { return m_in_simulate_mode; } inline int SimulationAtrHandle() const { return m_simulation_atr_handle; } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CStrategyAO::CStrategyAO(ulong magic_number_, string symbol_, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0 , int subwindow_ = 0, ulong max_deviation_ = 0, string name = "Strategy") : CStrategyBase(magic_number_, symbol_, timeframe_, chart_id_, subwindow_, max_deviation_, name), m_simulation_atr_handle(INVALID_HANDLE), m_in_simulate_mode(false) { //--- ::ArraySetAsSeries(m_simulation_atr_arr, true); ::ArrayResize(m_simulation_atr_arr, 0); } //+------------------------------------------------------------------+ //| Funciones para la simulacion | //+------------------------------------------------------------------+ bool CStrategyAO::CopyDataAtrSimulate(int start, int count) { ::ResetLastError(); if(::CopyBuffer(m_simulation_atr_handle, 0, start, count, m_simulation_atr_arr) < count) { LogError(::StringFormat("No se pudieron copiar datos del atr, ultimo error= %d", GetLastError()), FUNCION_ACTUAL); return false; } return true; } //+------------------------------------------------------------------+ bool CStrategyAO::OnInitSimulate(int start, int count) { // Antes de la simulacion copiamos el atr para el uso del tp y sl if(!CopyDataAtrSimulate(start, count)) return false; if(!OnSimulationStart()) return false; //--- m_in_simulate_mode = true; return true; } //+------------------------------------------------------------------+ void CStrategyAO::OnEndSimulate(void) { m_in_simulate_mode = false; OnSimulationEnd(); } //+------------------------------------------------------------------+ void CStrategyAO::SetAtrTP_SLOptimizer(int handle) { if(handle == INVALID_HANDLE) { LogError("El handle del indicador atr para la simulacion es invalido", FUNCION_ACTUAL); Remover(); return; } m_simulation_atr_handle = handle; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CStrategyAO::GetTP(double entry_price, ENUM_POSITION_TYPE position_type, datetime curr_time, int index) { double val = m_point_value; double val_to = m_TP_POINTS; if(m_tp_sl_mode == TP_SL_ATR) { val_to = m_atr_multiplier_tp; val = m_simulation_atr_arr[index]; } const double spr = (m_tick.ask - m_tick.bid); const double to_sum = ::fmax(m_stops_leevel + spr, (val * val_to)); return position_type == POSITION_TYPE_BUY ? entry_price + to_sum : entry_price - to_sum; } //+------------------------------------------------------------------+ double CStrategyAO::GetSL(double entry_price, ENUM_POSITION_TYPE position_type, datetime curr_time, int index) { double val = m_point_value; double val_to = m_SL_POINTS; if(m_tp_sl_mode == TP_SL_ATR) { val_to = m_atr_multiplier_sl; val = m_simulation_atr_arr[index]; } const double spr = (m_tick.ask - m_tick.bid); const double to_sum = ::fmax(m_stops_leevel + spr, (val * val_to)); return position_type == POSITION_TYPE_BUY ? entry_price - to_sum : entry_price + to_sum; } //+------------------------------------------------------------------+ #endif // MQLARTICLES_STRATEGY_DRV_AO_MAIN_MQH