297 lines
9.9 KiB
MQL5
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
|