Este script faz parte do artigo "Aprendizado de Máquina: Como Máquinas de Vetores de Suporte podem ser usadas em Trading", publicado no site da MQL5.
Imagine um cenário hipotético: você é um pesquisador investigando um animal raro encontrado apenas nas profundezas do Ártico, chamado Schnick. Devido à remoteness, apenas um pequeno número deles foi encontrado (digamos cerca de 5000). Como pesquisador, você se pergunta... como posso identificar um Schnick?
Você tem à sua disposição apenas os artigos de pesquisa publicados por alguns poucos pesquisadores que já viram um. Nesses artigos, os autores descrevem certas características sobre os Schnicks que encontraram, como altura, peso e número de patas, mas todas essas características variam entre os artigos, sem um padrão claro...
Como podemos usar esses dados para identificar um novo animal como um schnick?
Uma possível solução para nosso problema é utilizar uma máquina de vetores de suporte para identificar os padrões nos dados e criar uma estrutura que possa ser usada para classificar os animais como schnick ou não. O primeiro passo é criar um conjunto de dados que pode ser usado para treinar sua máquina de vetores de suporte. Os dados de treinamento são um conjunto de entradas e saídas correspondentes que a máquina irá analisar e extrair um padrão.
Este script tenta demonstrar o poder do uso de máquinas de vetores de suporte para resolver problemas de classificação utilizando a Ferramenta de Aprendizado de Máquina de Vetores de Suporte disponível no Mercado MQL5. Uma descrição completa desse problema hipotético e do script pode ser encontrada no artigo "Aprendizado de Máquina: Como Máquinas de Vetores de Suporte podem ser usadas em Trading". O artigo inclui um passo a passo de como usar o script e como esse problema pode dar insights sobre o uso de aprendizado de máquina para avaliar tendências de mercado.
Código:
//+------------------------------------------------------------------+ //| 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" //+------------------------------------------------------------------+ //| Este script demonstra as capacidades da Ferramenta de Máquina //| de Vetores de Suporte //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| A seguinte declaração importa todas as funções incluídas na //| Ferramenta de Máquina de Vetores de Suporte '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 //--- O número de entradas que estaremos usando para a svm int N_Inputs=7; //+------------------------------------------------------------------+ //| Função de inicialização do Expert | //+------------------------------------------------------------------+ int OnInit() { double inputs[]; //array de double vazio a ser usado para criar entradas de treinamento bool outputs[]; //array bool vazio a ser usado para criar entradas de treinamento int N_TrainingPoints=5000; //define o número de amostras de treinamento a serem geradas int N_TestPoints=5000 //define o número de amostras a serem usadas para teste genTrainingData(inputs,outputs,N_TrainingPoints); //Gera as entradas e saídas a serem usadas para treinar a svm int handle1=initSVMachine(); //inicializa uma nova máquina de vetores de suporte e retorna um handle setInputs(handle1,inputs,7); //passa as entradas (sem erros) para a máquina de vetores de suporte setOutputs(handle1,outputs); //passa as saídas (sem erros) para a máquina de vetores de suporte setParameter(handle1,OP_TOLERANCE,0.01); //define o parâmetro de tolerância de erro para <5% training(handle1); //treina a máquina de vetores de suporte usando as entradas/saídas passadas insertRandomErrors(inputs,outputs,500); //pega as entradas/saídas originais geradas e adiciona erros aleatórios aos dados int handle2=initSVMachine(); //inicializa uma nova máquina de vetores de suporte e retorna um handle setInputs(handle2,inputs,7); //passa as entradas (com erros) para a máquina de vetores de suporte setOutputs(handle2,outputs); //passa as saídas (com erros) para a máquina de vetores de suporte setParameter(handle2,OP_TOLERANCE,0.01); //define o parâmetro de tolerância de erro para <5% training(handle2); //treina a máquina de vetores de suporte usando as entradas/saídas passadas double t1=testSVM(handle1,N_TestPoints); //testa a precisão da máquina de vetores de suporte treinada e salva em t1 double t2=testSVM(handle2,N_TestPoints); //testa a precisão da máquina de vetores de suporte treinada e salva em t2 Print("A precisão da SVM é ",NormalizeDouble(t1,2),"% (usando entradas/saídas de treinamento sem erros)"); Print("A precisão da SVM é ",NormalizeDouble(t2,2),"% (usando entradas/saídas de treinamento com erros)"); deinitSVMachine(); //Limpa toda a memória usada na geração da SVM para evitar vazamento de memória return(0); } //+------------------------------------------------------------------+ //| Função de desinicialização do Expert | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- Nenhuma função executada em OnDeinit() } //+------------------------------------------------------------------+ //| Função de tick do Expert | //+------------------------------------------------------------------+ void OnTick() { //--- Nenhuma função executada em OnTick() } //+------------------------------------------------------------------+ //| Esta função pega as propriedades de observação do animal observado e, //| com base nos critérios que escolhemos, retorna true/false se é um 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 a altura estiver fora dos parâmetros > retorna(false) if(weight < 40 || weight > 50) return(false); //Se o peso estiver fora dos parâmetros > retorna(false) if(N_legs < 8 || N_legs > 10) return(false); //Se o N_Legs estiver fora dos parâmetros > retorna(false) if(N_eyes < 3 || N_eyes > 4) return(false); //Se o N_eyes estiver fora dos parâmetros > retorna(false) if(L_arm < 400 || L_arm > 450) return(false); //Se o L_arm estiver fora dos parâmetros > retorna(false) if(av_speed < 2 || av_speed > 2.5) return(false); //Se a av_speed estiver fora dos parâmetros > retorna(false) if(f_call < 11000 || f_call > 15000) return(false); //Se o f_call estiver fora dos parâmetros > retorna(false) return(true); //Caso contrário > retorna(true) } //+------------------------------------------------------------------+ //| Esta função pega um array de double vazio e um array booleano vazio //| e gera as entradas/saídas a serem usadas para treinar a SVM //+------------------------------------------------------------------+ void genTrainingData(double &inputs[],bool &outputs[],int N) { double in[]; //cria um array de double vazio a ser usado //para armazenar temporariamente as entradas geradas ArrayResize(in,N_Inputs); //redimensiona o array in[] para N_Inputs ArrayResize(inputs,N*N_Inputs); //redimensiona o array inputs[] para ter um tamanho de N*N_Inputs ArrayResize(outputs,N); //redimensiona o array outputs[] para ter um tamanho de N for(int i=0;i<N;i++) { in[0]= randBetween(980,1120); //Entrada aleatória gerada para altura in[1]= randBetween(38,52); //Entrada aleatória gerada para peso in[2]= randBetween(7,11); //Entrada aleatória gerada para N_legs in[3]= randBetween(3,4.2); //Entrada aleatória gerada para N_eyes in[4]= randBetween(380,450); //Entrada aleatória gerada para L_arms in[5]= randBetween(2,2.6); //Entrada aleatória gerada para av_speed in[6]= randBetween(10500,15500); //Entrada aleatória gerada para f_call //--- copia as novas entradas aleatórias geradas no array de entrada de treinamento ArrayCopy(inputs,in,i*N_Inputs,0,N_Inputs); //--- avalia as entradas aleatórias e determina se é um schnick outputs[i]=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]); } } //+------------------------------------------------------------------+ //| Esta função pega o handle para a SVM treinada e testa quão //| bem-sucedida ela é ao classificar novas entradas aleatórias //+------------------------------------------------------------------+ 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); //Entrada aleatória gerada para altura in[1]= randBetween(38,52); //Entrada aleatória gerada para peso in[2]= randBetween(7,11); //Entrada aleatória gerada para N_legs in[3]= randBetween(3,4.2); //Entrada aleatória gerada para N_eyes in[4]= randBetween(380,450); //Entrada aleatória gerada para L_arms in[5]= randBetween(2,2.6); //Entrada aleatória gerada para av_speed in[6]= randBetween(10500,15500); //Entrada aleatória gerada para f_call //--- usa a função isItASchnick para determinar a saída desejada real Actual_Output=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]); //--- usa a SVM treinada para retornar a saída prevista. Predicted_Output=classify(handle,in); if(Actual_Output==Predicted_Output) { N_correct++; //Essa instrução conta o número de vezes que a saída prevista está correta. } } //--- retorna a precisão da SVM treinada como uma porcentagem return(100*((double)N_correct/(double)N)); } //+------------------------------------------------------------------+ //| Esta função pega as entradas e saídas de treinamento corretas //| geradas e insere N erros aleatórios nos dados //+------------------------------------------------------------------+ void insertRandomErrors(double &inputs[],bool &outputs[],int N) { int nTrainingPoints=ArraySize(outputs); //calcula o número de pontos de treinamento int index; //cria um novo inteiro 'index' bool randomOutput; //cria um novo bool 'randomOutput' double in[]; //cria um array de double vazio a ser usado //para armazenar temporariamente as entradas geradas ArrayResize(in,N_Inputs); //redimensiona o array in[] para N_Inputs for(int i=0;i<N;i++) { in[0]= randBetween(980,1120); //Entrada aleatória gerada para altura in[1]= randBetween(38,52); //Entrada aleatória gerada para peso in[2]= randBetween(7,11); //Entrada aleatória gerada para N_legs in[3]= randBetween(3,4.2); //Entrada aleatória gerada para N_eyes in[4]= randBetween(380,450); //Entrada aleatória gerada para L_arms in[5]= randBetween(2,2.6); //Entrada aleatória gerada para av_speed in[6]= randBetween(10500,15500); //Entrada aleatória gerada para f_call //--- escolhe aleatoriamente uma das entradas de treinamento para inserir um erro index=(int)MathRound(randBetween(0,nTrainingPoints-1)); //--- gera uma saída booleana aleatória a ser usada para criar erro if(randBetween(0,1)>0.5) randomOutput=true; else randomOutput=false; //--- copia as novas entradas aleatórias geradas no array de entrada de treinamento ArrayCopy(inputs,in,index*N_Inputs,0,N_Inputs); //--- copia a nova saída booleana gerada no array de saída de treinamento outputs[index]=randomOutput; } } //+------------------------------------------------------------------+ //| Esta função é usada para criar um valor aleatório entre t1 e t2 //+------------------------------------------------------------------+ double randBetween(double t1,double t2) { return((t2-t1)*((double)MathRand()/(double)32767)+t1); } //+------------------------------------------------------------------+
Publicações relacionadas
- MACD Sample: Um Guia Prático para o Expert Advisor no MetaTrader 5
- Trader Automático: RSI e MFI com Otimização Automática para MetaTrader 4
- VR-SETKA-3: Um EA Revolutionário para MetaTrader 5
- Como Proteger Seu Indicador/EA no MetaTrader 4 com Senha
- Fechamento Automático com Kijun Sen: Um EA para MetaTrader 4