//+------------------------------------------------------------------+ //| 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 #ifndef EASYSB_CORE_STRATEGY_MQH #define EASYSB_CORE_STRATEGY_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // Source: https://www.youtube.com/watch?v=o0v4KQxZbpU&t=183s #include "Functions.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CEstrategia : public CStrategyBase { private: //--- Variables bool m_operate; uint8_t m_strategy_flags; double m_max_9; double m_min_9; bool m_ai_init; //--- Functions pointers CEstrategia_FuncBos m_func_bos; CEstrategia_FuncBos m_func_pda; //--- Ia // Variables miembro uint8_t m_ai_flags; CStrategyAiGetData* m_ai_get_data; IStrategyAddonAiFilter* m_ai_intermadiary; IStrategyAddonTPSL* m_ai_sl; IStrategyAddonTPSL* m_ai_tp; CAiLeoMulyiFeatureGen* m_data_generator; // Funciones template bool InitAiComponentForTraining(const string& prefix, TFinalClass* &intermediay, const int bar_to_revise, const bool common_folder); //--- 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 InitAiTraining(int bar_to_revise, bool common_folder); void InitAiLive(int bar_to_revise, double min_proba, ENUM_TPSL_GENERAL type_tp_sl_ai, ENUM_STRATEGY_ENTRY entry_type, CSetFile* &set_file, ConfigDependencyAiStrBase& config_in); //--- void OnNewBar(const datetime curr_time) override; void OnNewWeek(const datetime curr_time) override; void OnInterupcion(); void OnTick(const datetime curr_time) override {} //--- void OnNewBarM1(const datetime curr_time); //--- __forceinline bool UseAi() const { return m_ai_flags > 0;} void InitAiFlags(ENUM_TPSL_GENERAL type_tp_sl_ai, ENUM_STRATEGY_ENTRY entry_type); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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"), m_ai_tp(NULL), m_ai_sl(NULL), m_ai_intermadiary(NULL), m_data_generator(NULL), m_ai_init(false), m_ai_get_data(NULL), m_ai_flags(0) { 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); } //--- if(m_ai_get_data != NULL) delete m_ai_get_data; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::InitAiFlags(ENUM_TPSL_GENERAL type_tp_sl_ai, ENUM_STRATEGY_ENTRY entry_type) { m_ai_flags |= (entry_type == STRATEGY_TYPE_ENTRY_WITH_AI ? AIDATALEO_ADDON_FLAG_ENTRY : 0); m_ai_flags |= (type_tp_sl_ai == TPSL_GENERAL_TYPE_USE_TP_AI || type_tp_sl_ai == TPSL_GENERAL_TYPE_USE_FULL_AI ? AIDATALEO_ADDON_FLAG_TP : 0); m_ai_flags |= (type_tp_sl_ai == TPSL_GENERAL_TYPE_USE_SL_AI || type_tp_sl_ai == TPSL_GENERAL_TYPE_USE_FULL_AI ? AIDATALEO_ADDON_FLAG_SL : 0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template bool CEstrategia::InitAiComponentForTraining(const string& prefix, TFinalClass* &intermediay, const int bar_to_revise, const bool common_folder) { // Intermediario de ia intermediay = new TTrainerClass(); TTrainerClass* trainer = (TTrainerClass*)intermediay; // Writer TWriterClass* writer = new TWriterClass(m_ai_get_data); // Output TOutputClass* output = new TOutputClass(); // Inicamos const string file_name_scaler_p = FILE_NAME_AI_DATA_SCALER_P(prefix); const string file_name_data = FILE_NAME_AI_DATA_SCALER_DATA(prefix); // Iniciamos trainer return trainer.Init(m_timeframe, m_symbol, file_name_scaler_p, file_name_data, common_folder, m_data_generator.Header(), bar_to_revise, writer, output, SCALERBYLEO_SCALER_TYPE_ROBUST); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::InitAiTraining(int bar_to_revise, bool common_folder) { //--- if(m_ai_init) return; //--- Trainer //--- m_ai_flags = AIDATALEO_ADDON_FLAG_ENTRY | AIDATALEO_ADDON_FLAG_TP | AIDATALEO_ADDON_FLAG_SL; //--- Generador de data m_data_generator = new CAiLeoMulyiFeatureGen(); g_ai_data_features_parser.AddLogFlags(LogFlags()); if(!m_data_generator.Init("GeneradorData", g_res_generic_features)) { LogError("Fallo al cargar las features", FUNCION_ACTUAL); Remover(); } else { LogInfo("Generador de data cargado exitosamente", FUNCION_ACTUAL); AddLogger(m_data_generator); } //--- Data global m_ai_get_data = new CStrategyAiGetData(m_data_generator, true); //--- Trainer para prediccion if(!InitAiComponentForTraining("pred", m_ai_intermadiary, bar_to_revise, common_folder)) { LogCriticalError("Fallo al iniciar el trainer para entry ia", FUNCION_ACTUAL); Remover(); return; } else { AddLogger(m_ai_intermadiary); } //--- Trainer para tp if(!InitAiComponentForTraining("tp", m_ai_tp, bar_to_revise, common_folder)) { LogCriticalError("Fallo al iniciar el trainer para tp", FUNCION_ACTUAL); Remover(); return; } else { AddLogger(m_ai_tp); } //--- Trainer para sl if(!InitAiComponentForTraining("sl", m_ai_sl, bar_to_revise, common_folder)) { LogCriticalError("Fallo al iniciar el trainer para sl", FUNCION_ACTUAL); Remover(); return; } else { AddLogger(m_ai_sl); } //--- m_ai_init = true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::InitAiLive(int bar_to_revise, double min_proba, ENUM_TPSL_GENERAL type_tp_sl_ai, ENUM_STRATEGY_ENTRY entry_type, CSetFile* &set_file, ConfigDependencyAiStrBase& config_in) { //--- if(m_ai_init) return; //--- if(m_ai_flags == 0) // NO AI return; //--- config_in.main_folder = FOLDER_AI_DATA; //config_in.comon_folder = true; lo elige el user config_in.file_name_idx = "idx.txt"; // Scalado config_in.file_name_scalers[CONFIGURATION_DEPENDECY_ARR_IDX_PRED] = FILE_NAME_AI_DATA_SCALER_NAME("pred"); config_in.file_name_scalers[CONFIGURATION_DEPENDECY_ARR_IDX_SL] = FILE_NAME_AI_DATA_SCALER_NAME("sl"); config_in.file_name_scalers[CONFIGURATION_DEPENDECY_ARR_IDX_TP] = FILE_NAME_AI_DATA_SCALER_NAME("tp"); // Onnx config_in.file_name_models[CONFIGURATION_DEPENDECY_ARR_IDX_PRED] = "ModelPred.onnx"; config_in.file_name_models[CONFIGURATION_DEPENDECY_ARR_IDX_SL] = "ModelSL_f.onnx"; config_in.file_name_models[CONFIGURATION_DEPENDECY_ARR_IDX_TP] = "ModelTP_f.onnx"; //--- ConfigDependencyOutAiNormal out_data; if(!CConfigurationsDependecy::GetDependencyNormal(config_in, out_data)) { LogError("Fallo al cargar dependencias del modelo", FUNCION_ACTUAL); Remover(); return; } set_file = out_data.set_file; //--- Generador de data m_data_generator = new CAiLeoMulyiFeatureGen(); g_ai_data_features_parser.AddLogFlags(LogFlags()); if(!m_data_generator.Init("GeneradorData", g_res_generic_features)) { LogError("Fallo al cargar las features", FUNCION_ACTUAL); Remover(); } else { LogInfo("Generador de data cargado exitosamente", FUNCION_ACTUAL); AddLogger(m_data_generator); } //--- Data global m_ai_get_data = new CStrategyAiGetData(m_data_generator, true); //--- if((m_ai_flags & AIDATALEO_ADDON_FLAG_ENTRY) != 0) { m_ai_intermadiary = new CAiPredictorFinal(); CAiPredictorFinal* preditor = (CAiPredictorFinal*)m_ai_intermadiary; if(!preditor.Init(SCALERBYLEO_SCALER_TYPE_ROBUST, m_ai_get_data, out_data.file_name_scaler_pred, out_data.file_name_onnx_pred, out_data.idx_pred)) { LogError("Fallo al cargar el predictor", FUNCION_ACTUAL); Remover(); return; } else { AddLogger(m_ai_intermadiary); preditor.MinProba(min_proba); } } //--- if((m_ai_flags & AIDATALEO_ADDON_FLAG_TP) != 0) { m_ai_tp = new CAiPredictorFinalRegTp(); CAiPredictorFinalRegTp* preditor = (CAiPredictorFinalRegTp*)m_ai_tp; if(!preditor.Init(SCALERBYLEO_SCALER_TYPE_ROBUST, m_ai_get_data, out_data.file_name_scaler_tp, out_data.file_name_onnx_tp, out_data.idx_tp)) { LogError("Fallo al cargar el predictor", FUNCION_ACTUAL); Remover(); return; } else { AddLogger(m_ai_tp); } } //--- if((m_ai_flags & AIDATALEO_ADDON_FLAG_SL) != 0) { m_ai_sl = new CAiPredictorFinalRegSl(); CAiPredictorFinalRegSl* preditor = (CAiPredictorFinalRegSl*)m_ai_sl; if(!preditor.Init(SCALERBYLEO_SCALER_TYPE_ROBUST, m_ai_get_data, out_data.file_name_scaler_sl, out_data.file_name_onnx_sl, out_data.idx_sl)) { LogError("Fallo al cargar el predictor", FUNCION_ACTUAL); Remover(); return; } else { AddLogger(m_ai_sl); } } //--- m_ai_init = true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::OnNewBarM1(const datetime curr_time) { if(m_data_generator != NULL) { CIctLibPool::OnNewBarM1(curr_time); // Ejecutamos el POOL m_data_generator.OnNewBarM1(curr_time); // Ejecutamos las features } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::OnNewWeek(const datetime curr_time) { g_bos_choch.DeleteAll(); g_bloque1.DeleteAll(); g_bloque2.DeleteAll(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CEstrategia::Clean(void) { m_strategy_flags = 0; m_func_bos = NULL; m_func_pda = NULL; 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; //--- Ejecuciones de addons Ai solo si se utilizan if(m_ai_intermadiary != NULL) m_ai_intermadiary.OnNewBar(curr_time); // SL if(m_ai_sl != NULL) m_ai_sl.OnNewBar(curr_time); // TP if(m_ai_tp != NULL) m_ai_tp.OnNewBar(curr_time); //--- Estrategia if(g_sesion.EnSesion()) { 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; //--- if(m_strategy_flags == 0) { 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) { m_strategy_flags |= S_FLAG_DIRECION_SELL; m_func_bos = EstrategiaFuncionts::EstRopturaAlaBaja; } else if(m_min_9 > prev_low) { m_strategy_flags |= S_FLAG_DIRECION_BUY; m_func_bos = EstrategiaFuncionts::EstRopturaAlAlza; } } else if((m_strategy_flags & S_FLAG_DEZPLAZAMIENTO_HECHO) == 0) { if(m_func_bos()) { m_strategy_flags |= S_FLAG_DEZPLAZAMIENTO_HECHO; if((m_strategy_flags & S_FLAG_DIRECION_BUY) != 0) { m_func_pda = EstrategiaFuncionts::PdaMigAlcista; } else { m_func_pda = EstrategiaFuncionts::PdaMitBajista; } } } else { if(m_func_pda()) { OpenOrder(((m_strategy_flags & S_FLAG_DIRECION_BUY) != 0 ? POSITION_TYPE_BUY : POSITION_TYPE_SELL)); } } } 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); //--- static StrategyTradeConfig config; config.type = type; config.curr_time = m_tick.time; //--- if(m_ai_get_data != NULL) { m_ai_get_data.GenerateData(m_tick.time); } //--- if(type == POSITION_TYPE_BUY) { double entry = m_tick.ask; config.entry = entry; //--- SL static double sl; if(m_ai_sl != NULL) { m_ai_sl.ModifyTPSL(config, sl, EMPTY_DOUBLE); } else { sl = GetSL(entry, type, m_tick.time); } //--- TP static double tp; if(m_ai_tp != NULL) { m_ai_tp.ModifyTPSL(config, EMPTY_DOUBLE, tp); } else { tp = GetTP(entry, type, m_tick.time); } //--- Entrada if(m_ai_intermadiary != NULL && !m_ai_intermadiary.CheckOpenOrder(config)) { Clean(); m_operate = true; return; } //--- Apertura de posiciones risk.SetStopLoss(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; config.entry = entry; //--- SL static double sl; if(m_ai_sl != NULL) { m_ai_sl.ModifyTPSL(config, sl, EMPTY_DOUBLE); } else { sl = GetSL(entry, type, m_tick.time); } //--- TP static double tp; if(m_ai_tp != NULL) { m_ai_tp.ModifyTPSL(config, EMPTY_DOUBLE, tp); } else { tp = GetTP(entry, type, m_tick.time); } //--- Entrada if(m_ai_intermadiary != NULL && !m_ai_intermadiary.CheckOpenOrder(config)) { Clean(); m_operate = true; return; } //--- Apertura de posiciones risk.SetStopLoss(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; } //+------------------------------------------------------------------+ #endif // EASYSB_CORE_STRATEGY_MQH