Discusión sobre el artículo "Uso de modelos ONNX en MQL5" - página 5

 
Buen artículo. El gráfico de predicción de los datos de prueba es decepcionante. Bien podrías saltarte todo ese modelado/entrenamiento DNN y simplemente usar una predicción del próximo precio igual al último precio conocido. Apuesto a que la precisión de la predicción de un modelo tan trivial será mayor que utilizando su modelo DNN. Sugiero comparar esas dos precisiones y mostrarlas aquí. En general, usar DNN para predecir precios es una mala idea. Son más adecuados para la clasificación de los patrones de precios (por ejemplo, comprar, vender, mantener). Además, el número de pesos en su DNN es astronómico. Debe de estar sobreajustándose.
 
Vladimir #:
Buen artículo. El gráfico de predicción de los datos de prueba es decepcionante. Bien podrías saltarte todo ese modelado/entrenamiento DNN y simplemente usar una predicción del próximo precio igual al último precio conocido. Apuesto a que la precisión de la predicción de un modelo tan trivial será mayor que utilizando su modelo DNN. Sugiero comparar esas dos precisiones y mostrarlas aquí. En general, usar DNN para predecir precios es una mala idea. Son más adecuados para la clasificación de los patrones de precios (por ejemplo, comprar, vender, mantener). Además, el número de pesos en su DNN es astronómico. Debe de ser un ajuste excesivo.

Gracias Vladimir.
Sólo para discutir, cuando el tiempo lo permita, modificaría este modelo para hacer la clasificación para la comparación.

Por favor, hágamelo saber si usted tiene ideas.

Vladimir
Vladimir
  • 2022.04.30
  • www.mql5.com
Trader's profile
 
const long input_shape[] = {1, input_count};
const long output_shape[] = {1, output_count};

El tutorial da una entrada de un lote SAMPLE_SIZE número de entradas cercanas, usted quiere un lote de entradas input_count.

También su modelo no utiliza flotadores como entradas, pero los dobles,

Nota del Moderador: Este mensaje está fuera de secuencia debido a los mensajes a continuación se ha movido de otro tema. Por favor, vea el post de abajo.

 
¿Podemos solucionar juntos este modelo ONNX?

Hola comunidad MQL5, He estado tratando de seguir este tutorial sobre cómo utilizar ONNX en su EA. En el tutorial de una red neuronal fue el modelo de elección, He utilizado un gradiente impulsado árbol.

Construí el modelo utilizando el paquete Python InterpretML, y lo exporté a ONNX utilizando ebm2onnx.

Resumiré el proceso mediante el cual se entrenó el modelo.

1) El modelo fue entrenado en 5 entradas, OHLC y Altura, la altura se calcula como ((H + L) / 2) - C.

2) El modelo es un clasificador binario, con el objetivo de clasificar la siguiente vela como ARRIBA (1) o ABAJO (0).

Datos de entrenamiento del modelo

Los datos utilizados para entrenar el modelo.

3) El modelo se exportó al formato ONNX

Representación de ONNX

Representación del modelo ONNX.


Para conseguir que el modelo funcionara, me desvié del código del tutorial y seguí editando el código para intentar que el modelo ONNX funcionara, pero ahora realmente no sé qué estoy haciendo mal. Sigo recibiendo un error que el mango para el modelo no es válido.

He adjuntado el código MQL5 a continuación.

Ahora voy a resumir los pasos que tomé en mi código que se desvían de lo que está en el tutorial, y voy a explicar por qué me desvié del tutorial también

1) LINEA 57: Configuración de la forma de entrada del modelo.
En el tutorial se utilizaron 3 dimensiones para establecer la forma de entrada y salida, es decir {1,SAMPLE_SIZE,1}; Sin embargo, cuando seguí ese enfoque seguí recibiendo un error, específicamente el error 5808. Después del proceso habitual de prueba y error me di cuenta de que si utilizaba sólo 1 dimensión, el número de entradas, el error desaparecía.

2) LINEA 68: Configuración de la forma de salida del modelo.

Misma lógica que la anterior.

Las otras desviaciones que hice no afectan al modelo, por ejemplo, llevé la cuenta del tiempo usando una lógica que me pareció más intuitiva que la lógica implementada en el tutorial. No necesité normalizar las entradas porque es un modelo basado en árboles.


Si usted puede detectar otros errores que he hecho , le agradecería su perspicacia.

//+------------------------------------------------------------------+
//|ONNX.mq5
//|Copyright 2023, MetaQuotes Ltd. |
//| https://www.mql5.com
//+------------------------------------------------------------------+
//Propiedades meta
#property copyright "Gamuchirai Zororo Ndawana"
#property link      "https://www.mql5.com"
#property version   "1.00"

//Librería comercial
#include <Trade\Trade.mqh>

//Lectura de nuestro modelo ONNX y almacenamiento en una matriz de datos
#resource "\\Files\\Python\\Volatility_75_EBM.onnx" as uchar ExtModel[]

//Definiciones personalizadas de palabras clave
#define   SAMPLE_SIZE 998
#define   PRICE_UP 1
#define   PRICE_DOWN 0

//Variables globales
long     ExtHandle = INVALID_HANDLE;
int      ExtPredictedClass = -1;
datetime ExtNextBar = 0;
datetime ExtNextMinute =0;
float    ExtMin = 0;
float    ExtMax = 0;
double   min_volume;
CTrade   ExtTrade;

//Entradas
int input lot_mutliple = 1; //¿Cuántas veces mayor que el lote mínimo debemos introducir?

int OnInit()
  {
   //Comprueba si el símbolo y el marco temporal se ajustan a las condiciones de formación
   if(_Symbol != "Volatility 75 Index" || _Period != PERIOD_M1)
       {
            Comment("Model must be used with the Volatility 75 Index on the 1 Minute Chart");
            return(INIT_FAILED);
       }
    
    //Crear un modelo ONNX a partir de nuestra matriz de datos
    ExtHandle = OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT);
    Print("ONNX Create from buffer status ",ExtHandle);
    
    //Comprobación de la validez del asa
    if(ExtHandle == INVALID_HANDLE)
      {
            Comment("ONNX create from buffer error ", GetLastError());
            return(INIT_FAILED);
      }
   
   //Ajustar forma de entrada
   long input_count = OnnxGetInputCount(ExtHandle);   
   const long input_shape[] = {input_count};
   Print("Total model inputs : ",input_count);
   if(!OnnxSetInputShape(ExtHandle,0,input_shape))
      {
            Comment("ONNX set input shape error ", GetLastError());
            OnnxRelease(ExtHandle);
            return(INIT_FAILED);
      }
      
   //Fijar la forma de salida
   long output_count = OnnxGetOutputCount(ExtHandle);
   const long output_shape[] = {output_count};
   Print("Total model outputs : ",output_count);
   if(!OnnxSetOutputShape(ExtHandle,0,output_shape))
      {
            Comment("ONNX set output shape error ", GetLastError());
            OnnxRelease(ExtHandle);
            return(INIT_FAILED);
      }
    
    //Obtener el volumen mínimo de negociación permitido 
    min_volume = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);  
    return(INIT_SUCCEEDED);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Función de desinicialización experta|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   if(ExtHandle != INVALID_HANDLE)
      {
         OnnxRelease(ExtHandle);
         ExtHandle = INVALID_HANDLE;
      }
  }
//+------------------------------------------------------------------+
//| Función tick experto|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   //Rastreadores de tiempo
   static datetime time_stamp;
   datetime time = iTime(_Symbol,PERIOD_M1,0);
      
    //Comprobar nueva barra
     if(time_stamp != time)
      {
         time_stamp = time;
         
         PredictedPrice();
         Print("Predicted class: ",ExtPredictedClass);
         
         if(ExtPredictedClass == PRICE_UP || ExtPredictedClass == PRICE_DOWN)
            if(PositionSelect(_Symbol))
               CheckForClose();
            if(PositionsTotal() == 0)
               CheckForOpen();
      }
   
  }
//+------------------------------------------------------------------+

void CheckForOpen(void)
   {
      ENUM_ORDER_TYPE signal = WRONG_VALUE;
      
      //Comprobar señales
      if(ExtPredictedClass == PRICE_DOWN)
         {
            signal = ORDER_TYPE_SELL;
         }
         
      else if(ExtPredictedClass == PRICE_UP)
         {
            signal = ORDER_TYPE_BUY;
         }
         
      if(signal != WRONG_VALUE && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         {
            double price, sl = 0 , tp = 0;
            double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
            double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
            
            if(signal == ORDER_TYPE_SELL)
               {
                  price = bid;
               }
               
           else
               {
                  price = ask;
               }
               
            Print("Opening a new position: ",signal);  
            ExtTrade.PositionOpen(_Symbol,signal,min_volume,price,0,0);
         }
   }
   
void CheckForClose(void)
   {
      bool bsignal = false;
      
      long type = PositionGetInteger(POSITION_TYPE);
      
      if(type == POSITION_TYPE_BUY && ExtPredictedClass == PRICE_DOWN)
         bsignal = true;
         
      if(type == POSITION_TYPE_SELL && ExtPredictedClass == PRICE_UP)
         bsignal = true;
         
         if(bsignal && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
            {
                  ExtTrade.PositionClose(_Symbol,3);
                  CheckForOpen();
            }
   }
   
 void PredictedPrice(void)
   {
      vectorf output_data(1);
      float   open  = float(iOpen(_Symbol,PERIOD_M1,1));
      float   high  = float(iHigh(_Symbol,PERIOD_M1,1));
      float   low   = float(iLow(_Symbol,PERIOD_M1,1));
      float   close = float(iClose(_Symbol,PERIOD_M1,1));
      float   height =  float((((high + low) / 2) - close));
      Print("Current open ",open);
      Print("Current high ",high);
      Print("Current low ",low);
      Print("Current close ",close);
      Print("Current height ",height);
      vectorf input_data = {open,high,low,close,height};
      
      Print("Input vector: ",input_data);
      
       if(!OnnxRun(ExtHandle,ONNX_NO_CONVERSION,input_data,output_data))
         {
            Print("ONNX run error : ",GetLastError());
            OnnxRelease(ExtHandle);
         }
        
       int predicted = int(output_data[0]);
       
       Print("Model prediction: ",predicted);
       Print(output_data);
       
       if(predicted == 1)
         {
            ExtPredictedClass = PRICE_UP;
         }
         
       else if(predicted == 0)
         {
            ExtPredictedClass = PRICE_DOWN;
         }
         
         Comment("Model Prediction: ", ExtPredictedClass);
   }



Foro sobre trading, sistemas automatizados de trading y testeo de estrategias de trading

Discusión del artículo "Cómo utilizar modelos ONNX en MQL5"

Stian Andreassen, 2023.12.08 20:51

const long input_shape[] = {1, input_count};
const long output_shape[] = {1, output_count};

El tutorial da una entrada de un lote SAMPLE_SIZE número de entradas de cierre, que desea un lote de entradas input_count.

También su modelo no utiliza flotadores como entradas, pero los dobles,



Gracias por compartir Sitan, he aplicado lo que usted ha señalado, pero el error sigue ahí


Un lote de input_count

Un lote de entradas input_count.

Poner la entrada en doble

Establecer entrada en doble

Mensaje de error

Mensaje de error.


Archivos adjuntos:
 
amuchirai Zororo Ndawana #:
¿Podemos solucionar juntos este modelo ONNX?

Hello MQL5 community, I've been trying to follow this tutorial on how to use ONNX in your EA's. In the tutorial a neural network was the model of choice, I've used a gradient boosted tree. 

Construí el modelo utilizando el paquete InterpretML Python, y lo exporté a ONNX utilizando ebm2onnx.

Resumiré el proceso mediante el cual se entrenó el modelo.

1) El modelo fue entrenado en 5 entradas, OHLC y Altura, la altura se calcula como ((H + L) / 2) - C.

2) El modelo es un clasificador binario, cuyo objetivo es clasificar la siguiente vela como ARRIBA (1) o ABAJO (0).

Los datos utilizados para entrenar el modelo.

3) El modelo se exportó al formato ONNX

Representación del modelo ONNX.


Para conseguir que el modelo funcionara, me desvié del código del tutorial y seguí editando el código para intentar que el modelo ONNX funcionara, pero ahora realmente no sé qué estoy haciendo mal. Sigo recibiendo un error que el mango para el modelo no es válido.

He adjuntado el código MQL5 a continuación.

Ahora voy a resumir los pasos que tomé en mi código que se desvían de lo que está en el tutorial, y voy a explicar por qué me desvié del tutorial también

1) LINEA 57: Configuración de la forma de entrada del modelo.
En el tutorial se utilizaron 3 dimensiones para establecer la forma de entrada y salida, es decir {1,SAMPLE_SIZE,1}; Sin embargo, cuando seguí ese enfoque seguí recibiendo un error, específicamente el error 5808. Después del proceso habitual de prueba y error me di cuenta de que si utilizaba sólo 1 dimensión, el número de entradas, el error desaparecía.

2) LINEA 68: Configuración de la forma de salida del modelo.

Misma lógica que la anterior.

Las otras desviaciones que hice no afectan al modelo, por ejemplo, llevé la cuenta del tiempo usando una lógica que me pareció más intuitiva que la lógica implementada en el tutorial. No necesité normalizar las entradas porque es un modelo basado en árboles.


Si usted puede detectar otros errores que he hecho , le agradecería su perspicacia.





Gracias por compartir Sitan, he aplicado lo que señaló, pero el error sigue ahí


Un lote de entradas input_count.

Establecer entrada en doble

Mensaje de error.


Parece que MQL5 (o mejor dicho ONNXMLTools) todavía no soporta ONNX de EBM:

https://www.mql5.com/es/docs/onnx/onnx_conversion

Si consulta los archivos adjuntos ONNX (especialmente model.eurusd.D1.10.class.onnx que utiliza 4 entradas) de https://www.mql5.com/es/articles/12484; y utiliza Netron(versión web) para visualizar los archivos onnx verá las diferencias.

Creo que los dos artículos siguientes también te ayudarán a entenderlo mejor:

Modelos de regresión de la librería Scikit-learn y su exportación a ONNX

Modelos de clasificación de la librería Scikit-Learn y su exportación a ONNX

Wrapping ONNX models in classes
Wrapping ONNX models in classes
  • www.mql5.com
Object-oriented programming enables creation of a more compact code that is easy to read and modify. Here we will have a look at the example for three ONNX models.
 

Hola a todos,


Estamos intentando utilizar una red neuronal keras con 11 predictores en un momento dado (tamaño de lote 32) para hacer predicciones en el XauUsd (donde la salida es un número singular entre 0 y 1). En primer lugar, cargamos desde OnnxCreatefrombuffer (porque OnnxCreate en sí no funciona para nosotros), entonces siempre obtenemos un error en la etapa OnnxRun, donde he adjuntado ambos errores a continuación. Cualquier ayuda sobre qué dimensión para remodelar la entrada, qué formato para poner nuestro vector predictor en (si debe ser un vector en absoluto?), o simplemente cualquier ayuda o sugerencias con la sintaxis para ayudar a hacer frente a estos errores sería increíble. Hemos tratado de remodelación a todo tipo de combinaciones de 32,1,11 vectores y no hubo suerte y realmente ni idea con los próximos pasos ... Muchas gracias a quien pueda ayudarnos. Ben.

Error 5808

ONNX: input parameter #0 tensor has wrong dimension [0], try to use OnnxSetInputShape'

ONNX: parámetro de entrada #0 tamaño inválido, se esperaban 1408 bytes en lugar de 480'

 

Hola, intento utilizar el

OnnxModelInfo.mq5

pero no consigo que funcione, ¿qué estoy haciendo mal? no puede ser tan complicado.

He copiado y pegado el script OnnxModelInfo, y lo he guardado en la carpeta Files.

Tengo un modelo onnx (adjunto)

y cuando compilo el script aparecen 21 errores.

¿Alguien me puede ayudar con esto? Por favor

'element_type' - undeclared identifier  onnx read file.mq5      60      49
'element_type' - parameter for EnumToString must be an enumeration      onnx read file.mq5      60      49
'dimensions' - undeclared identifier    onnx read file.mq5      62      17
'dimensions' - undeclared identifier    onnx read file.mq5      64      37
'[' - array required    onnx read file.mq5      64      47
'dimensions' - undeclared identifier    onnx read file.mq5      65      51
'[' - array required    onnx read file.mq5      65      61
'dimensions' - undeclared identifier    onnx read file.mq5      66      33
'dimensions' - undeclared identifier    onnx read file.mq5      68      23
'[' - array required    onnx read file.mq5      68      33
'dimensions' - undeclared identifier    onnx read file.mq5      71      48
'[' - array required    onnx read file.mq5      71      58
'dimensions' - undeclared identifier    onnx read file.mq5      80      33
'dimensions' - undeclared identifier    onnx read file.mq5      82      35
'[' - array required    onnx read file.mq5      82      45
'dimensions' - undeclared identifier    onnx read file.mq5      100     28
';' - unexpected token  onnx read file.mq5      102     45
'<' - l-value required  onnx read file.mq5      100     17
cannot implicitly convert type 'string' to 'bool'       onnx read file.mq5      102     21
l-value required        onnx read file.mq5      102     20
'(' - unbalanced left parenthesis       onnx read file.mq5      100     9
empty controlled statement found        onnx read file.mq5      102     45
Archivos adjuntos:
model.onnx  295 kb
 
MetaQuotes:

Se ha publicado el nuevo artículo Uso de modelos ONNX en MQL5:

Autor: MetaQuotes

Hola señores.

Alguien me puede ayudar, porque al final del proceso en python, sale el siguiente error: AttributeError: 'Sequential' object has no attribute 'output_names'. No se mucho de python ni de programación. ¡Así que cualquier ayuda se agradecería! Gracias.

 
Hola señores.

Alguien me puede ayudar, porque al final del proceso en python, sale el siguiente error: AttributeError: 'Sequential' object has no attribute 'output_names'. No se mucho de python ni de programación. ¡Así que cualquier ayuda será bienvenida! Gracias.
 
Alberto Henrique Tacoronte # Hola señores. Alguien me puede ayudar, porque al final del proceso en python, sale el siguiente error: AttributeError: 'Sequential' object has no attribute 'output_names'. No se mucho de python ni de programación. ¡Así que cualquier ayuda se agradecería! Gracias.

Hola Alberto, por favor, publica la parte de tu código[usando el botónCÓDIGO (Alt -S)] donde se produce el error para que alguien que sepa Python(MetaTrader para Python | ONNX Models) pueda indicarte la solución...