English Русский 中文 Español Deutsch 日本語
Seleção automática de sinais promissores

Seleção automática de sinais promissores

MetaTrader 5Integração | 9 fevereiro 2018, 14:34
2 144 0
Alexander Fedosov
Alexander Fedosov

Introdução

A negociação automatizada em mercados financeiros é o objetivo final do desenvolvimento de novos robôs de negociação, pois o mercado está em constante mudança. No entanto, os EAs automatizados não podem estar preparados para todas as situações de mercado. Portanto, o caminho mais eficaz continua a ser a simbiose de um robô e o controle humano sobre o sistema automatizado. Um bom exemplo desta interação pode ser encontrado no serviço de Sinais de negociação. Nele, são oferecidos sistemas e métodos de negociação com diferentes níveis de risco e dinâmicas de negociação. Existem muitas ferramentas que ajudam a encontrar o sinal desejado. No entanto, o que está em causa é determinar o conjunto de parâmetros adequado para vosso estilo de negociação. Uma solução conveniente seria determinar - quanto ao sinal - o conjunto de parâmetros e os valores para estilos de negociação arriscados, moderados e conservadores.

Modelo para classificar sinais de negociação

Para uma classificação abrangente dos sinais, foram selecionados cinco critérios de avaliação. Cada um deles será classificado numa escala de 20 pontos, em que 0 significa um estilo de negociação arriscado e 20 - conservador. Em resumo, cada sinal de negociação será avaliado num sistema de 100 pontos. Eu escolhi as seguintes características como critérios.

1) Alavancagem da conta negociação.

Sabe-se que quanto maior a alavancagem, maior o risco de perder uma quantidade significativa de dinheiro. Com base no sistema de 20 pontos, os seguintes valores serão usados ​​para avaliar a alavancagem: 

  • Serão dados 20 pontos à alavancagem de 1:1.
  • 0 pontos serão dados à alavancagem de 1:500 e superior.

Para avaliar o sinal com base no valor de alavancagem, usaremos a seguinte equação canônica linear:

onde Xa = 1, Ya = 20, enquanto Xb = 500 e Yb = 0. Assim, obtemos a equação da reta que passa por dois pontos. No nosso caso, ela reflete a dependência entre a escala de 20 pontos (pontuação) e o valor da alavancagem atual. 

Mais uma vez ressaltamos que a dependência é válida no intervalo estabelecido - de 0 a 20. Isso significa que, mesmo que a alavancagem seja superior a 1:500 (por exemplo, 1: 1000), sua nota também será 0.

2) Crescimento da conta em porcentagem.

Para avaliar este parâmetro de acordo com o sistema de 20 pontos, devem-se ter em conta dois fatores. Em primeiro lugar, o crescimento pode ser negativo. Além disso, não seria inteiramente correto comparar seu valor absoluto. Portanto, apresentaremos as seguintes regras e premissas.

  • O crescimento negativo indica que o sinal avaliado atualmente está no grupo de risco e, por isso, a ele é atribuída uma pontuação de 0.
  • Em vez de o crescimento absoluto do sinal, avaliaremos sua dinâmica semanal.
  • O risco é um conceito subjetivo. Há quem ache que um crescimento semanal de 10% é suficiente, há quem pense que é pouco. No entanto, é necessário definir um certo intervalo. Por isso, usaremos o incremento semanal de 1% como o crescimento de referência de um sinal conservador, e tomaremos 15% como o limiar de negociação de risco, por semana.

Novamente, usamos a equação acima, isto é, Xa = 1, Ya = 20, enquanto  Xb = 15 e Yb = 0. Obtemos a seguinte dependência:

3) Rebaixamento máximo em porcentagem.

Esse valor caracteriza diretamente o risco de negociação. Usaremos as seguintes regras para determinar os valores-limite.

  • Mesmo um rebaixamento de até 20% será considerado um estilo conservador de negociação. Sua nota será de 20 pontos.
  • Um rebaixamento superior a 40% será considerado um estilo arriscado de negociação e receberá 0 pontos.
  • O intervalo de 20-40% do rebaixamento máximo será avaliado a partir da equação da reta, definida pelos dois pontos anteriores.  

Nesta equação, Xa = 20, Ya = 20, enquanto Xb = 40 e Yb = 0. Obtemos a seguinte dependência:

4) Valor do ROI ( Return on Investment) em porcentagem.

Um retorno sobre o investimento superior a 100% significa um uso rentável dos fundos; valores inferiores a 100% indicam que os investimentos são utilizados de forma ineficiente. Usamos a escala de 20 pontos para este indicador do grau de sucesso do investimento.

  • ROI inferior a 100% receberá 0 pontos.
  • ROI superior a 200% obterá 20 pontos.
  • O intervalo de 100 a 200 será avaliado a partir da equação da reta, definida pelos dois pontos anteriores.

Nesta equação Xa = 100, Ya = 0, enquanto Xb = 200 e Yb = 20. Obtemos a seguinte dependência:

5) Tempo de vida do sinal de negociação.

A vida útil de um sinal de negociação é um fator muito importante, uma vez que mostra se a negociação está sendo realizada corretamente, em princípio. Para avaliá-lo numa escala de 20 pontos, primeiro determinamos a quantidade de tempo considerada confiável e comprovada. Como unidade de medida, usaremos semanas, porque já foram usadas durante a avaliação do crescimento. Atenção: esse indicador é de caráter individual, quer dizer, cada um é livre para escolher critérios de confiabilidade próprios no que diz respeito ao tempo. Para nosso sistema, escolhemos os seguintes valores limite.

  • Sinais cuja vida é inferior a 4 semanas (número de semanas completas no mês) recebem 0 pontos.
  • Sinais cuja vida é superior a 25 semanas (número de semanas completas em seis meses) recebem 20 pontos.
  • O intervalo entre 4 e 25 semanas será avaliado de acordo com a equação da reta, definida pelos dois pontos anteriores.  


Realização de uma ferramenta de classificação

A biblioteca de interface gráfica do usuário EasyandFastGUI foi selecionada para levar a cabo a ideia. A estrutura do aplicativo é mostrada nas figuras 1a e 1b (veja abaixo). Consiste nos seguintes elementos:

  • Uma tabela de sinais disponíveis para a conta atual, no terminal.
  • Uma avaliação detalhada do sinal selecionado na tabela, por categorias.
  • O número de sinais de negociação disponíveis para a conta atual.
  • Uma avaliação final visual do sinal selecionado na tabela.


Fig.1a Estrutura do aplicativo (parte esquerda)

A avaliação final, representada como uma escala de gradiente, não tem informações dizendo que o lado esquerdo reflete os sinais desfavoráveis. Ela apenas fornece a visualização do estilo de negociação num sinal de negociação particular. Afinal, embora uma negociação arriscada traga potenciais perdas, também aumenta a possibilidade de tirar lucros.


Fig.1b Estrutura do aplicativo (lado direito)

Na realização do programa, abordaremos os principais métodos que refletem a essência do aplicativo. O primeiro método é o CreateGUI(). Ele é uma montagem de todos os outros métodos e é responsável pela exibição de todas as informações visuais.

  • O método CreateWindow() cria uma janela de aplicativo com um cabeçalho. É possível fechá-lo e reduzir o tamanho.
  • O método CreateTable() cria uma tabela com todos os sinais disponíveis para a conta atual.
  • O método CreateStatusBar() cria uma barra de status, que mostra o número total de sinais de negociação disponíveis.
  • Os métodos CreatePicture1() e CreatePicture2() criam uma escala de gradiente e um ponteiro para a escala, respectivamente.
  • Os métodos CreateTextLabel() definem a exibição de informações detalhadas sobre o sinal de negociação selecionado.
  • O método CreateButton() cria um botão para assinatura do sinal selecionado na tabela.
//+------------------------------------------------------------------+
//| Cria a interface gráfica do programa                          |
//+------------------------------------------------------------------+
bool CProgram::CreateGUI(void)
  {
//--- Criação de painel
   if(!CreateWindow("Auto Search Signal"))
      return(false);
//--- Criação de tabela
   if(!CreateTable(7,100))
      return(false);
//--- Barra de Status
   if(!CreateStatusBar(1,26))
      return(false);
//--- Imagens
   if(!CreatePicture1(618,40))
      return(false);
   if(!CreatePicture2(610,80))
      return(false);
//--- Etiqueta
   if(!CreateTextLabel1(20,20,"Avaliação da alavancagem: -"))
      return(false);
   if(!CreateTextLabel2(20,40,"Avaliação do crescimento: -"))
      return(false);
   if(!CreateTextLabel3(20,60,"Avaliação do rebaixamento: -"))
      return(false);
   if(!CreateTextLabel4(200,20,"Avaliação do ROI: -"))
      return(false);
   if(!CreateTextLabel5(200,40,"Avaliação do tempo de vida: -"))
      return(false);
//--- Botões com imagem
   if(!CreateButton(440,40,"Assinar"))
      return(false);
//--- Conclusão da criação da GUI
   CWndEvents::CompletedGUI();
   return(true);
  }
//+-----------------------------------------------------------------


O seguinte método é responsável pela experiência interativa: permite a escolha de um sinal de negociação a partir da lista na tabela e exibir as informações sobre ele. Ele também acompanha o evento de clicar o botão criado anteriormente e de assinar o sinal selecionado.

//+------------------------------------------------------------------+
//| Manipulador de eventos                                               |
//+------------------------------------------------------------------+
void CProgram::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- O evento de botão pressionado na opção da lista ou tabela
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_LIST_ITEM)
     {
      int x=610+3*int(m_table.GetValue(9,m_table.SelectedItem()));
      //---
      CreateTextLabel1(20,20,"Avaliação da alavancagem: "+IntegerToString(GetLeverageRating(int(m_table.GetValue(2,m_table.SelectedItem())))));
      CreateTextLabel2(20,40,"Avaliação do crescimento: "+IntegerToString(GetGainRating(int(m_table.GetValue(3,m_table.SelectedItem())),int(m_table.GetValue(8,m_table.SelectedItem())))));
      CreateTextLabel3(20,60,"Avaliação do rebaixamento: "+IntegerToString(GetDrawDownRating(int(m_table.GetValue(5,m_table.SelectedItem())))));
      CreateTextLabel4(200,20,"Avaliação do ROI: "+IntegerToString(GetROIRating(int(m_table.GetValue(4,m_table.SelectedItem())))));
      CreateTextLabel5(200,40,"Avaliação do tempo de vida: "+IntegerToString(GetWeeksRating(int(m_table.GetValue(8,m_table.SelectedItem())))));
      CreatePicture2(x,80);
      //---
      m_button.IsLocked(false);
      Update(true);
     }
//---
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_BUTTON)
     {
      //--- Se pressionarmos o botão
      if(lparam==m_button.Id())
        {
         SignalSubscribe(long(m_table.GetValue(6,m_table.SelectedItem())));
        }
     }
  }

A seguir, consideraremos os métodos que realizam a avaliação dos sinais de negociação. Primeiro, é preciso obter a lista de sinais de negociação disponíveis para a conta atual, bem como as informações a serem adicionadas à tabela.

O método GetTradingSignals() recebe todas as informações sobre os sinais disponíveis e os armazena nas matrizes de dados:

//+------------------------------------------------------------------+
//| Obtenção de informações sobre sinais de negociação disponíveis              |
//+------------------------------------------------------------------+
bool CProgram::GetTradingSignals(void)
  {
// --- pedimos o número total de sinais na base de dados 
   m_signals_total=SignalBaseTotal();
//---
   ArrayResize(m_name,m_signals_total);
   ArrayResize(m_curr,m_signals_total);
   ArrayResize(m_leverage,m_signals_total);
   ArrayResize(m_gain,m_signals_total);
   ArrayResize(m_roi,m_signals_total);
   ArrayResize(m_max_drawdown,m_signals_total);
   ArrayResize(m_pips,m_signals_total);
   ArrayResize(m_subscr,m_signals_total);
   ArrayResize(m_weeks,m_signals_total);
   ArrayResize(m_rating,m_signals_total);
// --- ciclo de acordo com todos os sinais 
   for(int i=0;i<m_signals_total;i++)
     {
      //--- selecionamos o sinal para trabalho futuro 
      if(SignalBaseSelect(i))
        {
         //--- obtenção das propriedades do sinal 
         m_name[i]=SignalBaseGetString(SIGNAL_BASE_NAME);                                                // nome do sinal
         m_curr[i]=SignalBaseGetString(SIGNAL_BASE_CURRENCY);                                            // moeda do sinal
         m_leverage[i]=SignalBaseGetInteger(SIGNAL_BASE_LEVERAGE);                                       // alavancagem
         m_gain[i]=SignalBaseGetDouble(SIGNAL_BASE_GAIN);                                                // crescimento da conta em %
         m_roi[i]=SignalBaseGetDouble(SIGNAL_BASE_ROI);                                                  // ROI
         m_max_drawdown[i]=SignalBaseGetDouble(SIGNAL_BASE_MAX_DRAWDOWN);                                // Rebaixamento máximo
         m_id[i]=SignalBaseGetInteger(SIGNAL_BASE_ID);                                                   // ID do sinal
         m_subscr[i]=SignalBaseGetInteger(SIGNAL_BASE_SUBSCRIBERS);                                      // número de assinantes
         m_weeks[i]=int((TimeCurrent()-SignalBaseGetInteger(SIGNAL_BASE_DATE_PUBLISHED))/3600/24/7);     //tempo de vida do sinal
         //--- obtenção de avaliação coletiva
         m_rating[i]=GetLeverageRating(m_leverage[i])+GetGainRating(m_gain[i],m_weeks[i])+GetDrawDownRating(m_max_drawdown[i])+GetROIRating(m_roi[i])+GetWeeksRating(m_weeks[i]);
        }
      else
        {
         PrintFormat("Erro ao selecionar o sinal. Código de erro=%d",GetLastError());
         return(false);
        }
     }
   return (true);
  }
//+------------------------------------------------------------------+

Como se pode ver na listagem acima, à matriz m_rating [] são adicionados os dados da avaliação final de cada sinal de negociação. Por isso, consideremos os métodos utilizados neste cálculo. Eles são a implementação informática programa do modelo falado na primeira parte do artigo.

//+------------------------------------------------------------------+
//| Avaliação da alavancagem de negociação                                           |
//+------------------------------------------------------------------+
int CProgram::GetLeverageRating(long leverage)
  {
   int lev_rating=int(-20.0/499.0*double(leverage)+10000.0/499.0);
   lev_rating=(lev_rating>20)?20:lev_rating;
   return lev_rating;
  }
//+------------------------------------------------------------------+
//| Avaliação do crescimento                                                  |
//+------------------------------------------------------------------+
int CProgram::GetGainRating(double gain,int weeks)
  {
   weeks=(weeks==0)?1:weeks;
   int gain_rating=int(-10*(gain/double(weeks)/7.0)+150.0/7.0);
   gain_rating=(gain_rating>20)?20:gain_rating;
   gain_rating=(gain_rating<0)?0:gain_rating;
   gain_rating=(gain<0)?0:gain_rating;
   return gain_rating;
  }
//+------------------------------------------------------------------+
//| Avaliação do rebaixamento máximo                                     |
//+------------------------------------------------------------------+
int CProgram::GetDrawDownRating(double max_drawdown)
  {
   int drawdn_rating=int(-max_drawdown+40);
   drawdn_rating=(drawdn_rating>20)?20:drawdn_rating;
   drawdn_rating=(drawdn_rating<0)?0:drawdn_rating;
   return drawdn_rating;
  }
//+------------------------------------------------------------------+
//| Avaliação do ROI                                                       |
//+------------------------------------------------------------------+
int CProgram::GetROIRating(double roi)
  {
   int roi_rating=int(0.2*roi-20);
   roi_rating=(roi_rating>20)?20:roi_rating;
   roi_rating=(roi_rating<0)?0:roi_rating;
   return roi_rating;
  }
//+------------------------------------------------------------------+
//| Avaliação do crescimento do sinal de negociação                                |
//+------------------------------------------------------------------+
int CProgram::GetWeeksRating(int weeks)
  {
   int age_rating=int(20.0*double(weeks)/21.0-80.0/21.0);
   age_rating=(age_rating>20)?20:age_rating;
   age_rating=(age_rating<0)?0:age_rating;
   return age_rating;
  }

Em seguida, todos os dados obtidos são adicionados à tabela usando o método InitializingTable() e são exibidos visualmente usando o método CreateTable().

//+------------------------------------------------------------------+
//| Inicialização de tabela                                            |
//+------------------------------------------------------------------+
void CProgram::InitializingTable(void)
  {
//---
   string columns[10]=
     {
      "Nome do sinal",
      "Moeda da conta",
      "Alavancagem da conta de negociação",
      "Crescimento da conta, %",
      "ROI",
      "Max. rebaixamento",
      "ID do sinal",
      "Número de assinantes",
      "Tempo de vida, sem.",
      "Avaliação"
     };
//---
   for(int c=0; c<COLUMNS1_TOTAL; c++)
     {
      //--- Definimos o título do cabeçalho
      m_table.SetHeaderText(c,columns[c]);
      //---
      for(int r=0; r<m_signals_total; r++)
        {
         if(c==0)
            m_table.SetValue(c,r,m_name[r]);
         else if(c==1)
            m_table.SetValue(c,r,m_curr[r]);
         else if(c==2)
            m_table.SetValue(c,r,IntegerToString(m_leverage[r]));
         else if(c==3)
            m_table.SetValue(c,r,DoubleToString(m_gain[r],2));
         else if(c==4)
            m_table.SetValue(c,r,DoubleToString(m_roi[r],2));
         else if(c==5)
            m_table.SetValue(c,r,DoubleToString(m_max_drawdown[r],2));
         else if(c==6)
            m_table.SetValue(c,r,IntegerToString(m_id[r]));
         else if(c==7)
            m_table.SetValue(c,r,IntegerToString(m_subscr[r]));
         else if(c==8)
            m_table.SetValue(c,r,IntegerToString(m_weeks[r]));
         else if(c==9)
            m_table.SetValue(c,r,IntegerToString(m_rating[r]));
        }
     }
  }
//+------------------------------------------------------------------+
//| Criamos uma tabela desenhada                                      |
//+------------------------------------------------------------------+
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_up.bmp"
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_down.bmp"
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\circle_gray.bmp"
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\calendar.bmp"
//---
bool CProgram::CreateTable(const int x_gap,const int y_gap)
  {
#define COLUMNS1_TOTAL 10
//--- Criamos o ponteiro para o elemento principal
   m_table.MainPointer(m_window);
//--- Matriz de largura de colunas
   int width[COLUMNS1_TOTAL];
   ::ArrayInitialize(width,110);
   width[1]=80;
   width[2]=100;
   width[4]=90;
   width[8]=85;
   width[9]=90;
//--- Matriz de recuo do texto, nas colunas, ao longo do eixo X
   int text_x_offset[COLUMNS1_TOTAL];
   ::ArrayInitialize(text_x_offset,7);
//--- Matriz de alinhamento do texto, nas colunas
   ENUM_ALIGN_MODE align[COLUMNS1_TOTAL];
   ::ArrayInitialize(align,ALIGN_CENTER);
//---
   GetTradingSignals();
//--- Propriedades
   m_table.XSize(1000);
   m_table.YSize(470);
   m_table.CellYSize(20);
   m_table.TableSize(COLUMNS1_TOTAL,m_signals_total);
   m_table.TextAlign(align);
   m_table.ColumnsWidth(width);
   m_table.TextXOffset(text_x_offset);
   m_table.LabelXGap(5);
   m_table.LabelYGap(4);
   m_table.IconXGap(7);
   m_table.IconYGap(4);
   m_table.MinColumnWidth(0);
   m_table.ShowHeaders(true);
   m_table.IsSortMode(true);
   m_table.LightsHover(true);
   m_table.SelectableRow(true);
   m_table.IsWithoutDeselect(true);
   m_table.ColumnResizeMode(true);
   m_table.IsZebraFormatRows(clrWhiteSmoke);
   m_table.AutoXResizeMode(true);
   m_table.AutoXResizeRightOffset(7);
   m_table.AutoYResizeBottomOffset(28);
   m_table.HeadersColor(clrSkyBlue);
   m_table.DataType(2,TYPE_INT);
   m_table.DataType(3,TYPE_FLOAT);
   m_table.DataType(4,TYPE_FLOAT);
   m_table.DataType(5,TYPE_FLOAT);
   m_table.DataType(6,TYPE_INT);
   m_table.DataType(7,TYPE_INT);
   m_table.DataType(8,TYPE_INT);
   m_table.DataType(9,TYPE_INT);

//--- Preenchemos a tabela com dados
   InitializingTable();
//--- Criamos um elemento de controle
   if(!m_table.CreateTable(x_gap,y_gap))
      return(false);
//--- Adicionamos um objeto à matriz geral de grupos de objetos
   CWndContainer::AddToElementsArray(0,m_table);
   m_table.SortData(9);
   m_table.SortData(9);
   return(true);
  }

Para um uso mais conveniente dos dados da tabela de sinais de negociação, devem-se atribuir os tipos de dados para as células exibidas. Isso permitirá uma correta classificação de dados nas colunas da tabela. Para uma melhor exibição visual, a tabela será inicialmente ordenada pela última coluna. A classificação é realizada duas vezes: a primeira classificação é descendente, enquanto a segunda e subsequentes classificações serão realizadas na ordem oposta à anterior.

O último elemento a mencionar é a exibição visual da avaliação final na forma de uma escala de gradiente e um ponteiro para ela. Isso é feito por dois métodos cujas listas são fornecidas abaixo. As mudanças na posição do ponteiro na escala já foram observadas no método OnEvent() acima.

//+------------------------------------------------------------------+
//| Cria uma escala de gradiente                                        |
//+------------------------------------------------------------------+
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp64\\000.bmp"
#resource "\\Images\\EasyAndFastGUI\\Controls\\ArrowUp_blue.bmp"
//---
bool CProgram::CreatePicture1(const int x_gap,const int y_gap)
  {
//--- Criamos o ponteiro para o elemento principal
   m_picture1.MainPointer(m_window);
//--- Propriedades
   m_picture1.XSize(300);
   m_picture1.YSize(40);
   m_picture1.IconFile("Images\\EasyAndFastGUI\\Icons\\bmp64\\000.bmp");
//--- Criação de botão
   if(!m_picture1.CreatePicture(x_gap,y_gap))
      return(false);
//--- Adicionamos o ponteiro para o elemento na base
   CWndContainer::AddToElementsArray(0,m_picture1);
   return(true);
  }
//+------------------------------------------------------------------+
//| Cria um ponteiro para escala                                      |
//+------------------------------------------------------------------+
bool CProgram::CreatePicture2(const int x_gap,const int y_gap)
  {
//--- Criamos o ponteiro para o elemento principal
   m_picture2.MainPointer(m_window);
//--- Propriedades
   m_picture2.XSize(16);
   m_picture2.YSize(16);
   m_picture2.IconFile("Images\\EasyAndFastGUI\\Controls\\ArrowUp_blue.bmp");
//--- Criação de botão
   if(!m_picture2.CreatePicture(x_gap,y_gap))
      return(false);
//--- Adicionamos o ponteiro para o elemento na base
   CWndContainer::AddToElementsArray(0,m_picture2);
   return(true);
  }


Seleção de sinais potencialmente promissores

Ao selecionar um sinal e determinar suas perspectivas, esperamos um bom sinal para trazer certos resultados no futuro. A prática mostra que os sinais que apresentam altas taxas de crescimento, no menor tempo possível, duram pouco. É porque esses sinais geralmente usam estilos de negociação de alto risco para ganhar maiores lucros. No entanto, não devemos excluir da lista de sinais promissores aqueles cujo estilo de negociação é de alto risco. Alguns traders planejam permanecer no mercado por um longo tempo e ganhar dinheiro devagar. Outros visam lucros rápidos e estão prontos para assumir certos riscos. 

Portanto, dividimos visualmente o sistema de avaliação acima em três categorias (figura 2).

  • Primeira categoria. Zona vermelha. Os sinais desta zona podem ter alta rentabilidade, mas envolvem riscos elevados.
  • Segunda categoria. Zona Amarela. Estes sinais mostram boa rentabilidade com um risco moderado.
  • Terceira categoria. Zona verde. Estes sinais são considerados potencialmente promissores, porque eles mostram maior confiabilidade, embora a rentabilidade possa não ser alta.


Fig.2. Categorias da escala de gradiente para a avaliação dos sinais

Para programar esta categorização, adicionamos ao método InitializingTable() as seguintes linhas:

//+------------------------------------------------------------------+
//| Inicialização de tabela                                            |
//+------------------------------------------------------------------+
void CProgram::InitializingTable(void)
  {
//---
   string columns[10]=
     {
      "Nome do sinal",
      "Moeda da conta",
      "Alavancagem da conta de negociação",
      "Crescimento da conta, %",
      "ROI",
      "Max. rebaixamento",
      "ID do sinal",
      "Número de assinantes",
      "Tempo de vida, sem.",
      "Avaliação"
     };
//---
   for(int c=0; c<COLUMNS1_TOTAL; c++)
     {
      //--- Definimos o título do cabeçalho
      m_table.SetHeaderText(c,columns[c]);

      //---
      for(int r=0; r<m_signals_total; r++)
        {
         if(c==0)
           {
            m_table.SetValue(c,r,m_name[r]);
            if(m_rating[r]<=30)
               m_table.TextColor(c,r,clrCrimson);
            else if(m_rating[r]>30 && m_rating[r]<=66)
               m_table.TextColor(c,r,clrOrange);
            else if(m_rating[r]>66)
               m_table.TextColor(c,r,clrForestGreen);
           }
         else if(c==1)
            m_table.SetValue(c,r,m_curr[r]);
         else if(c==2)
            m_table.SetValue(c,r,IntegerToString(m_leverage[r]));
         else if(c==3)
            m_table.SetValue(c,r,DoubleToString(m_gain[r],2));
         else if(c==4)
            m_table.SetValue(c,r,DoubleToString(m_roi[r],2));
         else if(c==5)
            m_table.SetValue(c,r,DoubleToString(m_max_drawdown[r],2));
         else if(c==6)
            m_table.SetValue(c,r,IntegerToString(m_id[r]));
         else if(c==7)
            m_table.SetValue(c,r,IntegerToString(m_subscr[r]));
         else if(c==8)
            m_table.SetValue(c,r,IntegerToString(m_weeks[r]));
         else if(c==9)
            m_table.SetValue(c,r,IntegerToString(m_rating[r]));
        }
     }
  }

Com base nos resultados obtidos, alteramos a cor do nome do sinal de negociação (a primeira coluna) usando o método TextColor(). Assim, é possível ver a categoria a que o sinal pertence, sem analisá-lo ou verificar a última coluna da tabela contendo o pontuação da avaliação.


Fig.3. Indicação colorida de sinais de negociação

Os sinais podem ser agrupados em categorias ordenando a tabela pela última coluna. Esta classificação está habilitada por padrão. A última ação óbvia é realizar o recurso para assinar o sinal. Isso pode ser feito através do método CreateButton() :

//+------------------------------------------------------------------+
//| Cria um botão com imagem                                       |
//+------------------------------------------------------------------+
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\start.bmp"
//---
bool CProgram::CreateButton(const int x_gap,const int y_gap,const string text)
  {
//--- Criamos o ponteiro para o elemento principal
   m_button.MainPointer(m_window);
//--- Propriedades
   m_button.XSize(120);
   m_button.YSize(22);
   m_button.IconXGap(3);
   m_button.IconYGap(3);
   m_button.FontSize(10);
   m_button.IsCenterText(true);
   m_button.IconFile("Images\\EasyAndFastGUI\\Icons\\bmp16\\start.bmp");
   m_button.IsLocked(true);
//--- Criamos um elemento de controle
   if(!m_button.CreateButton(text,x_gap,y_gap))
      return(false);
//--- Adicionamos o ponteiro para o elemento na base
   CWndContainer::AddToElementsArray(0,m_button);
   return(true);
  }
//+------------------------------------------------------------------+

Para evitar possíveis erros na funcionalidade desenvolvida acima, vejamos:

1. Para poder trabalhar com sinais de negociação no terminal, você deve estar logado usando sua conta mql5, no MetaTrader 5:

Fig.4 Autorização no terminal

2. Ao executar o aplicativo, é preciso ativar a opção Permitir alterar as configurações de sinal. Caso contrário, a assinatura do sinal comercial usando este aplicativo retornará o erro 4014 ("Função do sistema não é permitida para chamada").

Fig.5 Ajustes necessários durante a inicialização do aplicativo

3. E a última coisa que pode afetar a operação correta do aplicativo é o arquivo signals.dat. Se os dados na tabela forem exibidos incorretamente ou não forem exibidos, você deve encontrar este arquivo em C:\Users\Nome do computador\AppData\Roaming\MetaQuotes\Terminal\..\bases\signals e excluí-lo. Em seguida, reinicie o terminal e abra a guia Sinais, como mostrado na figura 6. Um novo arquivo será gerado automaticamente, depois disso você pode iniciar e usar o aplicativo.

Fig.6 Aba Sinais no terminal MetaTrader 5

No terminal, ao contrária da seção Sinais no site, em vez de exibir todos os sinais, são exibidos somente os sinais que são adequados para trabalhar com a atual conta de negociação selecionada. 


Fim do artigo

Neste artigo, desenvolvemos um sistema simples de avaliação para certas caraterísticas dos sinais de negociação. É reduzida a uma pontuação total de 100 pelo estilo de negociação. Com base nesta avaliação, todos os sinais disponíveis foram divididos em três categorias, que diferem em termos de perspectivas, riscos de negociação, tempo de vida e crescimento percentual da conta de negociação.

No final do artigo, anexado um arquivo com todos os ficheiros listados classificados em pastas. Para o bom funcionamento, você só precisa salvar a pasta MQL5 no diretório raiz do terminal. O aplicativo usa a biblioteca de interface gráfica do usuário EasyAndFastGUI retirada do artigo. A biblioteca foi ligeiramente modificada e também está anexada a este artigo.

Programas utilizados no artigo:

#
 Nome
Tipo
Descrição
1
AutoSearch.mq5 Expert Advisor
 Aplicativo para seleção automática de sinais promissores
2
Program.mqh Biblioteca  Classe para criação de aplicativos
3
MainWindow.mqh Biblioteca  Conjunto de métodos utilizados para criar o aplicativo


Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/3398

Arquivos anexados |
MQL5.zip (1631.66 KB)
Criando uma nova estratégia de negociação usando uma tecnologia de resolução de entradas em indicadores Criando uma nova estratégia de negociação usando uma tecnologia de resolução de entradas em indicadores
O artigo sugere uma tecnologia que ajuda todos a criar estratégias de negociação personalizadas, montando um conjunto de indicadores individuais, além de desenvolver sinais personalizados de entrada no mercado.
Avaliação do risco numa sequência de trades com um ativo. Continuação Avaliação do risco numa sequência de trades com um ativo. Continuação
O artigo desenvolve as idéias propostas, na seção anterior, e continua a examiná-las. Além disso, discute questões sobre a alocação da rentabilidade, a construção e o estudo de padrões estatísticos.
Como reduzir os riscos trader Como reduzir os riscos trader
A negociação nos mercados financeiros está associada a um conjunto de riscos que deve ser considerado nos algoritmos dos sistemas de negociação. A redução desses riscos é uma tarefa importante, quando se quer tirar lucro da negociação.
Estratégia de negociação "Momentum Pinball" Estratégia de negociação "Momentum Pinball"
Neste artigo, continuamos a falar sobre a programação das estratégias de negociação descritas no livro de L. Raschke e L. Connors "Street Smarts: High Probability Short-Term Trading Strategies, devoted to testing of range limits by price". Desta vez, estudamos o sistema "Momentum Pinball": é descrita a criação de dois indicadores, um robô de negociação e um bloco de sinal com base nele.