Convalida del modello nello Strategy Tester

I modelli creati per le operazioni sui mercati finanziari possono essere convalidati nel terminale MetaTrader 5 Strategy Tester. Questa è l'opzione più veloce e conveniente, che elimina la necessità di emulare ulteriormente l'ambiente di mercato e le condizioni di trading.

Per testare il modello, creiamo un Expert Advisor basato sul codice del progetto pubblico ONNX.Price.Prediction. Questo richiederà alcune modifiche.

Spostarsi per la creazione del modello nella funzione OnInit. La sessione onnx sarà chiusa in OnDeinit. Individua il blocco delle operazioni del modello principale nel gestore OnTick.

Inoltre, aggiungere il prezzo della Chiusura ottenuto delle due barre precedenti, che è necessario per confrontare il prezzo attuale di Chiusura e la previsione.

Il codice dell'Expert Advisor è piccolo e facile da leggere.

 
const long   ExtInputShape [] = {1,10,4}; // dimensione del modello d'ingresso
const long   ExtOutputShape[] = {1,1};    // dimensione del modello d'uscita
#resource "Python/model.onnx" as uchar ExtModel[];// modello come risorsa
 
long handle;         // handle del modello
ulong predictions=0// contatore delle previsioni
ulong confirmed=0;   // contatore previsioni con successo
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//-- controlli di base
   if(_Symbol!="EURUSD")
     {
      Print("Symbol must be EURUSD, testing aborted");
      return(-1);
     }
   if(_Period!=PERIOD_H1)
     {
      Print("Timeframe must be H1, testing aborted");
      return(-1);
     }
//-- creare il modello
   handle=OnnxCreateFromBuffer(ExtModel,ONNX_DEBUG_LOGS);
//-- specificare la dimensione dei dati d'ingresso
   if(!OnnxSetInputShape(handle,0,ExtInputShape))
     {
      Print("OnnxSetInputShape failed, error ",GetLastError());
      OnnxRelease(handle);
      return(-1);
     }
//-- specificare la dimensione dei dati d'uscita
   if(!OnnxSetOutputShape(handle,0,ExtOutputShape))
     {
      Print("OnnxSetOutputShape failed, error ",GetLastError());
      OnnxRelease(handle);
      return(-1);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//-- operazione del modello completa
   OnnxRelease(handle);
//-- calcolo e statistiche di previsione d'uscita
   PrintFormat("Successfull predictions = %.2f %%",confirmed*100./double(predictions));
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   static datetime open_time=0;
   static double predict;
//-- controlla l'orario di apertura della barra corrente
   datetime time=iTime(_Symbol,_Period,0);
   if(time==0)
     {
      PrintFormat("Failed to get Time(0), error %d"GetLastError());
      return;
     }
//-- se l'orario di apertura non è cambiato, uscire fino alla prossima chiamata OnTick
   if(time==open_time)
      return;
//-- ottenere i prezzi di Chiusura delle ultime due barre completate
   double close[];
   int recieved=CopyClose(_Symbol,_Period,1,2,close);
   if(recieved!=2)
     {
      PrintFormat("CopyClose(2 bars) failed, error %d",GetLastError());
      return;
     }
   double delta_predict=predict-close[0]; // variazione dei prezzi prevista
   double delta_actual=close[1]-close[0]; // variazione effettiva dei prezzi
   if((delta_predict>0 && delta_actual>0) || (delta_predict<0 && delta_actual<0))
      confirmed++;
 
//-- calcolare il prezzo di Chiusura sulla nuova barra per convalidare il prezzo sulla barra successiva
   matrix rates;
//-- ottenere 10 barre
   if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC,1,10))
      return;
//---inserire un insieme di vettori OHLC
   matrix x_norm=rates.Transpose();
   vector m=x_norm.Mean(0);
   vector s=x_norm.Std(0);
   matrix mm(10,4);
   matrix ms(10,4);
//-- riempire le matrici di normalizzazione
   for(int i=0i<10i++)
     {
      mm.Row(m,i);
      ms.Row(s,i);
     }
//-- normalizzare i dati d'ingresso
   x_norm-=mm;
   x_norm/=ms;
//-- convertire i dati d'ingresso normalizzati in tipo float
   matrixf x_normf;
   x_normf.Assign(x_norm);
//-- ottenere i dati d'uscita del modello qui, cioè la previsione dei prezzi
   vectorf y_norm(1);
//-- eseguire il modello
   if(!OnnxRun(handle,ONNX_DEBUG_LOGS | ONNX_NO_CONVERSION,x_normf,y_norm))
     {
      Print("OnnxRun failed, error ",GetLastError());
     }
//-- fare la trasformazione inversa per ottenere il prezzo previsto e per convalidarlo su una nuova barra
   predict=y_norm[0]*s[3]+m[3];
   predictions++;  // aumentare il contatore delle previsioni
   Print(predictions,". close prediction = ",predict);
//-- salva l'orario di apertura della barra per controllarlo al tick successivo
   open_time=time;
  }

Compilare l'Expert Advisor ed eseguire il test nel periodo dell'anno 2022. Specificare EURUSD con il timeframe H1, che sono i dati su cui il modello è stato addestrato. La modalità di modellazione tick può essere ignorata, poiché il codice controlla la nascita di una nuova barra.  

Impostazioni Backtest

 

Esegui e controlla il risultato in testing journal. Si nota che poco più del 50% delle previsioni erano corrette nel 2022.

Testing Journal

 

Se il test preliminare del modello ha generato risultati soddisfacenti, è possibile iniziare a scrivere una strategia di trading a tutti gli effetti sulla base di questo modello.