EasySbAi/AiAd/AiPred.mqh
2026-04-10 15:47:40 -05:00

297 lines
9.9 KiB
MQL5

//+------------------------------------------------------------------+
//| 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 <typename TPadre, typename TModel>
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 <typename TPadre, typename TModel> CAiPredictorBase::CAiPredictorBase(void)
: m_scaler(NULL), m_get_data(NULL)
{
m_idx_features_size = ArrayResize(m_idx_feautures, 0);
}
//+------------------------------------------------------------------+
template <typename TPadre, typename TModel> CAiPredictorBase::~CAiPredictorBase(void)
{
//---
if(CheckPointer(m_scaler) == POINTER_DYNAMIC)
delete m_scaler;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TPadre, typename TModel>
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<IStrategyAddonAiFilter, COnnxSimpleModel>
{
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<IStrategyAddonTPSL, COnnxModelRegresoin>
{
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<IStrategyAddonTPSL, COnnxModelRegresoin>
{
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