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.
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
- Utiliser MQL5 Wizard pour Créer un Expert Advisor Basé sur les Modèles de Chandeliers Englobants et MFI
- Développez un Expert Advisor avec MQL5 : Signaux de Trading 3 Corbeaux Noirs / 3 Soldats Blancs + RSI
- Découvrez CoensioTrader1V06 : Votre nouvel allié sur MetaTrader 5
- Découvrez Exp5-VirtualTradePad : L'outil incontournable pour MetaTrader 5
- Découvrez l'Expert Advisor exp_iCustom_v5 pour MetaTrader 4