Discussion de l'article "Comment utiliser les modèles ONNX dans MQL5" - page 5

 
Bel article. Le graphique de prédiction sur les données de test est décevant. Vous pourriez tout aussi bien vous passer de toute cette modélisation/formation DNN et utiliser simplement une prédiction du prochain prix égale au dernier prix connu. Je parie que la précision de prédiction de ce modèle trivial sera supérieure à celle de votre modèle DNN. Je suggère de comparer ces deux précisions et de les montrer ici. En général, l'utilisation de DNN pour prédire les prix est une mauvaise idée. Ils sont mieux adaptés à la classification des modèles de prix (par exemple, achat, vente, maintien). De plus, le nombre de poids dans votre DNN est astronomique. Il doit s'agir d'un surajustement.
 
Vladimir #:
Bel article. Le graphique de prédiction sur les données de test est décevant. Vous pourriez tout aussi bien vous passer de toute cette modélisation/formation DNN et utiliser simplement une prédiction du prochain prix égale au dernier prix connu. Je parie que la précision de prédiction de ce modèle trivial sera supérieure à celle de votre modèle DNN. Je suggère de comparer ces deux précisions et de les montrer ici. En général, l'utilisation de DNN pour prédire les prix est une mauvaise idée. Ils sont mieux adaptés à la classification des modèles de prix (par exemple, achat, vente, maintien). De plus, le nombre de poids dans votre DNN est astronomique. Il doit s'agir d'un surajustement.

Merci Vladimir.
Juste pour la discussion, lorsque le temps le permettra, je modifierai ce modèle pour effectuer une classification à des fins de comparaison.

N'hésitez pas à me faire part de vos idées.

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

Le tutoriel donne une entrée d'un lot SAMPLE_SIZE nombre d'entrées proches, vous voulez un lot d'entrées input_count.

De plus, votre modèle n'utilise pas de flottants comme entrées, mais des doubles,

Note du modérateur : Ce message est hors séquence car les messages ci-dessous ont été déplacés d'un autre sujet. Veuillez consulter le message ci-dessous.

 
Peut-on dépanner ensemble ce modèle ONNX ?

Bonjour à la communauté MQL5, J'ai essayé de suivre ce tutoriel sur la façon d'utiliser ONNX dans vos EA. Dans le tutoriel, un réseau neuronal était le modèle choisi, j'ai utilisé un arbre boosté par le gradient.

J'ai construit le modèle en utilisant le package Python InterpretML, et je l'ai exporté vers ONNX en utilisant ebm2onnx.

Je vais résumer le processus par lequel le modèle a été entraîné.

1) Le modèle a été entraîné sur 5 entrées, OHLC et hauteur, la hauteur est calculée comme ((H + L) / 2) - C.

2) Le modèle est un classificateur binaire, visant à classer la prochaine bougie comme étant à la hausse (1) ou à la baisse (0).

Modèle Données d'entraînement

Les données utilisées pour former le modèle.

3) Le modèle a ensuite été exporté au format ONNX.

Représentation de l'ONNX

Représentation du modèle ONNX.


Pour faire fonctionner le modèle, je me suis écarté du code du tutoriel et j'ai continué à éditer le code pour essayer de faire fonctionner le modèle ONNX, mais maintenant je ne sais vraiment pas ce que je fais de travers. Je n'arrête pas de recevoir une erreur indiquant que la poignée du modèle n'est pas valide.

J'ai joint le code MQL5 ci-dessous.

Je vais maintenant résumer les étapes que j'ai suivies dans mon code qui s'écartent de ce qui est indiqué dans le tutoriel, et j'expliquerai également pourquoi je me suis écarté du tutoriel.

1) LINE 57 : Setting Model Input Shape.
Dans le tutoriel, 3 dimensions ont été utilisées pour définir la forme de l'entrée et de la sortie, c'est-à-dire {1,SAMPLE_SIZE,1} ; Cependant, lorsque j'ai suivi cette approche, je n'ai cessé d'obtenir une erreur, en particulier l'erreur 5808. Après le processus habituel d'essais et d'erreurs, j'ai réalisé que si j'utilisais une seule dimension, le nombre d'entrées, l'erreur disparaissait.

2) LIGNE 68 : Définition de la forme de la sortie du modèle.

Même logique que ci-dessus.

Les autres écarts que j'ai faits n'affectent pas le modèle ; par exemple, j'ai suivi le temps en utilisant une logique que j'ai trouvée plus intuitive que celle mise en œuvre dans le didacticiel. Je n'ai pas eu besoin de normaliser les entrées car il s'agit d'un modèle basé sur les arbres.


Si vous pouvez repérer d'autres erreurs que j'ai commises, je vous serais reconnaissant de bien vouloir m'en faire part.

//+------------------------------------------------------------------+
//|ONNX.mq5 |
//|Copyright 2023, MetaQuotes Ltd. |
//| https ://www.mql5.com
//+------------------------------------------------------------------+
//Méta propriétés
#property copyright "Gamuchirai Zororo Ndawana"
#property link      "https://www.mql5.com"
#property version   "1.00"

//Bibliothèque commerciale
#include <Trade\Trade.mqh>

//Lecture de notre modèle ONNX et stockage dans un tableau de données
#resource "\\Files\\Python\\Volatility_75_EBM.onnx" as uchar ExtModel[]

/Définitions de mots-clés personnalisés
#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;

//Entrées
int input lot_mutliple = 1; /Combien de fois plus grand que le lot minimum devons-nous entrer ?

int OnInit()
  {
   /Vérifier si le symbole et la période de temps sont conformes aux conditions de formation
   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);
       }
    
    /Créer un modèle ONNX à partir de notre tableau de données
    ExtHandle = OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT);
    Print("ONNX Create from buffer status ",ExtHandle);
    
    /Vérification de la validité de la poignée
    if(ExtHandle == INVALID_HANDLE)
      {
            Comment("ONNX create from buffer error ", GetLastError());
            return(INIT_FAILED);
      }
   
   /Réglage de la forme de l'entrée
   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);
      }
      
   //Sélectionner la forme de la sortie
   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);
      }
    
    //Obtenir le volume minimum d'échanges autorisé 
    min_volume = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);  
    return(INIT_SUCCEEDED);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Fonction de désinitialisation de l'expert|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   if(ExtHandle != INVALID_HANDLE)
      {
         OnnxRelease(ExtHandle);
         ExtHandle = INVALID_HANDLE;
      }
  }
//+------------------------------------------------------------------+
//| Fonction de tic-tac expert|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   //Suivi du temps
   static datetime time_stamp;
   datetime time = iTime(_Symbol,PERIOD_M1,0);
      
    /Vérifier la nouvelle barre
     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;
      
      /Vérifier les signaux
      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 sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Discussion de l'article "Comment utiliser les modèles ONNX dans MQL5"

Stian Andreassen, 2023.12.08 20:51

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

Le tutoriel donne une entrée d'un lot SAMPLE_SIZE nombre d'entrées proches, vous voulez un lot d'entrées input_count.

De plus, votre modèle n'utilise pas de flottants comme entrées, mais des doubles,



J'ai appliqué ce que vous avez indiqué, mais l'erreur est toujours là.


Un lot d'input_count

Un lot d'entrées input_count.

Régler l'entrée sur double

Définir l'entrée à double

Message d'erreur

Message d'erreur.


Dossiers :
 
amuchirai Zororo Ndawana #:
Peut-on dépanner ensemble ce modèle 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. 

J'ai construit le modèle en utilisant le package InterpretML Python, et je l'ai exporté vers ONNX en utilisant ebm2onnx.

Je vais résumer le processus par lequel le modèle a été entraîné.

1) Le modèle a été entraîné sur 5 entrées, OHLC et hauteur, la hauteur est calculée comme ((H + L) / 2) - C.

2) Le modèle est un classificateur binaire, visant à classer la prochaine bougie comme étant à la hausse (1) ou à la baisse (0).

Les données utilisées pour former le modèle.

3) Le modèle a ensuite été exporté au format ONNX.

Représentation du modèle ONNX.


Pour faire fonctionner le modèle, je me suis écarté du code du tutoriel et j'ai continué à éditer le code pour essayer de faire fonctionner le modèle ONNX, mais maintenant je ne sais vraiment pas ce que je fais de travers. Je n'arrête pas de recevoir une erreur indiquant que la poignée du modèle n'est pas valide.

J'ai joint le code MQL5 ci-dessous.

Je vais maintenant résumer les étapes que j'ai suivies dans mon code qui s'écartent de ce qui est indiqué dans le tutoriel, et j'expliquerai également pourquoi je me suis écarté du tutoriel.

1) LINE 57 : Setting Model Input Shape.
Dans le tutoriel, 3 dimensions ont été utilisées pour définir la forme de l'entrée et de la sortie, c'est-à-dire {1,SAMPLE_SIZE,1} ; Cependant, lorsque j'ai suivi cette approche, je n'ai cessé d'obtenir une erreur, en particulier l'erreur 5808. Après le processus habituel d'essais et d'erreurs, j'ai réalisé que si j'utilisais une seule dimension, le nombre d'entrées, l'erreur disparaissait.

2) LIGNE 68 : Définition de la forme de la sortie du modèle.

Même logique que ci-dessus.

Les autres écarts que j'ai faits n'affectent pas le modèle ; par exemple, j'ai suivi le temps en utilisant une logique que j'ai trouvée plus intuitive que celle mise en œuvre dans le didacticiel. Je n'ai pas eu besoin de normaliser les entrées car il s'agit d'un modèle basé sur les arbres.


Si vous pouvez repérer d'autres erreurs que j'ai commises, je vous serais reconnaissant de bien vouloir m'en faire part.





J'ai appliqué ce que vous avez indiqué, mais l'erreur est toujours là.


Un lot d'entrées input_count.

Définir l'entrée à double

Message d'erreur.


Il semble que MQL5 ne supporte pas (ou plutôt ONNXMLTools ne supporte pas) encore l'ONNX d'EBM :

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

Si vous vous référez aux pièces jointes ONNX (en particulier model.eurusd.D1.10.class.onnx qui utilise 4 entrées) à partir de https://www.mql5.com/fr/articles/12484 ; et utilisez Netron(version web) pour visualiser les fichiers onnx, vous verrez les différences.

Je pense que les deux articles suivants vous aideront également à mieux comprendre :

Les modèles de régression de la bibliothèque Scikit-learn et leur exportation vers ONNX

Modèles de classification de la bibliothèque Scikit-Learn et leur exportation vers 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.
 

Bonjour à tous,


Nous essayons d'utiliser un réseau neuronal keras avec 11 prédicteurs à un moment donné (taille de lot 32) pour faire des prédictions sur le XauUsd (où la sortie est un nombre singulier entre 0 et 1). Tout d'abord, nous chargeons à partir de OnnxCreatefrombuffer (parce que OnnxCreate lui-même ne fonctionne pas pour nous), puis nous obtenons toujours une erreur à l'étape OnnxRun, où j'ai joint les deux erreurs ci-dessous. Si vous avez besoin d'aide pour savoir à quelle dimension donner une nouvelle forme à l'entrée, dans quel format mettre notre vecteur prédicteur (s'il doit être un vecteur ?), ou si vous avez besoin d'aide ou de suggestions sur la syntaxe pour résoudre ces erreurs, je vous en prie, je vous en prie. Nous avons essayé de remodeler en toutes sortes de combinaisons de vecteurs 32, 1, 11, mais sans succès, et nous n'avons aucune idée des étapes suivantes... Merci beaucoup à tous ceux qui peuvent nous aider ! Ben.

' error 5808'

ONNX : le paramètre d'entrée #0 tenseur a une mauvaise dimension [0], essayez d'utiliser OnnxSetInputShape'

ONNX : la taille du paramètre d'entrée #0 n'est pas valide, 1408 octets attendus au lieu de 480.

 

Bonjour, j'essaie d'utiliser le script de fichier

OnnxModelInfo.mq5

mais je n'arrive pas à le faire fonctionner, qu'est ce que je fais de travers ? ça ne peut pas être si compliqué !

J'ai copié-collé le script OnnxModelInfo, et je l'ai sauvegardé dans le dossier Files.

J'ai un modèle Onnx (ci-joint)

et lorsque je compile le script, 21 erreurs apparaissent.

Est-ce que quelqu'un peut m'aider ? Je vous prie d'agréer, Madame, Monsieur, l'expression de mes salutations distinguées.

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

Un nouvel article Utiliser les modèles ONNX dans MQL5 a été publié :

Auteur : MetaQuotes

Bonjour messieurs.

Quelqu'un peut-il m'aider, car à la fin du processus en python, l'erreur suivante apparaît : AttributeError : 'Sequential' object has no attribute 'output_names'. Je ne connais pas grand-chose à Python ou à la programmation. Toute aide serait donc appréciée ! Je vous remercie.

 
Bonjour messieurs.

Quelqu'un peut-il m'aider, car à la fin du processus en python, l'erreur suivante apparaît : AttributeError : L'objet 'Sequential' n'a pas d'attribut 'output_names'. Je ne connais pas grand chose à Python ou à la programmation. Toute aide sera donc la bienvenue ! Je vous remercie.
 
Alberto Henrique Tacoronte # Bonjour à tous. Quelqu'un peut-il m'aider, car à la fin du processus python, l'erreur suivante apparaît : AttributeError : 'Sequential' object has no attribute 'output_names'. Je ne connais pas grand-chose à Python ou à la programmation. Toute aide serait donc appréciée ! Je vous remercie.

Bonjour Alberto, merci de poster la partie de votre code[en utilisant le boutonCODE (Alt -S)] où l'erreur se produit afin que quelqu'un qui connaît Python(MetaTrader for Python | ONNX Models) puisse vous indiquer la solution...