//+------------------------------------------------------------------+ //| AiPred.mqh | //| Copyright 2025, Niquel Mendoza. | //| https://www.mql5.com/es/users/nique_372 | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Niquel Mendoza." #property link "https://www.mql5.com/es/users/nique_372" #property strict #ifndef EASYSB_AIAD_AIPRED_MQH #define EASYSB_AIAD_AIPRED_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //--- Inicializacion global #include "..\\Core\\DefGlobal.mqh" //--- Onnx default models #include "..\\Models\\OnnxDef.mqh" //--- Writer #include "Writer.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template class CAiPredictorBase : public TPadre { protected: TModel m_model; ScalerBase* m_scaler; CStrategyAiGetData* m_get_data; vector m_last_data; vector m_final_data; int m_idx_feautures[]; int m_idx_features_size; public: CAiPredictorBase(void); ~CAiPredictorBase(void); //--- bool Init(ENUM_SCALERBYLEO_TYPE type_scaler, CStrategyAiGetData* ai_ge_t, const string& pscaler, const string& onnx_file, const int& idx[]); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template CAiPredictorBase::CAiPredictorBase(void) : m_scaler(NULL), m_get_data(NULL) { m_idx_features_size = ArrayResize(m_idx_feautures, 0); } //+------------------------------------------------------------------+ template CAiPredictorBase::~CAiPredictorBase(void) { //--- if(CheckPointer(m_scaler) == POINTER_DYNAMIC) delete m_scaler; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template bool CAiPredictorBase::Init(ENUM_SCALERBYLEO_TYPE type_scaler, CStrategyAiGetData* ai_ge_t, const string& pscaler, const string& onnx_file, const int& idx[]) { //--- m_scaler = NULL; switch(type_scaler) { case SCALERBYLEO_SCALER_TYPE_MINMAX: m_scaler = new MaxMinScaler(); break; case SCALERBYLEO_SCALER_TYPE_STANDART: m_scaler = new StandardizationScaler(); break; case SCALERBYLEO_SCALER_TYPE_ROBUST: m_scaler = new RobustScaler(); break; default: LogError(StringFormat("Tipo de scalamiento = %s, es invalido", EnumToString(type_scaler)), FUNCION_ACTUAL); return false; } //--- // type_strategy en base a eso elegir el tipo de scaler y onnx y idx if(!m_scaler.load_by_file(pscaler)) return false; //--- m_idx_features_size = ArrayCopy(m_idx_feautures, idx); //--- if(!m_model.Init(onnx_file, true, m_idx_features_size+1)) return false; //--- m_get_data = ai_ge_t; //--- if(!CheckPointer(m_scaler)) { LogError("El scalador es invalido", FUNCION_ACTUAL); return false; } //--- if(!CheckPointer(m_get_data)) { LogError("El generador de data es invalido", FUNCION_ACTUAL); return false; } //--- return true; } //+------------------------------------------------------------------+ //| Clase predictora final para el filtro de operaciones | //+------------------------------------------------------------------+ class CAiPredictorFinal : public CAiPredictorBase { private: double m_min_proba; public: CAiPredictorFinal(void) : m_min_proba(0.6) {} ~CAiPredictorFinal(void) {} //--- void MinProba(double min_proba) { m_min_proba = min_proba; } __forceinline double MinProba() const { return m_min_proba; } //--- bool CheckOpenOrder(const StrategyTradeConfig& plan) override final; void OnNewBar(const datetime curr_time) override final {} }; //+------------------------------------------------------------------+ bool CAiPredictorFinal::CheckOpenOrder(const StrategyTradeConfig &plan) { //--- Generamos m_last_data = m_get_data.GetAsVector(); //--- Escalada completa // Transofrmacion completa // Mencionar que omitimos dos cols (salida, y tipe op.. esots no SON escalados...) m_last_data = m_scaler.transform(m_last_data); // Obtenemos lo sindices especificos (aqui se omitira type op.. pero lo forzamores luego) CAiLeoMulyiFeatureGen::GetDataCts(m_final_data, m_idx_feautures, m_idx_features_size, m_last_data); // Agregamos el tipo de operaicon al final const ulong size = m_final_data.Size(); m_final_data.Resize(size + 1); m_final_data[size] = double(plan.type); //--- // aqui m_last data ya se comptara como proba static ulong best_class_idx; static long best_class; if(!m_model.Predict(m_final_data, m_last_data, best_class_idx, best_class, ONNX_NO_CONVERSION)) { LogError("Ha ocurrido un error al intetnar predecir..", FUNCION_ACTUAL); return false; } //--- Operamos... const double proba = m_last_data[best_class_idx]; //--- LogInfo(StringFormat("Ai prediction = %s | Probabilidad = %.2f", (best_class == 1 ? "Operar" : "No operar"), proba), FUNCION_ACTUAL); //--- return (best_class == 1 && proba >= m_min_proba); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CAiPredictorFinalRegTp : public CAiPredictorBase { private: CAtr* m_atr; public: CAiPredictorFinalRegTp(void) { m_atr = CIctLibAtrManager::GetAtr(_Period); } ~CAiPredictorFinalRegTp(void) { if(CIctLibAtrManager::IsActive()) CIctLibAtrManager::RemoveAtr(m_atr); } //--- void ModifyTPSL(const StrategyTradeConfig& plan, double& sl, double& tp) override final; void OnNewBar(const datetime curr_time) override final {} }; //+------------------------------------------------------------------+ void CAiPredictorFinalRegTp::ModifyTPSL(const StrategyTradeConfig& plan, double& sl, double& tp) { //--- Generamos m_last_data = m_get_data.GetAsVector(); //--- Escalada completa // Transofrmacion completa // Mencionar que omitimos dos cols (salida, y tipe op.. esots no SON escalados...) m_last_data = m_scaler.transform(m_last_data); // Obtenemos lo sindices especificos (aqui se omitira type op.. pero lo forzamores luego) CAiLeoMulyiFeatureGen::GetDataCts(m_final_data, m_idx_feautures, m_idx_features_size, m_last_data); // Agregamos el tipo de operaicon al final const ulong size = m_final_data.Size(); m_final_data.Resize(size + 1); m_final_data[size] = double(plan.type); //--- // aqui m_last data ya se comptara como proba static double salida; if(!m_model.Predict(m_final_data, ONNX_NO_CONVERSION, salida)) { LogError("Ha ocurrido un error al intetnar predecir..", FUNCION_ACTUAL); return; } //--- salida *= m_atr[1]; LogInfo(StringFormat("Ai prediction = %.2f TP DIST", salida), FUNCION_ACTUAL); //--- tp = plan.type == POSITION_TYPE_BUY ? plan.entry + salida : plan.entry - salida; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CAiPredictorFinalRegSl : public CAiPredictorBase { private: CAtr* m_atr; public: CAiPredictorFinalRegSl(void) { m_atr = CIctLibAtrManager::GetAtr(_Period); } ~CAiPredictorFinalRegSl(void) {if(CIctLibAtrManager::IsActive()) CIctLibAtrManager::RemoveAtr(m_atr); } //--- void ModifyTPSL(const StrategyTradeConfig& plan, double& sl, double& tp) override final; void OnNewBar(const datetime curr_time) override final {} }; //+------------------------------------------------------------------+ void CAiPredictorFinalRegSl::ModifyTPSL(const StrategyTradeConfig& plan, double& sl, double& tp) { //--- Generamos m_last_data = m_get_data.GetAsVector(); //--- Escalada completa // Transofrmacion completa // Mencionar que omitimos dos cols (salida, y tipe op.. esots no SON escalados...) m_last_data = m_scaler.transform(m_last_data); // Obtenemos lo sindices especificos (aqui se omitira type op.. pero lo forzamores luego) CAiLeoMulyiFeatureGen::GetDataCts(m_final_data, m_idx_feautures, m_idx_features_size, m_last_data); // Agregamos el tipo de operaicon al final const ulong size = m_final_data.Size(); m_final_data.Resize(size + 1); m_final_data[size] = double(plan.type); //--- // aqui m_last data ya se comptara como proba static double salida; if(!m_model.Predict(m_final_data, ONNX_NO_CONVERSION, salida)) { LogError("Ha ocurrido un error al intetnar predecir..", FUNCION_ACTUAL); return; } //--- salida *= m_atr[1]; LogInfo(StringFormat("Ai prediction = %.2f SL DIST", salida), FUNCION_ACTUAL); //--- sl = plan.type == POSITION_TYPE_BUY ? plan.entry - salida : plan.entry + salida; } //+------------------------------------------------------------------+ #endif // EASYSB_AIAD_AIPRED_MQH