Accueil Trading Systématique Publication

Schnick : Testez le Système de Machine Learning sur MetaTrader 5

Pièce jointe
1370.zip (2.63 KB, Télécharger 0 fois)

Ce script fait partie de l'article "Machine Learning : Comment les Machines à Vecteurs de Support peuvent être utilisées en Trading" publié sur le site MQL5.

Cette version du code a été spécifiquement conçue pour être utilisée avec la version démonstration de l'outil d'apprentissage des machines à vecteurs de support, disponible gratuitement sur le MQL5 Market.

Imaginons un scénario hypothétique : vous êtes un chercheur étudiant un animal rare, le Schnick, qui se trouve uniquement dans les profondeurs de l'Arctique. Étant donné la rareté de ces créatures, seulement un petit nombre ont été découverts (disons environ 5000). En tant que chercheur, vous vous demandez... comment puis-je identifier un Schnick ?

Tout ce dont vous disposez, ce sont les articles de recherche publiés par les quelques chercheurs ayant croisé un Schnick. Dans ces publications, les auteurs décrivent certaines caractéristiques des Schnicks qu'ils ont observés, comme la taille, le poids, le nombre de pattes, etc. Toutefois, toutes ces caractéristiques varient d'un article à l'autre sans qu'il n'y ait de schéma discernable...

Comment pouvons-nous utiliser ces données pour identifier un nouvel animal comme étant un Schnick ?

Une solution possible à notre problème consiste à utiliser une machine à vecteurs de support pour identifier les schémas dans les données et créer un cadre permettant de classer les animaux comme étant un Schnick ou non. La première étape consiste à constituer un ensemble de données qui pourra être utilisé pour entraîner votre machine à vecteurs de support afin d'identifier les Schnicks. Les données d'entraînement sont un ensemble d'entrées et de sorties correspondantes que la machine à vecteurs de support peut analyser pour en extraire un modèle.

Ce script tente de démontrer la puissance de l'utilisation des machines à vecteurs de support pour résoudre des problèmes de classification en utilisant l'outil d'apprentissage des machines à vecteurs de support disponible sur le MQL5 Market. Une description complète de ce problème hypothétique et du script se trouve dans l'article "Machine Learning : Comment les Machines à Vecteurs de Support peuvent être utilisées en Trading". Cet article inclut un guide sur l'utilisation du script et sur la manière dont ce problème peut fournir des perspectives sur l'utilisation de l'apprentissage automatique pour évaluer les tendances du marché.

Code :

//+------------------------------------------------------------------+
//|                                                                                    Schnick_Demo.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"

//+------------------------------------------------------------------+
//| Ce script démontre les capacités de l'outil d'apprentissage
//|                     Machine à Vecteurs de Support
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| L'instruction suivante importe toutes les fonctions incluses dans
//| l'outil Machine à Vecteurs de Support 'svMachineTool.ex5'
//+------------------------------------------------------------------+
#import "svMachineTool_demo.ex5"
enum ENUM_TRADE {BUY,SELL};
enum ENUM_OPTION {OP_MEMORY,OP_MAXCYCLES,OP_TOLERANCE};
int  initSVMachine(void);
void setIndicatorHandles(int handle,int &indicatorHandles[],int offset,int N);
void setParameter(int handle,ENUM_OPTION option,double value);
bool genOutputs(int handle,ENUM_TRADE trade,int StopLoss,int TakeProfit,double duration);
bool genInputs(int handle);
bool setInputs(int handle,double &Inputs[],int nInputs);
bool setOutputs(int handle,bool &Outputs[]);
bool training(int handle);
bool classify(int handle);
bool classify(int handle,int offset);
bool classify(int handle,double &iput[]);
void deinitSVMachine(void);
#import
//--- Le nombre d'entrées que nous allons utiliser pour le svm
int N_Inputs=7;
//+------------------------------------------------------------------+
//| Fonction d'initialisation de l'expert                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   double inputs[];           //tableau double vide à utiliser pour créer les entrées d'entraînement
   bool   outputs[];          //tableau bool vide à utiliser pour créer les entrées d'entraînement
   int N_TrainingPoints=5000; //définit le nombre d'échantillons d'entraînement à générer
   int N_TestPoints=5000     //définit le nombre d'échantillons à utiliser lors des tests

   genTrainingData(inputs,outputs,N_TrainingPoints); //Génère les entrées et sorties à utiliser pour l'entraînement du svm

   int handle1=initSVMachine();             //initialise une nouvelle machine à vecteurs de support et retourne un handle
   setInputs(handle1,inputs,7);             //passe les entrées (sans erreurs) à la machine à vecteurs de support
   setOutputs(handle1,outputs);             //passe les sorties (sans erreurs) à la machine à vecteurs de support
   setParameter(handle1,OP_TOLERANCE,0.01); //définit le paramètre de tolérance d'erreur à <5%
   training(handle1);                       //entraîne la machine à vecteurs de support en utilisant les entrées/sorties passées

   insertRandomErrors(inputs,outputs,500);  //prend les entrées/sorties originales générées et ajoute des erreurs aléatoires aux données

   int handle2=initSVMachine();             //initialise une nouvelle machine à vecteurs de support et retourne un handle
   setInputs(handle2,inputs,7);             //passe les entrées (avec erreurs) à la machine à vecteurs de support
   setOutputs(handle2,outputs);             //passe les sorties (avec erreurs) à la machine à vecteurs de support
   setParameter(handle2,OP_TOLERANCE,0.01); //définit le paramètre de tolérance d'erreur à <5%
   training(handle2);                       //entraîne la machine à vecteurs de support en utilisant les entrées/sorties passées

   double t1=testSVM(handle1,N_TestPoints); //teste l'exactitude de la machine à vecteurs de support entraînée et la sauvegarde dans t1
   double t2=testSVM(handle2,N_TestPoints); //teste l'exactitude de la machine à vecteurs de support entraînée et la sauvegarde dans t2

   Print("L'exactitude du SVM est ",NormalizeDouble(t1,2),"% (utilisant les entrées/sorties d'entraînement sans erreurs)");
   Print("L'exactitude du SVM est ",NormalizeDouble(t2,2),"% (utilisant les entrées/sorties d'entraînement avec erreurs)");
   deinitSVMachine(); //libère toute la mémoire utilisée pour générer le SVM afin d'éviter les fuites de mémoire
   return(0);
  }
//+------------------------------------------------------------------+
//| Fonction de désinitialisation de l'expert                                   |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Aucune fonction exécutée dans OnDeinit()
  }
//+------------------------------------------------------------------+
//| Fonction de tick de l'expert                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Aucune fonction exécutée dans OnTick()   
  }
//+------------------------------------------------------------------+
//| Cette fonction prend les propriétés d'observation de l'animal observé
//| et, en fonction des critères choisis, retourne
//| vrai/faux selon qu'il s'agit d'un schnick
//+------------------------------------------------------------------+
bool isItASchnick(double height,double weight,double N_legs,double N_eyes,double L_arm,double av_speed,double f_call)
  {
   if(height   < 1000  || height   > 1100)  return(false); //Si la hauteur est en dehors des paramètres > retourner(false)
   if(weight   < 40    || weight   > 50)    return(false); //Si le poids est en dehors des paramètres > retourner(false)
   if(N_legs   < 8     || N_legs   > 10)    return(false); //Si le N_Legs est en dehors des paramètres > retourner(false)
   if(N_eyes   < 3     || N_eyes   > 4)     return(false); //Si le N_eyes est en dehors des paramètres > retourner(false)
   if(L_arm    < 400   || L_arm    > 450)   return(false); //Si le L_arm  est en dehors des paramètres > retourner(false)
   if(av_speed < 2     || av_speed > 2.5)   return(false); //Si la vitesse moyenne est en dehors des paramètres > retourner(false)
   if(f_call   < 11000 || f_call   > 15000) return(false); //Si f_call est en dehors des paramètres > retourner(false)
   return(true);                                           //Sinon > retourner(true)
  }
//+------------------------------------------------------------------+
//| Cette fonction prend un tableau double vide et un tableau booléen vide
//| et génère les entrées/sorties à utiliser pour entraîner le SVM
//+------------------------------------------------------------------+ 
void genTrainingData(double &inputs[],bool &outputs[],int N)
  {
   double in[];                //crée un tableau double vide à utiliser
                                   //pour stocker temporairement les entrées générées
   ArrayResize(in,N_Inputs);       //redimensionne le tableau in[] à N_Inputs
   ArrayResize(inputs,N*N_Inputs); //redimensionne le tableau inputs[] à une taille de N*N_Inputs 
   ArrayResize(outputs,N);         //redimensionne le tableau outputs[] à une taille de N 
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);    //Entrée aléatoire générée pour la hauteur
      in[1]=    randBetween(38,52);       //Entrée aléatoire générée pour le poids
      in[2]=    randBetween(7,11);        //Entrée aléatoire générée pour N_legs
      in[3]=    randBetween(3,4.2);       //Entrée aléatoire générée pour N_eyes
      in[4]=    randBetween(380,450);     //Entrée aléatoire générée pour L_arms
      in[5]=    randBetween(2,2.6);       //Entrée aléatoire générée pour av_speed
      in[6]=    randBetween(10500,15500); //Entrée aléatoire générée pour f_call

      //--- copie les nouvelles entrées aléatoires générées dans le tableau d'entrée d'entraînement
      ArrayCopy(inputs,in,i*N_Inputs,0,N_Inputs);
      //--- évalue les entrées aléatoires et détermine si c'est un schnick
      outputs[i]=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]);
   }
  }
//+------------------------------------------------------------------+
//| Cette fonction prend le handle du SVM entraîné et teste son
//| succès à classifier de nouvelles entrées aléatoires
//+------------------------------------------------------------------+ 
double testSVM(int handle,int N)
  {
   double in[];
   int atrue=0;
   int afalse=0;
   int N_correct=0;
   bool Predicted_Output;
   bool Actual_Output;
   ArrayResize(in,N_Inputs);
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);    //Entrée aléatoire générée pour la hauteur
      in[1]=    randBetween(38,52);       //Entrée aléatoire générée pour le poids
      in[2]=    randBetween(7,11);        //Entrée aléatoire générée pour N_legs
      in[3]=    randBetween(3,4.2);       //Entrée aléatoire générée pour N_eyes
      in[4]=    randBetween(380,450);     //Entrée aléatoire générée pour L_arms
      in[5]=    randBetween(2,2.6);       //Entrée aléatoire générée pour av_speed
      in[6]=    randBetween(10500,15500); //Entrée aléatoire générée pour f_call

      //--- utilise la fonction isItASchnick pour déterminer la sortie réelle désirée
      Actual_Output=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]);
      //--- utilise le SVM entraîné pour retourner la sortie prédite.
      Predicted_Output=classify(handle,in);
      if(Actual_Output==Predicted_Output)
        {
         N_correct++; //Cette instruction compte le nombre de fois où la sortie prédite est correcte.
        }
     }
//--- retourne l'exactitude du SVM entraîné en pourcentage
   return(100*((double)N_correct/(double)N));
  }
//+------------------------------------------------------------------+
//| Cette fonction prend les entrées et sorties d'entraînement correctes 
//| générées et insère N erreurs aléatoires dans les données
//+------------------------------------------------------------------+ 
void insertRandomErrors(double &inputs[],bool &outputs[],int N)
  {
   int nTrainingPoints=ArraySize(outputs); //calcule le nombre de points d'entraînement
   int index;                              //crée un nouvel entier 'index'
   bool randomOutput;                      //crée un nouveau booléen 'randomOutput'
   double in[];                            //crée un tableau double vide à utiliser
                                           //pour stocker temporairement les entrées générées
   ArrayResize(in,N_Inputs);               //redimensionne le tableau in[] à N_Inputs
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);    //Entrée aléatoire générée pour la hauteur
      in[1]=    randBetween(38,52);       //Entrée aléatoire générée pour le poids
      in[2]=    randBetween(7,11);        //Entrée aléatoire générée pour N_legs
      in[3]=    randBetween(3,4.2);       //Entrée aléatoire générée pour N_eyes
      in[4]=    randBetween(380,450);     //Entrée aléatoire générée pour L_arms
      in[5]=    randBetween(2,2.6);       //Entrée aléatoire générée pour av_speed
      in[6]=    randBetween(10500,15500); //Entrée aléatoire générée pour f_call

      //--- choisit aléatoirement une des entrées d'entraînement pour insérer une erreur
      index=(int)MathRound(randBetween(0,nTrainingPoints-1));
      //--- génère une sortie booléenne aléatoire à utiliser pour créer une erreur
      if(randBetween(0,1)>0.5) randomOutput=true;
      else                     randomOutput=false;

      //--- copie les nouvelles entrées aléatoires générées dans le tableau d'entrée d'entraînement
      ArrayCopy(inputs,in,index*N_Inputs,0,N_Inputs);
      //--- copie la nouvelle sortie aléatoire générée dans le tableau de sortie d'entraînement
      outputs[index]=randomOutput;
     }
  }
//+------------------------------------------------------------------+
//| Cette fonction est utilisée pour créer une valeur aléatoire entre t1 et t2
//+------------------------------------------------------------------+ 
double randBetween(double t1,double t2)
  {
   return((t2-t1)*((double)MathRand()/(double)32767)+t1);
  }
//+------------------------------------------------------------------+

Articles connexes

Commentaire (0)