Início Negociação Sistemática Postagem

Ferramenta de Aprendizado de Máquina: Teste do SVM para MetaTrader 5

Anexo
1370.zip (2.63 KB, Baixar 0 vezes)

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.

Esta versão do código foi desenvolvida especificamente para ser utilizada em conjunto com a versão demo da Ferramenta de Aprendizado de Máquina de Vetores de Suporte, disponível gratuitamente no Mercado 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

Comentário (0)