Validation du modèle dans le Strategy Tester

Les modèles créés pour les opérations sur les marchés financiers peuvent être validés dans le Strategy Tester du terminal MetaTrader 5. Il s'agit de l'option la plus rapide et la plus pratique, qui élimine le besoin d'émuler en plus l'environnement du marché et les conditions de trading.

Pour tester le modèle, créons un Expert Advisor basé sur le code du projet public ONNX.Price.Prediction. Cela nécessitera quelques modifications.

Déplacez la création du modèle vers la fonction OnInit. La session onnx sera fermée dans OnDeinit. Localisez le bloc d'opérations du modèle principal dans le gestionnaire OnTick.

Ajoutez également l'obtention du prix de clôture des deux barres précédentes, qui est nécessaire pour comparer le prix de clôture réel et la prédiction.

Le code Expert Advisor est petit et facile à lire.

 
const long   ExtInputShape [] = {1,10,4}; // forme d'entrée du modèle
const long   ExtOutputShape[] = {1,1};    // forme de sortie du modèle
#resource "Python/model.onnx" as uchar ExtModel[];// modèle en tant que ressource
 
long handle;         // handle du modèle
ulong predictions=0// compteur de prédictions
ulong confirmed=0;   // compteur de prédictions réussies
//+------------------------------------------------------------------+
//| Fonction d'initialisation de l'expert                            |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- vérifications de base
   if(_Symbol!="EURUSD")
     {
      Print("Le symbole doit être EURUSD, test abandonné");
      return(-1);
     }
   if(_Period!=PERIOD_H1)
     {
      Print("La période doit être H1, test annulé");
      return(-1);
     }
//--- crée le modèle
   handle=OnnxCreateFromBuffer(ExtModel,ONNX_DEBUG_LOGS);
//--- spécifie la forme des données d'entrée
   if(!OnnxSetInputShape(handle,0,ExtInputShape))
     {
      Print("Echec de OnnxSetInputShape, erreur ",GetLastError());
      OnnxRelease(handle);
      return(-1);
     }
//--- spécifie la forme des données de sortie
   if(!OnnxSetOutputShape(handle,0,ExtOutputShape))
     {
      Print("Echec de OnnxSetOutputShape, erreur ",GetLastError());
      OnnxRelease(handle);
      return(-1);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Fonction de dé-initialisation de l'expert                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- termine l'opération du modèle
   OnnxRelease(handle);
//--- calcule et génère des statistiques de prédiction
   PrintFormat("Prédictions réussies = %.2f %%",confirmed*100./double(predictions));
  }
//+------------------------------------------------------------------+
//| Fonction des ticks de l'expert                                   |
//+------------------------------------------------------------------+
void OnTick()
  {
   static datetime open_time=0;
   static double predict;
//--- vérifie l'heure d'ouverture actuelle de la barre
   datetime time=iTime(_Symbol,_Period,0);
   if(time==0)
     {
      PrintFormat("Échec de l'obtention de Time(0), erreur %d"GetLastError());
      return;
     }
//--- si l'heure d'ouverture n'a pas changé, quitter jusqu'au prochain appel OnTick
   if(time==open_time)
      return;
//--- obtient les prix de clôture des deux dernières barres terminées
   double close[];
   int recieved=CopyClose(_Symbol,_Period,1,2,close);
   if(recieved!=2)
     {
      PrintFormat("Echec de CopyClose(2 barres), erreur %d",GetLastError());
      return;
     }
   double delta_predict=predict-close[0]; // changement de prix prévu
   double delta_actual=close[1]-close[0]; // changement de prix réel
   if((delta_predict>0 && delta_actual>0) || (delta_predict<0 && delta_actual<0))
      confirmed++;
 
//--- calcule le prix de Clôture sur la nouvelle barre pour valider le prix de la barre suivante
   matrix rates;
//--- récupère 10 barres
   if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC,1,10))
      return;
//--- saisie d'un ensemble de vecteurs 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);
//--- remplissage des matrices de normalisation
   for(int i=0i<10i++)
     {
      mm.Row(m,i);
      ms.Row(s,i);
     }
//--- normalisation des données d'entrée
   x_norm-=mm;
   x_norm/=ms;
//--- convertit les données d'entrée normalisées en type flottant
   matrixf x_normf;
   x_normf.Assign(x_norm);
//--- récupère les données de sortie du modèle ici, c'est-à-dire la prévision de prix
   vectorf y_norm(1);
//--- exécute le modèle
   if(!OnnxRun(handle,ONNX_DEBUG_LOGS | ONNX_NO_CONVERSION,x_normf,y_norm))
     {
      Print("Echec de OnnxRun, erreur ",GetLastError());
     }
//--- effectue une transformation inverse pour obtenir le prix prédit et le valider sur une nouvelle barre
   predict=y_norm[0]*s[3]+m[3];
   predictions++;  // augmente le compteur de prédictions
   Print(predictions,". prédiction fermée = ",predict);
//--- enregistre l'heure d'ouverture de la barre pour la vérifier au prochain tick
   open_time=time;
  }

Compilez l'Expert Advisor et exécutez les tests pour l'année 2022. Spécifiez EURUSD avec la période H1, qui correspond aux données sur lesquelles le modèle a été formé. Le mode de modélisation des ticks peut être ignoré, puisque le code vérifie l'arrivée d'une nouvelle barre.  

Paramètres de Backtest

 

Exécutez et vérifiez le résultat dans le journal de test. Il montre qu'un peu plus de 50% des prévisions étaient correctes en 2022.

Journal de Test

 

Si les tests préliminaires du modèle ont généré des résultats satisfaisants, vous pouvez commencer à écrire une stratégie de trading basée sur ce modèle.