Schnick: Tester di Machine Learning per MetaTrader 5 - Demo Gratuita

Mike 2012.12.14 00:58 62 0 0
Allegato

Questo script è stato sviluppato per far parte dell'articolo "Machine Learning: Come i Support Vector Machines possono essere utilizzati nel Trading" pubblicato sul sito MQL5.

Questa versione del codice è stata scritta specificamente per essere utilizzata insieme alla versione demo del Support Vector Machine Learning Tool disponibile gratuitamente su MQL5 Market.

Immagina di essere un ricercatore che indaga su un animale raro trovato solo nelle profondità dell'Artico, chiamato Schnick. Data la remota ubicazione di questi animali, solo un ristretto numero è mai stato avvistato (diciamo circa 5000). Come ricercatore, ti trovi di fronte alla domanda: come posso identificare uno Schnick?

Hai a disposizione solo i documenti di ricerca pubblicati da alcuni ricercatori che ne hanno avvistati. In questi documenti, gli autori descrivono certe caratteristiche degli Schnick che hanno trovato, come altezza, peso, numero di zampe, ecc., ma tutte queste caratteristiche variano tra i vari articoli senza un modello riconoscibile…

Come possiamo utilizzare questi dati per identificare un nuovo animale come Schnick?

Una possibile soluzione è utilizzare un support vector machine per identificare i modelli nei dati e creare un framework che possa essere utilizzato per classificare gli animali come Schnick o non Schnick. Il primo passo è creare un insieme di dati da utilizzare per addestrare il tuo support vector machine a identificare gli Schnick. I dati di addestramento sono un insieme di input e output corrispondenti che il support vector machine analizzerà per estrarre un modello.

Questo script prova a dimostrare il potere dell'uso dei support vector machines nella risoluzione di problemi di classificazione utilizzando il Support Vector Machine Learning Tool disponibile su MQL5 Market. Una descrizione completa di questo problema ipotetico e dello script si trova nell'articolo "Machine Learning: Come i Support Vector Machines possono essere utilizzati nel Trading". L'articolo include una guida su come utilizzare lo script e come questo problema possa fornire spunti sull'uso del machine learning per valutare le tendenze di mercato.

Codice:

//+------------------------------------------------------------------+
//|                                                 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"

//+------------------------------------------------------------------+
//| Questo script dimostra le capacità del Support Vector
//|                     Machine Learning Tool
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| La seguente dichiarazione importa tutte le funzioni incluse in
//| il Support Vector Machine Tool '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
//--- Il numero di input che utilizzeremo per il svm
int N_Inputs=7;
//+------------------------------------------------------------------+
//| Funzione di inizializzazione dell'Expert                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   double inputs[];           //array vuoto di double da usare per creare gli input di addestramento
   bool   outputs[];          //array vuoto di bool da usare per creare gli input di addestramento
   int N_TrainingPoints=5000; //definisce il numero di campioni di addestramento da generare
   int N_TestPoints=5000     //definisce il numero di campioni da utilizzare durante il test

   genTrainingData(inputs,outputs,N_TrainingPoints); //Genera gli input e gli output da utilizzare per addestrare il svm

   int handle1=initSVMachine();             //inizializza un nuovo support vector machine e restituisce un handle
   setInputs(handle1,inputs,7);             //passa gli input (senza errori) al support vector machine
   setOutputs(handle1,outputs);             //passa gli output (senza errori) al support vector machine
   setParameter(handle1,OP_TOLERANCE,0.01); //imposta il parametro di tolleranza all'errore a <5%
   training(handle1);                       //addestra il support vector machine utilizzando gli input/output passati

   insertRandomErrors(inputs,outputs,500);  //prende gli input/output originali generati e aggiunge errori casuali ai dati

   int handle2=initSVMachine();             //inizializza un nuovo support vector machine e restituisce un handle
   setInputs(handle2,inputs,7);             //passa gli input (con errori) al support vector machine
   setOutputs(handle2,outputs);             //passa gli output (con errori) al support vector machine
   setParameter(handle2,OP_TOLERANCE,0.01); //imposta il parametro di tolleranza all'errore a <5%
   training(handle2);                       //addestra il support vector machine utilizzando gli input/output passati

   double t1=testSVM(handle1,N_TestPoints); //testa l'accuratezza del support vector machine addestrato e la salva in t1
   double t2=testSVM(handle2,N_TestPoints); //testa l'accuratezza del support vector machine addestrato e la salva in t2

   Print("L'accuratezza del SVM è ",NormalizeDouble(t1,2),"% (utilizzando input/output di addestramento senza errori)");
   Print("L'accuratezza del SVM è ",NormalizeDouble(t2,2),"% (utilizzando input/output di addestramento con errori)");
   deinitSVMachine(); //Pulisce tutta la memoria utilizzata nella generazione del SVM per evitare perdite di memoria
   return(0);
  }
//+------------------------------------------------------------------+
//| Funzione di deinizializzazione dell'Expert                                   |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Nessuna funzione eseguita in OnDeinit()
  }
//+------------------------------------------------------------------+
//| Funzione tick dell'Expert                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Nessuna funzione eseguita in OnTick()   
  }
//+------------------------------------------------------------------+
//| Questa funzione prende le proprietà di osservazione dell'animale osservato e, in base ai criteri scelti, restituisce
//| true/false se è uno 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); //Se l'altezza è al di fuori dei parametri > restituisci(false)
   if(weight   < 40    || weight   > 50)    return(false); //Se il peso è al di fuori dei parametri > restituisci(false)
   if(N_legs   < 8     || N_legs   > 10)    return(false); //Se il N_Legs è al di fuori dei parametri > restituisci(false)
   if(N_eyes   < 3     || N_eyes   > 4)     return(false); //Se il N_eyes è al di fuori dei parametri > restituisci(false)
   if(L_arm    < 400   || L_arm    > 450)   return(false); //Se il L_arm  è al di fuori dei parametri > restituisci(false)
   if(av_speed < 2     || av_speed > 2.5)   return(false); //Se la av_speed è al di fuori dei parametri > restituisci(false)
   if(f_call   < 11000 || f_call   > 15000) return(false); //Se il f_call è al di fuori dei parametri > restituisci(false)
   return(true);                                           //Altrimenti > restituisci(true)
  }
//+------------------------------------------------------------------+
//| Questa funzione prende un array di double vuoto e un array booleano vuoto
//| e genera gli input/output da utilizzare per addestrare il SVM
//+------------------------------------------------------------------+ 
void genTrainingData(double &inputs[],bool &outputs[],int N)
  {
   double in[];                //crea un array di double vuoto da utilizzare
                    //per memorizzare temporaneamente gli input generati
   ArrayResize(in,N_Inputs);       //ridimensiona l'array in[] a N_Inputs
   ArrayResize(inputs,N*N_Inputs); //ridimensiona l'array inputs[] a una dimensione di N*N_Inputs 
   ArrayResize(outputs,N);         //ridimensiona l'array outputs[] a una dimensione di N 
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);    //Input casuale generato per l'altezza
      in[1]=    randBetween(38,52);       //Input casuale generato per il peso
      in[2]=    randBetween(7,11);        //Input casuale generato per N_legs
      in[3]=    randBetween(3,4.2);       //Input casuale generato per N_eyes
      in[4]=    randBetween(380,450);     //Input casuale generato per L_arms
      in[5]=    randBetween(2,2.6);       //Input casuale generato per av_speed
      in[6]=    randBetween(10500,15500); //Input casuale generato per f_call

      //--- copia i nuovi input casuali generati nell'array di input di addestramento
      ArrayCopy(inputs,in,i*N_Inputs,0,N_Inputs);
      //--- valuta gli input casuali e determina se è uno schnick
      outputs[i]=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]);
   }
  }
//+------------------------------------------------------------------+
//| Questa funzione prende l'handle per il SVM addestrato e testa quanto
//| sia efficace nella classificazione di nuovi input casuali
//+------------------------------------------------------------------+ 
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);    //Input casuale generato per l'altezza
      in[1]=    randBetween(38,52);       //Input casuale generato per il peso
      in[2]=    randBetween(7,11);        //Input casuale generato per N_legs
      in[3]=    randBetween(3,4.2);       //Input casuale generato per N_eyes
      in[4]=    randBetween(380,450);     //Input casuale generato per L_arms
      in[5]=    randBetween(2,2.6);       //Input casuale generato per av_speed
      in[6]=    randBetween(10500,15500); //Input casuale generato per f_call

      //--- usa la funzione isItASchnick per determinare l'output desiderato effettivo
      Actual_Output=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]);
      //--- utilizza il SVM addestrato per restituire l'output predetto.
      Predicted_Output=classify(handle,in);
      if(Actual_Output==Predicted_Output)
        {
         N_correct++; //Questa istruzione tiene conto del numero di volte in cui l'output predetto è corretto.
        }
     }
//--- restituisce l'accuratezza del SVM addestrato come percentuale
   return(100*((double)N_correct/(double)N));
  }
//+------------------------------------------------------------------+
//| Questa funzione prende gli input e output di addestramento corretti 
//| generati e inserisce N errori casuali nei dati
//+------------------------------------------------------------------+ 
void insertRandomErrors(double &inputs[],bool &outputs[],int N)
  {
   int nTrainingPoints=ArraySize(outputs); //calcola il numero di punti di addestramento
   int index;                              //crea un nuovo intero 'index'
   bool randomOutput;                      //crea un nuovo bool 'randomOutput'
   double in[];                            //crea un array di double vuoto da utilizzare
                                           //per memorizzare temporaneamente gli input generati
   ArrayResize(in,N_Inputs);               //ridimensiona l'array in[] a N_Inputs
   for(int i=0;i<N;i++)
     {
      in[0]=    randBetween(980,1120);    //Input casuale generato per l'altezza
      in[1]=    randBetween(38,52);       //Input casuale generato per il peso
      in[2]=    randBetween(7,11);        //Input casuale generato per N_legs
      in[3]=    randBetween(3,4.2);       //Input casuale generato per N_eyes
      in[4]=    randBetween(380,450);     //Input casuale generato per L_arms
      in[5]=    randBetween(2,2.6);       //Input casuale generato per av_speed
      in[6]=    randBetween(10500,15500); //Input casuale generato per f_call

      //--- scegli casualmente uno degli input di addestramento per inserire un errore
      index=(int)MathRound(randBetween(0,nTrainingPoints-1));
      //--- genera un output booleano casuale da utilizzare per creare errore
      if(randBetween(0,1)>0.5) randomOutput=true;
      else                     randomOutput=false;

      //--- copia i nuovi input casuali generati nell'array di input di addestramento
      ArrayCopy(inputs,in,index*N_Inputs,0,N_Inputs);
      //--- copia il nuovo output casuale generato nell'array di output di addestramento
      outputs[index]=randomOutput;
     }
  }
//+------------------------------------------------------------------+
//| Questa funzione viene utilizzata per creare un valore casuale tra t1 e t2
//+------------------------------------------------------------------+ 
double randBetween(double t1,double t2)
  {
   return((t2-t1)*((double)MathRand()/(double)32767)+t1);
  }
//+------------------------------------------------------------------+
Elenco
Commento 0