MetaTrader5
Schnick: Tester di Machine Learning per MetaTrader 5 - Demo Gratuita
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);
}
//+------------------------------------------------------------------+
2012.12.14