Discussione sull’articolo "Come utilizzare i modelli ONNX in MQL5" - pagina 5

 
Bell'articolo. Il grafico di previsione sui dati di test è deludente. Potreste anche saltare tutta la modellazione/addestramento DNN e utilizzare semplicemente una previsione del prezzo successivo uguale all'ultimo prezzo noto. Scommetto che l'accuratezza della previsione di questo modello banale sarà superiore a quella del modello DNN. Suggerisco di confrontare queste due accuratezze e di mostrarle qui. In generale, l'uso di DNN per prevedere i prezzi è una cattiva idea. Sono più adatti per la classificazione dei modelli di prezzo (ad esempio, comprare, vendere, tenere). Inoltre, il numero di pesi della DNN è astronomico. Deve trattarsi di un overfitting.
 
Vladimir #:
Bell'articolo. Il grafico di previsione sui dati di test è deludente. Potreste anche saltare tutta la modellazione/addestramento DNN e utilizzare semplicemente una previsione del prezzo successivo uguale all'ultimo prezzo noto. Scommetto che l'accuratezza della previsione di questo modello banale sarà superiore a quella del modello DNN. Suggerisco di confrontare queste due accuratezze e di mostrarle qui. In generale, l'uso di DNN per prevedere i prezzi è una cattiva idea. Sono più adatti per la classificazione dei modelli di prezzo (ad esempio, comprare, vendere, tenere). Inoltre, il numero di pesi nella vostra DNN è astronomico. Deve trattarsi di un overfitting.

Grazie Vladimir.
A titolo di discussione, quando il tempo lo permetterà, modificherò questo modello per effettuare una classificazione a scopo di confronto.

Fatemi sapere se avete idee.

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};

Il tutorial fornisce un input di un batch SAMPLE_SIZE di input ravvicinati, mentre voi volete un batch di input_count di input.

Inoltre il vostro modello non usa i float come input, ma i double,

Nota del moderatore: questo post è fuori sequenza perché i post sottostanti sono stati spostati da un altro argomento. Si prega di vedere il post sottostante.

 
Possiamo risolvere insieme questo modello ONNX?

Salve comunità MQL5, ho cercato di seguire questo tutorial su come utilizzare ONNX nei vostri EA. Nel tutorial il modello scelto era una rete neurale, io ho usato un albero con gradiente boosted.

Ho costruito il modello utilizzando il pacchetto InterpretML di Python e l'ho esportato in ONNX utilizzando ebm2onnx.

Riassumerò il processo con cui è stato addestrato il modello.

1) Il modello è stato addestrato su 5 input, OHLC e Altezza, l'Altezza è calcolata come ((H + L) / 2) - C.

2) Il modello è un classificatore binario, con l'obiettivo di classificare la candela successiva come UP (1) o DOWN (0).

Dati di formazione del modello

I dati utilizzati per addestrare il modello.

3) Il modello è stato poi esportato in formato ONNX.

Rappresentazione ONNX

Rappresentazione del modello ONNX.


Per far funzionare il modello, mi sono discostato dal codice del tutorial e ho continuato a modificare il codice per cercare di far funzionare il modello ONNX, ma ora non so davvero cosa sto sbagliando. Continuo a ricevere un errore che indica che l'handle del modello non è valido.

Ho allegato il codice MQL5 qui sotto.

Ora riepilogherò i passi che ho fatto nel mio codice e che si discostano da quanto riportato nel tutorial e spiegherò anche perché mi sono discostato dal tutorial.

1) LINEA 57: Impostazione della forma di ingresso del modello.
Nel tutorial sono state utilizzate 3 dimensioni per impostare la forma di ingresso e di uscita, ovvero {1,SAMPLE_SIZE,1}; tuttavia, quando ho seguito questo approccio ho continuato a ricevere un errore, in particolare l'errore 5808. Dopo il consueto processo di ricerca ed errore, ho capito che se utilizzavo solo una dimensione, il numero di ingressi, l'errore scompariva.

2) LINEA 68: Impostazione della forma di uscita del modello.

Stessa logica di cui sopra.

Le altre deviazioni che ho fatto non influiscono sul modello, ad esempio ho tenuto traccia del tempo usando una logica che ho trovato più intuitiva di quella implementata nel tutorial. Non ho avuto bisogno di normalizzare gli input perché si tratta di un modello ad albero.


Se riuscite a individuare altri errori che ho commesso, vi sarei grato se poteste darmi una risposta.

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

//Biblioteca commerciale
#include <Trade\Trade.mqh>

/Lettura del nostro modello ONNX e memorizzazione in un array di dati
#resource "\\Files\\Python\\Volatility_75_EBM.onnx" as uchar ExtModel[]

//Definizioni di parole chiave personalizzate
#define   SAMPLE_SIZE 998
#define   PRICE_UP 1
#define   PRICE_DOWN 0

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

//Ingressi
int input lot_mutliple = 1; //Quanto tempo maggiore del lotto minimo dobbiamo inserire?

int OnInit()
  {
   //Controlla se il simbolo e l'intervallo di tempo sono conformi alle condizioni di formazione
   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);
       }
    
    //Creare un modello ONNX dal nostro array di dati
    ExtHandle = OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT);
    Print("ONNX Create from buffer status ",ExtHandle);
    
    /Verifica se l'handle è valido
    if(ExtHandle == INVALID_HANDLE)
      {
            Comment("ONNX create from buffer error ", GetLastError());
            return(INIT_FAILED);
      }
   
   /Impostare la forma dell'ingresso
   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);
      }
      
   /Impostare la forma dell'uscita
   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);
      }
    
    /Ottieni il volume di trading minimo consentito 
    min_volume = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);  
    return(INIT_SUCCEEDED);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Funzione di deinizializzazione dell'esperto|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   if(ExtHandle != INVALID_HANDLE)
      {
         OnnxRelease(ExtHandle);
         ExtHandle = INVALID_HANDLE;
      }
  }
//+------------------------------------------------------------------+
//| Funzione tick dell'esperto|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   //Segnalatori di tempo
   static datetime time_stamp;
   datetime time = iTime(_Symbol,PERIOD_M1,0);
      
    //Controllo della nuova 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;
      
      //Controllo dei segnali
      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);
   }



Forum sul trading, sui sistemi di trading automatico e sul test delle strategie di trading

Discussione dell'articolo "Come utilizzare i modelli ONNX in MQL5

Stian Andreassen, 2023.12.08 20:51

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

Il tutorial fornisce un input di un batch SAMPLE_SIZE numero di input ravvicinati, tu vuoi un batch di input_count input.

Inoltre il vostro modello non usa i float come input, ma i double,



Grazie per la condivisione di Sitan, ho applicato ciò che hai indicato ma l'errore è ancora presente.


Un lotto di input_count

Un lotto di ingressi input_count.

Impostare l'ingresso su doppio

Impostare l'ingresso su doppio

Messaggio di errore

Messaggio di errore.


File:
 
amuchirai Zororo Ndawana #:
Possiamo risolvere questo modello ONNX insieme?

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. 

Ho costruito il modello utilizzando il pacchetto InterpretML Python e l'ho esportato in ONNX utilizzando ebm2onnx.

Riassumerò il processo con cui il modello è stato addestrato.

1) Il modello è stato addestrato su 5 input, OHLC e Altezza, l'Altezza è calcolata come ((H + L) / 2) - C.

2) Il modello è un classificatore binario, con l'obiettivo di classificare la candela successiva come UP (1) o DOWN (0).

I dati utilizzati per addestrare il modello.

3) Il modello è stato poi esportato in formato ONNX.

Rappresentazione del modello ONNX.


Per far funzionare il modello, mi sono discostato dal codice del tutorial e ho continuato a modificare il codice per cercare di far funzionare il modello ONNX, ma ora non so proprio cosa sto sbagliando. Continuo a ricevere un errore che indica che l'handle del modello non è valido.

Ho allegato il codice MQL5 qui sotto.

Ora riepilogherò i passi che ho fatto nel mio codice e che si discostano da quanto riportato nel tutorial e spiegherò anche perché mi sono discostato dal tutorial.

1) LINEA 57: Impostazione della forma di ingresso del modello.
Nel tutorial sono state utilizzate 3 dimensioni per impostare la forma di ingresso e di uscita, ovvero {1,SAMPLE_SIZE,1}; tuttavia, quando ho seguito questo approccio ho continuato a ricevere un errore, in particolare l'errore 5808. Dopo il consueto processo di ricerca ed errore, ho capito che se utilizzavo solo una dimensione, il numero di ingressi, l'errore scompariva.

2) LINEA 68: Impostazione della forma di uscita del modello.

Stessa logica di cui sopra.

Le altre deviazioni che ho fatto non influiscono sul modello, ad esempio ho tenuto traccia del tempo usando una logica che ho trovato più intuitiva di quella implementata nel tutorial. Non ho avuto bisogno di normalizzare gli input perché si tratta di un modello ad albero.


Se riuscite a individuare altri errori che ho commesso, vi sarei grato se poteste darmi una risposta.





Grazie per la condivisione di Sitan, ho applicato ciò che hai indicato ma l'errore è ancora presente.


Un lotto di ingressi input_count.

Impostare l'ingresso su doppio

Messaggio di errore.


Sembra che MQL5 non supporti (o meglio ONNXMLTools non supporta ancora ONNX di EBM:

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

Se si fa riferimento agli allegati ONNX (in particolare model.eurusd.D1.10.class.onnx che utilizza 4 input) da https://www.mql5.com/it/articles/12484; e si utilizza Netron(versione web) per visualizzare i file onnx, si noteranno le differenze.

Penso che anche i due articoli seguenti possano aiutarvi a capire meglio:

Modelli di regressione della libreria Scikit-learn e loro esportazione in ONNX

Modelli di classificazione della libreria Scikit-Learn e loro esportazione in 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.
 

Ciao a tutti,


Stiamo cercando di utilizzare una rete neurale keras con 11 predittori in un momento (batch size 32) per fare previsioni su XauUsd (dove l'output è un numero singolare tra 0 e 1). In primo luogo, carichiamo da OnnxCreatefrombuffer (perché OnnxCreate stesso non funziona per noi), poi otteniamo sempre un errore nella fase OnnxRun, dove ho allegato entrambi gli errori qui sotto. Qualsiasi aiuto su quale dimensione rimodellare per l'input, in quale formato inserire il nostro vettore di predizione (se deve essere un vettore?), o semplicemente qualsiasi aiuto o suggerimento sulla sintassi per affrontare questi errori sarebbe fantastico. Abbiamo provato a rimodellare tutti i tipi di combinazioni di vettori 32,1,11 senza fortuna e non abbiamo idea dei prossimi passi da fare. Grazie mille a chiunque possa aiutarci!!! Ben.

' errore 5808'

ONNX: il parametro di input #0 del tensore ha una dimensione errata [0], provare a usare OnnxSetInputShape'.

ONNX: dimensione del parametro di input #0 non valida, previsti 1408 byte invece di 480".

 

Ciao, ho provato ad usare lo script

OnnxModelInfo.mq5

ma non riesco a farlo funzionare, cosa sto sbagliando? Non può essere così complicato!

Ho copiato e incollato lo script OnnxModelInfo e l'ho salvato nella cartella de Files.

Ho un modello onnx (allegato)

e quando compilo lo script, appaiono 21 errori.

Qualcuno può aiutarmi? Per favore

'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
File:
model.onnx  295 kb
 
MetaQuotes:

È stato pubblicato il nuovo articolo Utilizzo dei modelli ONNX in MQL5:

Autore: MetaQuotes

Salve signori.

Qualcuno può aiutarmi, perché alla fine del processo in python, viene fuori il seguente errore: AttributeError: 'Sequential' object has no attribute 'output_names'. Non so molto di python o di programmazione. Quindi qualsiasi aiuto sarebbe apprezzato! Grazie.

 
Salve signori.

Qualcuno può aiutarmi, perché alla fine del processo in python, viene fuori il seguente errore: AttributeError: l'oggetto 'Sequential' non ha l'attributo 'output_names'. Non so molto di Python o di programmazione. Quindi ogni aiuto sarà ben accetto! Grazie.
 
Alberto Henrique Tacoronte # Salve signori. Qualcuno può aiutarmi, perché alla fine del processo python, viene fuori il seguente errore: AttributeError: 'Sequential' object has no attribute 'output_names'. Non so molto di python o di programmazione. Quindi qualsiasi aiuto sarebbe apprezzato! Grazie.

Ciao Alberto, per favore pubblica la parte del tuo codice[usando il pulsanteCODICE (Alt -S)] in cui si verifica l'errore in modo che qualcuno che conosce Python(MetaTrader for Python | ONNX Models) possa indicare la soluzione...