Download MetaTrader 5

Criando uma nova estratégia de negociação usando uma tecnologia de resolução de entradas em indicadores

12 fevereiro 2018, 09:45
Dmitriy Gizlyk
0
1 305

Introdução

Sabe-se bem que apenas 5% dos traders obtêm lucros estáveis ​​nos mercados financeiros, enquanto que todos os 100% desejam alcançar isso. 

Para ter uma negociação bem sucedida, você precisa de uma estratégia de negociação rentável. Os sites relacionados ao assunto e a literatura sobre negociações descrevem centenas de estratégias de negociação. Uma interpretação detalhada dos sinais é anexada a todos os indicadores, mas as estatísticas permanecem inalteradas: os 5% não foram nem em 100 ou pelo menos em 10. Os ideólogos de mercado culpam a instabilidade do mercado, o que implica que as estratégias lucrativas anteriores perdem a eficácia.

No meu artigo anterior eu já disse sobre a resolução de entradas em indicadores e mostrei um exemplo de como melhorar a estratégia existente. Agora eu proponho criar uma estratégia personalizada "do zero" usando a tecnologia especificada. Isso nos permitirá examinar os indicadores que você conhece com "novos olhos", coletar modelos de indicadores personalizados, bem como reconsiderar os seus sinais. A aplicação da tecnologia sugerida implica uma abordagem criativa da interpretação dos sinais dos indicadores, o que permite que cada usuário crie sua própria e única estratégia.

1. Criação de um modelo para testes e análises

A primeira coisa que vemos em um terminal de negociação é o movimento contínuo do preços. Potencialmente, tendo aberto uma negociação a qualquer momento, nós podemos obter lucro. Mas, como você pode determinar onde e com que intensidade o preço irá seguir para o próximo momento? Os traders tentam encontrar uma resposta a esta questão na análise técnica e fundamentalista. Para a realização de análises técnicas, vários indicadores são constantemente inventados e aprimorados. A novidade aqui é a interpretação dos sinais desses indicadores; pode ser diferente do comum.

Assim, a tecnologia para a resolução das entradas em indicadores implica a comparação de posições abertas com os valores dos indicadores. Mais uma vez, potencialmente, nós podemos obter lucro a qualquer momento. Com base nesses dados de entrada, no início de cada vela, abra duas posições bidirecionais com os parâmetros definidos. Então, analise como o fator de lucro de cada operação depende dos valores dos indicadores.

Para resolver este problema, realize um trabalho de preparação menor.

1.1. Criação de uma classe de ordem virtual

Eu uso uma conta netting. Portanto, para abrir ordens bidirecionais, eu criarei as ordens virtuais que não serão monitoradas pelo terminal (de acordo com as configurações da conta), mas pelo Expert Advisor. Para este fim, crie a classe CDeal. Ao inicializar uma instância da classe, nós passaremos para ele: nome do símbolo, tipo de posição, horário de abertura e preço, bem como o stoploss e takeprofit. O volume da posição é omitido intencionalmente porque aqui não nos interessa. O importante para nós é o movimento dos preços, portanto o lucro/perda será calculado em pontos em vez de termos monetários.

Para a manutenção, a classe foi adicionada com as funções da verificação do estado da posição:

  • IsClosed — retorna um valor lógico, se a posição está fechada ou não;
  • Type - retorna o tipo de posição
  • GetProfit — retorna o lucro de uma posição fechada (para uma posição perdedora, o valor será negativo);
  • GetTime — retorna a hora de abertura da posição.

class CDeal          :  public CObject
  {
private:
   string               s_Symbol;
   datetime             dt_OpenTime;         // Horário da abertura da posição
   double               d_OpenPrice;         // Preço de abertura da posição
   double               d_SL_Price;          // Stop Loss da posição
   double               d_TP_Price;          // Take Profit da posição
   ENUM_POSITION_TYPE   e_Direct;            // Direção da posição aberta
   double               d_ClosePrice;        // Preço do fechamento da posição
   int                  i_Profit;            // Lucro da posição em pips
//---
   double               d_Point;
   
public:
                     CDeal(string symbol, ENUM_POSITION_TYPE type,datetime time,double open_price,double sl_price, double tp_price);
                    ~CDeal();
   //--- Verifica o estado
   bool              IsClosed(void);
   ENUM_POSITION_TYPE Type(void)    {  return e_Direct;    }
   double            GetProfit(void);
   datetime          GetTime(void)  {  return dt_OpenTime;  }
   //---
   void              Tick(void);
  };

Os ticks recebidos serão processados ​​na função Tick, que verificará e, se necessário, encerrará uma posição por stoploss ou takeprofit e poupando o lucro acumulado.

void CDeal::Tick(void)
  {
   if(d_ClosePrice>0)
      return;
   double price=0;
   switch(e_Direct)
     {
      case POSITION_TYPE_BUY:
        price=SymbolInfoDouble(s_Symbol,SYMBOL_BID);
        if(d_SL_Price>0 && d_SL_Price>=price)
          {
           d_ClosePrice=price;
           i_Profit=(int)((d_ClosePrice-d_OpenPrice)/d_Point);
          }
        else
          {
           if(d_TP_Price>0 && d_TP_Price<=price)
             {
              d_ClosePrice=price;
              i_Profit=(int)((d_ClosePrice-d_OpenPrice)/d_Point);
             }
          }
        break;
      case POSITION_TYPE_SELL:
        price=SymbolInfoDouble(s_Symbol,SYMBOL_ASK);
        if(d_SL_Price>0 && d_SL_Price<=price)
          {
           d_ClosePrice=price;
           i_Profit=(int)((d_OpenPrice-d_ClosePrice)/d_Point);
          }
        else
          {
           if(d_TP_Price>0 && d_TP_Price>=price)
             {
              d_ClosePrice=price;
              i_Profit=(int)((d_OpenPrice-d_ClosePrice)/d_Point);
             }
          }
        break;
     }
  }

1.2. Criação de uma classe para trabalhar com os indicadores

Para salvar e analisar os dados dos indicadores, eu usei as classes detalhadas no artigo anterior. Além disso, eu criei aqui a classe CDealsToIndicators, generalizando todas as classes de indicadores. Ele irá armazenar os arrays de classe dos indicadores e organizar o seu funcionamento.

class CDealsToIndicators
  {
private:
   CADX              *ADX[];
   CAlligator        *Alligator[];
   COneBufferArray   *OneBuffer[];
   CMACD             *MACD[];
   CStaticOneBuffer  *OneBufferStatic[];
   CStaticMACD       *MACD_Static[];
   CStaticADX        *ADX_Static[];
   CStaticAlligator  *Alligator_Static[];
   
   template<typename T>
   void              CleareArray(T *&array[]);

public:
                     CDealsToIndicators();
                    ~CDealsToIndicators();
   //---
   bool              AddADX(string symbol, ENUM_TIMEFRAMES timeframe, int period, string name);
   bool              AddADX(string symbol, ENUM_TIMEFRAMES timeframe, int period, string name, int &handle);
   bool              AddAlligator(string symbol,ENUM_TIMEFRAMES timeframe,uint jaw_period, uint jaw_shift, uint teeth_period, uint teeth_shift, uint lips_period, uint lips_shift, ENUM_MA_METHOD method, ENUM_APPLIED_PRICE price, string name);
   bool              AddAlligator(string symbol,ENUM_TIMEFRAMES timeframe,uint jaw_period, uint jaw_shift, uint teeth_period, uint teeth_shift, uint lips_period, uint lips_shift, ENUM_MA_METHOD method, ENUM_APPLIED_PRICE price, string name, int &handle);
   bool              AddMACD(string symbol, ENUM_TIMEFRAMES timeframe, uint fast_ema, uint slow_ema, uint signal, ENUM_APPLIED_PRICE applied_price, string name);
   bool              AddMACD(string symbol, ENUM_TIMEFRAMES timeframe, uint fast_ema, uint slow_ema, uint signal, ENUM_APPLIED_PRICE applied_price, string name, int &handle);
   bool              AddOneBuffer(int handle, string name);
   //---
   bool              SaveNewValues(long ticket);
   //---
   bool              Static(CArrayObj *deals);
  };

1.3. Criação do Expert Advisor para testes

Tudo está preparado. Agora, procedemos para a criação do EA para trabalhar no testador de estratégia. Primeiro, defina a lista de indicadores aplicados e seus parâmetros. Para demonstrar a tecnologia, eu tirei os seguintes indicadores:

  • ADX;
  • Alligator;
  • CCI;
  • Chaikin;
  • Force Index;
  • MACD.

Para cada um deles, três conjuntos de parâmetros são criados, os dados são rastreados em três intervalos de tempo.

A negociações com stoploss e takeprofit estão vinculadas aos valores dos indicadores ATR e são definidas através da relação risco retorno.

//--- parâmetros de entrada
input double            Reward_Risk    =  1.0;
input int               ATR_Period     =  288;
input ENUM_TIMEFRAMES   TimeFrame1     =  PERIOD_M5;
input ENUM_TIMEFRAMES   TimeFrame2     =  PERIOD_H1;
input ENUM_TIMEFRAMES   TimeFrame3     =  PERIOD_D1;
input string            s1                =  "ADX"                ;  //---
input uint              ADX_Period1       =  14                   ;
input uint              ADX_Period2       =  28                   ;
input uint              ADX_Period3       =  56                   ;
input string            s2                =  "Alligator"          ;  //---
input uint              JAW_Period1       =  13                   ;
input uint              JAW_Shift1        =  8                    ;
input uint              TEETH_Period1     =  8                    ;
input uint              TEETH_Shift1      =  5                    ;
input uint              LIPS_Period1      =  5                    ;
input uint              LIPS_Shift1       =  3                    ;
input uint              JAW_Period2       =  26                   ;
input uint              JAW_Shift2        =  16                   ;
input uint              TEETH_Period2     =  16                   ;
input uint              TEETH_Shift2      =  10                   ;
input uint              LIPS_Period2      =  10                   ;
input uint              LIPS_Shift2       =  6                    ;
input uint              JAW_Period3       =  42                   ;
input uint              JAW_Shift3        =  32                   ;
input uint              TEETH_Period3     =  32                   ;
input uint              TEETH_Shift3      =  20                   ;
input uint              LIPS_Period3      =  20                   ;
input uint              LIPS_Shift3       =  12                   ;
input ENUM_MA_METHOD    Alligator_Method  =  MODE_SMMA            ;
input ENUM_APPLIED_PRICE Alligator_Price  =  PRICE_MEDIAN         ;
input string            s5                =  "CCI"                ;  //---
input uint              CCI_Period1       =  14                   ;
input uint              CCI_Period2       =  28                   ;
input uint              CCI_Period3       =  56                   ;
input ENUM_APPLIED_PRICE CCI_Price        =  PRICE_TYPICAL        ;
input string            s6                =  "Chaikin"            ;  //---
input uint              Ch_Fast_Period1   =  3                    ;
input uint              Ch_Slow_Period1   =  14                   ;
input uint              Ch_Fast_Period2   =  6                    ;
input uint              Ch_Slow_Period2   =  28                   ;
input uint              Ch_Fast_Period3   =  12                   ;
input uint              Ch_Slow_Period3   =  56                   ;
input ENUM_MA_METHOD    Ch_Method         =  MODE_EMA             ;
input ENUM_APPLIED_VOLUME Ch_Volume       =  VOLUME_TICK          ;
input string            s7                =  "Force Index"        ;  //---
input uint              Force_Period1     =  14                   ;
input uint              Force_Period2     =  28                   ;
input uint              Force_Period3     =  56                   ;
input ENUM_MA_METHOD    Force_Method      =  MODE_SMA             ;
input ENUM_APPLIED_VOLUME Force_Volume    =  VOLUME_TICK          ;
input string            s8                =  "MACD"               ;  //---
input uint              MACD_Fast1        =  12                   ;
input uint              MACD_Slow1        =  26                   ;
input uint              MACD_Signal1      =  9                    ;
input uint              MACD_Fast2        =  24                   ;
input uint              MACD_Slow2        =  52                   ;
input uint              MACD_Signal2      =  18                   ;
input uint              MACD_Fast3        =  48                   ;
input uint              MACD_Slow3        =  104                  ;
input uint              MACD_Signal3      =  36                   ;
input ENUM_APPLIED_PRICE MACD_Price       =  PRICE_CLOSE          ;

No bloco de variáveis globais, declare:

  • array para armazenar as transações da classe de negociação,
  • instância de classe para trabalhar com os indicadores IndicatorsStatic,
  • variável para armazenar o manipulador do indicador ATR,
  • duas variáveis ​​de serviço para armazenar o horário da última barra processada (last_bar) e a última ordem fechada (last_closed_deal). Nós precisamos que esta última não perca posições já fechadas em cada tick.

Na função OnInit, execute a inicialização de variáveis ​​globais e as classes de indicadores necessários.

int OnInit()
  {
//---
   last_bar=0;
   last_closed_deal=0;
//---
   Deals =  new CArrayObj();
   if(CheckPointer(Deals)==POINTER_INVALID)
      return INIT_FAILED;
//---
   IndicatorsStatic  =  new CDealsToIndicators();
   if(CheckPointer(IndicatorsStatic)==POINTER_INVALID)
      return INIT_FAILED;
//---
   atr=iATR(_Symbol,TimeFrame1,ATR_Period);
   if(atr==INVALID_HANDLE)
      return INIT_FAILED;
//---
   AddIndicators(TimeFrame1);
   AddIndicators(TimeFrame2);
   AddIndicators(TimeFrame3);
//---
   return(INIT_SUCCEEDED);
  }

Nós usaremos o mesmo conjunto de indicadores em três intervalos diferentes. É por isso que é razoável colocar a inicialização das classes dos indicadores em uma função separada - AddIndicators. Em seus parâmetros, o tempo gráfico necessário será especificado.

bool AddIndicators(ENUM_TIMEFRAMES timeframe)
  {
   if(CheckPointer(IndicatorsStatic)==POINTER_INVALID)
     {
      IndicatorsStatic  =  new CDealsToIndicators();
      if(CheckPointer(IndicatorsStatic)==POINTER_INVALID)
         return false;
     }
   string tf_name=StringSubstr(EnumToString(timeframe),7);
   string name="ADX("+IntegerToString(ADX_Period1)+") "+tf_name;
   if(!IndicatorsStatic.AddADX(_Symbol, timeframe, ADX_Period1, name))
      return false;
   name="ADX("+IntegerToString(ADX_Period2)+") "+tf_name;
   if(!IndicatorsStatic.AddADX(_Symbol, timeframe, ADX_Period2, name))
      return false;
   name="ADX("+IntegerToString(ADX_Period3)+") "+tf_name;
   if(!IndicatorsStatic.AddADX(_Symbol, timeframe, ADX_Period3, name))
      return false;
   name="Alligator("+IntegerToString(JAW_Period1)+","+IntegerToString(TEETH_Period1)+","+IntegerToString(LIPS_Period1)+") "+tf_name;
   if(!IndicatorsStatic.AddAlligator(_Symbol, timeframe, JAW_Period1, JAW_Shift1, TEETH_Period1, TEETH_Shift1, LIPS_Period1, LIPS_Shift1, Alligator_Method, Alligator_Price, name))
      return false;
   name="Alligator("+IntegerToString(JAW_Period2)+","+IntegerToString(TEETH_Period2)+","+IntegerToString(LIPS_Period2)+") "+tf_name;
   if(!IndicatorsStatic.AddAlligator(_Symbol, timeframe, JAW_Period2, JAW_Shift2, TEETH_Period2, TEETH_Shift2, LIPS_Period2, LIPS_Shift2, Alligator_Method, Alligator_Price, name))
      return false;
   name="Alligator("+IntegerToString(JAW_Period3)+","+IntegerToString(TEETH_Period3)+","+IntegerToString(LIPS_Period3)+") "+tf_name;
   if(!IndicatorsStatic.AddAlligator(_Symbol, timeframe, JAW_Period3, JAW_Shift3, TEETH_Period3, TEETH_Shift3, LIPS_Period3, LIPS_Shift3, Alligator_Method, Alligator_Price, name))
      return false;
   name="MACD("+IntegerToString(MACD_Fast1)+","+IntegerToString(MACD_Slow1)+","+IntegerToString(MACD_Signal1)+") "+tf_name;
   if(!IndicatorsStatic.AddMACD(_Symbol, timeframe, MACD_Fast1, MACD_Slow1, MACD_Signal1, MACD_Price, name))
      return false;
   name="MACD("+IntegerToString(MACD_Fast2)+","+IntegerToString(MACD_Slow2)+","+IntegerToString(MACD_Signal2)+") "+tf_name;
   if(!IndicatorsStatic.AddMACD(_Symbol, timeframe, MACD_Fast2, MACD_Slow2, MACD_Signal2, MACD_Price, name))
      return false;
   name="MACD("+IntegerToString(MACD_Fast3)+","+IntegerToString(MACD_Slow3)+","+IntegerToString(MACD_Signal3)+") "+tf_name;
   if(!IndicatorsStatic.AddMACD(_Symbol, timeframe, MACD_Fast3, MACD_Slow3, MACD_Signal3, MACD_Price, name))
      return false;
   name="CCI("+IntegerToString(CCI_Period1)+") "+tf_name;
   int handle = iCCI(_Symbol, timeframe, CCI_Period1, CCI_Price);
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   name="CCI("+IntegerToString(CCI_Period2)+") "+tf_name;
   handle = iCCI(_Symbol, timeframe, CCI_Period2, CCI_Price);
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   handle = iCCI(_Symbol, timeframe, CCI_Period3, CCI_Price);
   name="CCI("+IntegerToString(CCI_Period3)+") "+tf_name;
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   handle = iForce(_Symbol, timeframe, Force_Period1, Force_Method, Force_Volume);
   name="Force("+IntegerToString(Force_Period1)+") "+tf_name;
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   handle = iForce(_Symbol, timeframe, Force_Period2, Force_Method, Force_Volume);
   name="Force("+IntegerToString(Force_Period2)+") "+tf_name;
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   handle = iForce(_Symbol, timeframe, Force_Period3, Force_Method, Force_Volume);
   name="Force("+IntegerToString(Force_Period3)+") "+tf_name;
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   name="CHO("+IntegerToString(Ch_Slow_Period1)+","+IntegerToString(Ch_Fast_Period1)+") "+tf_name;
   handle = iChaikin(_Symbol, timeframe, Ch_Fast_Period1, Ch_Slow_Period1, Ch_Method, Ch_Volume);
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   handle = iChaikin(_Symbol, timeframe, Ch_Fast_Period2, Ch_Slow_Period2, Ch_Method, Ch_Volume);
   name="CHO("+IntegerToString(Ch_Slow_Period2)+","+IntegerToString(Ch_Fast_Period2)+") "+tf_name;
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   handle = iChaikin(_Symbol, timeframe, Ch_Fast_Period3, Ch_Slow_Period3, Ch_Method, Ch_Volume);
   name="CHO("+IntegerToString(Ch_Slow_Period3)+","+IntegerToString(Ch_Fast_Period3)+") "+tf_name;
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   return true;
  }

As operações realizadas na OnTick podem ser divididas em dois blocos: controle de posições abertas e abertura de novas posições.

O primeiro bloco de operações é realizado em cada tick. Nela, todos os negócios abertos anteriormente são, consequentemente, recuperados do array e a função Tick é chamada para cada um deles. Ele verifica o gatilho do stop loss e de take profit da posição e, quando necessário, uma ordem é encerrada no preço atual, poupando o lucro gerado. Para não verificar novamente os negócios encerrado anteriormente, na variável last_closed_deal, o número da negociação que precede o primeiro não encerrado é salvo. 

void OnTick()
  {
//---
   int total=Deals.Total();
   CDeal *deal;
   bool found=false;
   for(int i=last_closed_deal;i<total;i++)
     {
      deal  =  Deals.At(i);
      if(CheckPointer(deal)==POINTER_INVALID)
         continue;
      if(!found)
        {
         if(deal.IsClosed())
           {
            last_closed_deal=i;
            continue;
           }
         else
            found=true;
        }
      deal.Tick();
     }

O segundo bloco de operações começa com a verificação da ocorrência de novas barras. No início de cada barra, obtém-se o valor do indicador ATR da última vela fechada, calcula-se a o stop loss e o take profit de acordo com os parâmetros definidos e as posições virtuais abertas. Para cada posição, é salvo os dados do indicador chamando a função SaveNewValues ​​da nossa classe para trabalhar com os indicadores.

//---
   datetime cur_bar=(datetime)SeriesInfoInteger(_Symbol,PERIOD_CURRENT,SERIES_LASTBAR_DATE);
   datetime cur_time=TimeCurrent();
   if(cur_bar==last_bar || (cur_time-cur_bar)>10)
      return;
   double atrs[];
   if(CopyBuffer(atr,0,1,1,atrs)<=0)
      return;

   last_bar=cur_bar;
   double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
   double stops=MathMax(2*atrs[0],SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point);
   double sl=NormalizeDouble(stops,_Digits);
   double tp=NormalizeDouble(Reward_Risk*(stops+ask-bid),_Digits);
   deal  =  new CDeal(_Symbol,POSITION_TYPE_BUY,TimeCurrent(),ask,bid-sl,ask+tp);
   if(CheckPointer(deal)!=POINTER_INVALID)
      if(Deals.Add(deal))
         IndicatorsStatic.SaveNewValues(Deals.Total()-1);
   deal  =  new CDeal(_Symbol,POSITION_TYPE_SELL,TimeCurrent(),bid,ask+sl,bid-tp);
   if(CheckPointer(deal)!=POINTER_INVALID)
      if(Deals.Add(deal))
         IndicatorsStatic.SaveNewValues(Deals.Total()-1);
   return;
  }

No OnTester, é coletado os resultados do teste executado e construído os gráficos para análise. Para isso, chama-se a função estática da classe para trabalhar com os indicadores.

Certifique-se de limpar a memória na função OnDeinit!

O código completo do EA e as classes utilizadas são fornecidas em anexo.

2. Análise dos resultados dos testes

Então, nós criamos o EA de testes. Agora, vamos pensar sobre o período analisado. Ao escolher um período, leve em consideração que ele deve ser suficientemente longo para que a objetividade da análise seja alcançada. Outro requisito para um período: deve incluir não apenas movimentos unidirecionais, mas também períodos de movimentos de tendências bidirecionais, bem como de forma lateralizada. Essa abordagem permite criar uma estratégia de negociação capaz de gerar lucro dentro dos períodos de qualquer movimento. Meu exemplo analisa o par de moedas EURUSD para o período de 01/01/2016 a 1/10/2017.

Período de testeParâmetros de teste

Até agora, nosso processo terá um caráter iterativo que eu recomendo depois de configurar todos os parâmetros necessários para testar o EA para salvar o conjunto de parâmetros do arquivo para trabalhos futuros.

Cada estágio de teste será realizado em 2 execuções com relação lucro/ risco retorno igual a 1/1 e 15/1. Na primeira execução, avaliaremos a probabilidade de um movimento direcionado, enquanto que na segunda a força do movimento.

O EA mostra um grande número de gráficos para análise, portanto, eles não são fornecidos no artigo na íntegra - todos os relatórios são fornecidos em anexo. Aqui, nós mostraremos apenas os gráficos, através dos quais foram tomadas as decisões sobre o uso de indicadores na nova estratégia.

2.1. Primeira etapa

Como nós esperávamos, a primeira etapa de teste não mostrou áreas lucrativas definidas. Mas, ao mesmo tempo, deve-se prestar atenção ao indicador índice de força. No tempo gráfico M5, o gráfico de dependência do lucro das operações em relação aos valores dos indicadores cai para a área zero. A importância desta observação é evidenciada pelo fato de que esse fenômeno aparece nos gráficos dos indicadores analíticos com todos os parâmetros utilizados para testes. Para o nosso modelo, selecione os parâmetros com o caractere do fenômeno mais aparente (rebaixamento máximo).

Gráficos analíticos do indicador de força com um período igual a 56 no tempo gráfico M5

Vamos ampliar o gráfico analisado. Como você pode ver, o efeito desse fator está disponível no intervalo de -0.01 a 0.01. O fenômeno observado é igualmente verdadeiro tanto para negociações de compra quanto para venda.

Esta observação pode ser explicada pela ausência de volatilidade dentro do intervalo de valores observado. Para a nossa estratégia, certifique-se de marcar a proibição para abrir quaisquer ordens dentro deste intervalo.

Depende do lucro nos valores do indicador índice de força perto da marca zero.

Adicione nossa EA a este filtro. Para fazer isso, primeiro adicione a variável global para armazenar o manipulador do indicador.

int                  force;

Na medida em que o indicador necessário como o filtro já é aplicado no EA, nós não vamos anexá-lo ao gráfico mais uma vez. Basta copiar seu manipulador para a nossa variável global em AddIndicators. Mas certifique-se de lembrar que esta função é chamada três vezes para a inicialização do indicador em diferentes tempos gráficos. Portanto, antes de copiar o manipulador do indicador, nós devemos verificar a conformidade do tempo gráfico.

   handle = iForce(_Symbol, timeframe, Force_Period3, Force_Method, Force_Volume);
   if(timeframe==TimeFrame1)
      force=handle;

Agora, adicione o filtro imediatamente ao OnTick. Ao construir o gráfico, lembre-se de que, na função de construção do gráfico analítico, os dados foram arredondados. Portanto, deve-se arredondar também os dados ao filtrar os valores do indicador de negociação.

   double atrs[];
   double force_data[];
   if(CopyBuffer(atr,0,1,1,atrs)<=0 || CopyBuffer(force,0,1,1,force_data)<=0)
      return;      // Algum erro no carregamento dos dados do indicador

   last_bar=cur_bar;
   double d_Step=_Point*1000;
   if(MathAbs(NormalizeDouble(force_data[0]/d_Step,0)*d_Step)<=0.01)
      return;    // Filtrado pelo Índice de Força

O código completo do EA é fornecido em anexo a este artigo.

Depois de adicionar o filtro no EA, implemente o segundo estágio de teste. Antes de testar, certifique-se de baixar os parâmetros salvos anteriormente.

2.2. Segunda etapa

Após repetidos testes do EA, eu prestei atenção no indicador MACD. As áreas rentáveis ​​apareceram no gráfico.

O gráfico de dependência de lucro nos valores do histograma MACD.

No gráfico com a proporção de lucro/risco 15/1, essas áreas são mais expressas; Isso pode evidenciar potencial de sinais dentro dessas faixas.

O gráfico de dependência de lucro nos valores do histograma MACD (lucro/risco = 15/1)

Este filtro também deve ser adicionado ao nosso código do EA. A lógica da adição do filtro é análoga à fornecida na descrição da primeira fase.

Em variáveis ​​globais:

int                  macd;

Na função AddIndicators:

   name="MACD("+IntegerToString(MACD_Fast2)+","+IntegerToString(MACD_Slow2)+","+IntegerToString(MACD_Signal2)+") "+tf_name;
   if(timeframe==TimeFrame1)
     {
      if(!IndicatorsStatic.AddMACD(_Symbol, timeframe, MACD_Fast2, MACD_Slow2, MACD_Signal2, MACD_Price, name, macd))
         return false;
     }
   else
     {
      if(!IndicatorsStatic.AddMACD(_Symbol, timeframe, MACD_Fast2, MACD_Slow2, MACD_Signal2, MACD_Price, name))
         return false;
     }

Na OnTick:

   double macd_data[];
   if(CopyBuffer(atr,0,1,1,atrs)<=0 || CopyBuffer(force,0,1,1,force_data)<=0 || CopyBuffer(macd,0,1,1,macd_data)<=0)
      return;

e

   double macd_Step=_Point*50;
   macd_data[0]=NormalizeDouble(macd_data[0]/macd_Step,0)*macd_Step;
   if(macd_data[0]>=0.0015 && macd_data[0]<=0.0035)
     {
      deal  =  new CDeal(_Symbol,POSITION_TYPE_BUY,TimeCurrent(),ask,bid-sl,ask+tp);
      if(CheckPointer(deal)!=POINTER_INVALID)
         if(Deals.Add(deal))
            IndicatorsStatic.SaveNewValues(Deals.Total()-1);
     }
   if(macd_data[0]<=(-0.0015) && macd_data[0]>=(-0.0035))
     {
      deal  =  new CDeal(_Symbol,POSITION_TYPE_SELL,TimeCurrent(),bid,ask+sl,bid-tp);
      if(CheckPointer(deal)!=POINTER_INVALID)
         if(Deals.Add(deal))
            IndicatorsStatic.SaveNewValues(Deals.Total()-1);
     }

Depois de adicionar o deslocamento do filtro para a terceira etapa do teste.

2.3. Terceira etapa

Na terceira etapa, eu prestei atenção no oscilador Chaikin. Nas gráficos analíticos do oscilador no tempo gráfico D1, nós vemos o crescimento do lucro em posições longas na redução de valores, enquanto que no crescimento do valor dos indicadores, o lucro cresce em posições vendidas.

Dependência de lucro nos valores do oscilador Chaikin

Minha observação é confirmada também ao analisar os gráficos com a razão lucro/risco igual a 15/1.

Dependência de lucro nos valores do oscilador Chaikin.

Adicione nossa observação ao código do EA.

Em variáveis ​​globais:

int                  cho;

Na função AddIndicators:

   handle = iChaikin(_Symbol, timeframe, Ch_Fast_Period2, Ch_Slow_Period2, Ch_Method, Ch_Volume);
   name="CHO("+IntegerToString(Ch_Slow_Period2)+","+IntegerToString(Ch_Fast_Period2)+") "+tf_name;
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   if(timeframe==TimeFrame3)
      cho=handle;

Na OnTick:

   double cho_data[];
   if(CopyBuffer(atr,0,1,1,atrs)<=0 || CopyBuffer(force,0,1,1,force_data)<=0 || CopyBuffer(macd,0,1,1,macd_data)<=0
      || CopyBuffer(cho,0,1,2,cho_data)<2)
      return;

e

   if(macd_data[0]>=0.0015 && macd_data[0]<=0.0035 && (cho_data[1]-cho_data[0])<0)
     {
      deal  =  new CDeal(_Symbol,POSITION_TYPE_BUY,TimeCurrent(),ask,bid-sl,ask+tp);
      if(CheckPointer(deal)!=POINTER_INVALID)
         if(Deals.Add(deal))
            IndicatorsStatic.SaveNewValues(Deals.Total()-1);
     }
   if(macd_data[0]<=(-0.0015) && macd_data[0]>=(-0.0035) && (cho_data[1]-cho_data[0])>0)
     {
      deal  =  new CDeal(_Symbol,POSITION_TYPE_SELL,TimeCurrent(),bid,ask+sl,bid-tp);
      if(CheckPointer(deal)!=POINTER_INVALID)
         if(Deals.Add(deal))
            IndicatorsStatic.SaveNewValues(Deals.Total()-1);
     }

Prossiga para a etapa seguinte.

2.4. Quarta etapa

Depois de mais um teste do EA, minha atenção foi novamente destinada para o tempo gráfico D1. Desta vez, eu considerei o indicador CCI. Seus gráficos analíticos demonstraram crescimento de lucro em posições vendidas na redução de valores do indicador e crescimento do lucro nas posições compradas - com o crescimento nos valores do indicador. Essa tendência foi observada em todos os três períodos estudados, mas o lucro máximo foi alcançado quando se usa o período 14, que é padrão para este oscilador.

Dependência do lucro nos valores dos indicadores CCI.

Os gráficos analíticos recebidos no teste com razão lucro/risco igual a 15/1 confirmam a nossa observação.

Dependência do lucro nos valores dos indicadores CCI.

Adicione esta observação também ao teste do código do EA.

Em variáveis ​​globais:

int                  cci;

Para o AddIndicators:

   name="CCI("+IntegerToString(CCI_Period1)+") "+tf_name;
   int handle = iCCI(_Symbol, timeframe, CCI_Period1, CCI_Price);
   if(handle<0 || !IndicatorsStatic.AddOneBuffer(handle, name) )
      return false;
   if(timeframe==TimeFrame3)
      cci=handle;

Para o OnTick:

   double cci_data[];
   if(CopyBuffer(atr,0,1,1,atrs)<=0 || CopyBuffer(force,0,1,1,force_data)<=0 || CopyBuffer(macd,0,1,1,macd_data)<=0
      || CopyBuffer(cho,0,1,2,cho_data)<2 || CopyBuffer(cci,0,1,2,cci_data)<2)
      return;

e

   if(macd_data[0]>=0.0015 && macd_data[0]<=0.0035 && (cho_data[1]-cho_data[0])<0 && (cci_data[1]-cci_data[0])>0)
     {
      deal  =  new CDeal(_Symbol,POSITION_TYPE_BUY,TimeCurrent(),ask,bid-sl,ask+tp);
      if(CheckPointer(deal)!=POINTER_INVALID)
         if(Deals.Add(deal))
            IndicatorsStatic.SaveNewValues(Deals.Total()-1);
     }
   if(macd_data[0]<=(-0.0015) && macd_data[0]>=(-0.0035) && (cho_data[1]-cho_data[0])>0 && (cci_data[1]-cci_data[0])<0)
     {
      deal  =  new CDeal(_Symbol,POSITION_TYPE_SELL,TimeCurrent(),bid,ask+sl,bid-tp);
      if(CheckPointer(deal)!=POINTER_INVALID)
         if(Deals.Add(deal))
            IndicatorsStatic.SaveNewValues(Deals.Total()-1);
     }

O código completo do EA em todas as etapas é fornecido em anexo ao artigo.

3. Criação e teste do EA nos sinais selecionados

Não há limite para a perfeição, você pode continuar analisando e adicionando os filtros para aumentar o fator de lucro da estratégia. Mas eu acredito que as quatro etapas fornecidas são suficientes para a demonstração da tecnologia. No próximo passo, crie um EA simples para verificar nossa estratégia no testador. Isso nos permitirá avaliar o fator de lucro e o rebaixamento de nossa estratégia, bem como a variação do saldo em andamento.

Na estratégia, nós utilizamos os quatro indicadores para tomar uma decisão sobre a negociação e o indicador ATR para definir o stop loss e take profit. Consequentemente, nos parâmetros de entrada do EA, nós devemos definir todas as informações de entrada necessárias para os indicadores. Nesta fase, nós não criaremos o gerenciamento de dinheiro, todos as ordens usarão uma quantidade fixa do volume.

//--- parâmetros de entrada
input double            Lot               =  0.1                  ;
input double            Reward_Risk       =  15.0                 ;
input ENUM_TIMEFRAMES   ATR_TimeFrame     =  PERIOD_M5            ;
input int               ATR_Period        =  288                  ;
input string            s1                =  "CCI"                ;  //---
input ENUM_TIMEFRAMES   CCI_TimeFrame     =  PERIOD_D1            ;
input uint              CCI_Period        =  14                   ;
input ENUM_APPLIED_PRICE CCI_Price        =  PRICE_TYPICAL        ;
input string            s2                =  "Chaikin"            ;  //---
input ENUM_TIMEFRAMES   Ch_TimeFrame      =  PERIOD_D1            ;
input uint              Ch_Fast_Period    =  6                    ;
input uint              Ch_Slow_Period    =  28                   ;
input ENUM_MA_METHOD    Ch_Method         =  MODE_EMA             ;
input ENUM_APPLIED_VOLUME Ch_Volume       =  VOLUME_TICK          ;
input string            s3                =  "Force Index"        ;  //---
input ENUM_TIMEFRAMES   Force_TimeFrame   =  PERIOD_M5            ;
input uint              Force_Period      =  56                   ;
input ENUM_MA_METHOD    Force_Method      =  MODE_SMA             ;
input ENUM_APPLIED_VOLUME Force_Volume    =  VOLUME_TICK          ;
input string            s4                =  "MACD"               ;  //---
input ENUM_TIMEFRAMES   MACD_TimeFrame    =  PERIOD_M5            ;
input uint              MACD_Fast         =  12                   ;
input uint              MACD_Slow         =  26                   ;
input uint              MACD_Signal       =  9                    ;
input ENUM_APPLIED_PRICE MACD_Price       =  PRICE_CLOSE          ;

Nas variáveis ​​globais, declare:

  • instância de classe para realizar as operações de negociação,
  • variáveis ​​para lidar com o armazenamento dos indicadores usados,
  • variáveis ​​auxiliares para as datas de gravação da última barra processada e da última negociação,
  • variáveis ​​para armazenar o tempo gráfico máximo e mínimo.

Na função OnInit, inicialize os indicadores e defina os valores iniciais das variáveis.

int OnInit()
  {
//---
   last_bar=0;
   last_deal=0;
//---
   atr=iATR(_Symbol,ATR_TimeFrame,ATR_Period);
   if(atr==INVALID_HANDLE)
      return INIT_FAILED;
//---
   force=iForce(_Symbol,Force_TimeFrame,Force_Period,Force_Method,Force_Volume);
   if(force==INVALID_HANDLE)
      return INIT_FAILED;
//---
   macd=iMACD(_Symbol,MACD_TimeFrame,MACD_Fast,MACD_Slow,MACD_Signal,MACD_Price);
   if(macd==INVALID_HANDLE)
      return INIT_FAILED;
//---
   cho=iChaikin(_Symbol,Ch_TimeFrame,Ch_Fast_Period,Ch_Slow_Period,Ch_Method,Ch_Volume);
   if(cho==INVALID_HANDLE)
      return INIT_FAILED;
//---
   cci=iCCI(_Symbol,CCI_TimeFrame,CCI_Period,CCI_Price);
   if(cci==INVALID_HANDLE)
      return INIT_FAILED;
//---
   MaxPeriod=fmax(Force_TimeFrame,MACD_TimeFrame);
   MaxPeriod=fmax(MaxPeriod,Ch_TimeFrame);
   MaxPeriod=fmax(MaxPeriod,CCI_TimeFrame);
   MinPeriod=fmin(Force_TimeFrame,MACD_TimeFrame);
   MinPeriod=fmin(MinPeriod,Ch_TimeFrame);
   MinPeriod=fmin(MinPeriod,CCI_TimeFrame);
//---
   return(INIT_SUCCEEDED);
  }

Na função OnDeinit, feche os indicadores utilizados.

void OnDeinit(const int reason)
  {
//---
   if(atr!=INVALID_HANDLE)
      IndicatorRelease(atr);
//---
   if(force==INVALID_HANDLE)
      IndicatorRelease(force);
//---
   if(macd==INVALID_HANDLE)
      IndicatorRelease(macd);
//---
   if(cho==INVALID_HANDLE)
      IndicatorRelease(cho);
//---
   if(cci==INVALID_HANDLE)
      IndicatorRelease(cci);
  }

As principais ações serão realizadas no OnTick. No início da função, verifique a ocorrência de uma nova barra. Uma nova posição será aberta somente na abertura de uma nova barra pelo tempo gráfico mínimo (eu limitei 10 segundos da abertura da barra) e, somente, a menos que uma posição for aberta dentro da barra atual pelo tempo gráfico máximo. De tal maneira, eu limitava a abertura de apenas uma ordem para um sinal.

void OnTick()
  {
//---
   datetime cur_bar=(datetime)SeriesInfoInteger(_Symbol,MinPeriod,SERIES_LASTBAR_DATE);
   datetime cur_max=(datetime)SeriesInfoInteger(_Symbol,MaxPeriod,SERIES_LASTBAR_DATE);
   datetime cur_time=TimeCurrent();
   if(cur_bar<=last_bar || (cur_time-cur_bar)>10 || cur_max<=last_deal)
      return;

Além disso, obtenha os dados dos indicadores utilizados. Em caso de erro de obtenção dos dados de pelo menos um dos indicadores, saia da função.

   last_bar=cur_bar;
   double atrs[];
   double force_data[];
   double macd_data[];
   double cho_data[];
   double cci_data[];
   if(CopyBuffer(atr,0,1,1,atrs)<=0 || CopyBuffer(force,0,1,1,force_data)<=0 || CopyBuffer(macd,0,1,1,macd_data)<=0
      || CopyBuffer(cho,0,1,2,cho_data)<2 || CopyBuffer(cci,0,1,2,cci_data)<2)
     {
      return;
     }

Em seguida, em conformidade com a nosso estratégia, verifique o índice de força. Se não conseguir satisfazer o nosso filtro, saia da função até abrir a próxima barra.

   double force_Step=_Point*1000;
   if(MathAbs(NormalizeDouble(force_data[0]/force_Step,0)*force_Step)<=0.01)
      return;

Na próxima etapa, verifique o sinal para a abertura de posição comprada. Se houver um sinal positivo, verifique se uma posição aberta já está disponível. Se disponível e é vendida, encerre ela. Se uma posição comprada está sendo perdedora, ignora o sinal e sai da função.

Depois disso, calcule os parâmetros para a nova posição e envie uma ordem.

Execute as mesmas operações para a posição vendida.

   double macd_Step=_Point*50;
   macd_data[0]=NormalizeDouble(macd_data[0]/macd_Step,0)*macd_Step;
   if(macd_data[0]>=0.0015 && macd_data[0]<=0.0035 && (cho_data[1]-cho_data[0])<0 && (cci_data[1]-cci_data[0])>0)
     {
      if(PositionSelect(_Symbol))
        {
         switch((int)PositionGetInteger(POSITION_TYPE))
           {
            case POSITION_TYPE_BUY:
              if(PositionGetDouble(POSITION_PROFIT)<=0)
                 return;
              break;
            case POSITION_TYPE_SELL:
              Trade.PositionClose(_Symbol);
              break;
           }
        }
      last_deal=cur_max;
      double stops=MathMax(2*atrs[0],SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point);
      double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
      double sl=NormalizeDouble(stops,_Digits);
      double tp=NormalizeDouble(Reward_Risk*(stops+ask-bid),_Digits);
      double SL=NormalizeDouble(bid-sl,_Digits);
      double TP=NormalizeDouble(ask+tp,_Digits);
      if(!Trade.Buy(Lot,_Symbol,ask,SL,TP,"New Strategy"))
         Print("Error of open BUY ORDER "+Trade.ResultComment());
     }
   if(macd_data[0]<=(-0.0015) && macd_data[0]>=(-0.0035) && (cho_data[1]-cho_data[0])>0 && (cci_data[1]-cci_data[0])<0)
     {
      if(PositionSelect(_Symbol))
        {
         switch((int)PositionGetInteger(POSITION_TYPE))
           {
            case POSITION_TYPE_SELL:
              if(PositionGetDouble(POSITION_PROFIT)<=0)
                 return;
              break;
            case POSITION_TYPE_BUY:
              Trade.PositionClose(_Symbol);
              break;
           }
        }
      last_deal=cur_max;
      double stops=MathMax(2*atrs[0],SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point);
      double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
      double sl=NormalizeDouble(stops,_Digits);
      double tp=NormalizeDouble(Reward_Risk*(stops+ask-bid),_Digits);
      double SL=NormalizeDouble(ask+sl,_Digits);
      double TP=NormalizeDouble(bid-tp,_Digits);
      if(!Trade.Sell(Lot,_Symbol,bid,SL,TP,"New Strategy"))
         Print("Error of open SELL ORDER "+Trade.ResultComment());
     }
   return;
  }

O código completo do EA é fornecido em anexo.

Depois de preparar o EA, nós podemos testar nossa estratégia. Para evitar a situação "adequação da estratégia com o período", estenda o período testado: teste a estratégia de 1/01/2015 até 01/12/2017. O capital inicial dos testes é de USD 10 000, volume - 1 lote.

Teste da estratégia. 

De acordo com os resultados dos testes, o EA demonstrou um lucro de 74.8% com um rebaixamento máximo de 12.4% do saldo e patrimônio de 23.8%. No total, foram feitas 44 negociações (22 posições vendidas e 22 compradas). A participação das posições lucrativas ​​representa 18.2% e é igual tanto para posições vendidas quanto para as compradas. Essa baixa percentagem de posições lucrativas é estipulada pelo uso de alta proporção de risco retorno (15:1) e deixa espaço para uma maior melhoria da estratégia.

Resultados do teste da estratégia.

Conclusão

O artigo demonstrou a tecnologia para criação de uma estratégia de negociação "do zero" usando um método de entrada nos indicadores. A estratégia obtida como resultado é capaz de gerar lucro para um período de tempo prolongado, que se comprova através do teste durante três anos. Não obstante o fato de que, ao criar os indicadores da estratégia do pacote padrão do MetaTrader, os sinais para a realização de negócios estão longe dos descritos na literatura para os indicadores selecionados. A tecnologia sugerida permite uma abordagem criativa para usar os indicadores nas estratégias de negociação e não está limitada pelos indicadores utilizados. Você pode usar qualquer indicador e variantes para avaliar a qualidade de seus sinais.

Referências

  1. Entradas nos indicadores
  2. Gráficos e diagramas em formato HTML

Programas usados ​​no artigo:

#
 Nome
Tipo 
Descrição 
  New_Strategy_Gizlyk.zip    
1 NewStrategy1.mq5  EA  EA para implementar a primeira etapa da criação da estratégia
 2 NewStrategy2.mq5   EA EA para implementar a segunda etapa da criação da estratégia
 3 NewStrategy3.mq5   EA  EA para implementar a terceira etapa da criação da estratégia 
 4 NewStrategy4.mq5   EA
 EA para implementar a quarta etapa da criação da estratégia 
 5 NewStrategy_Final.mq5  EA
 Teste da estratégia do EA
6 DealsToIndicators.mqh  Biblioteca da classe  Classe para trabalhar com as classes dos indicadores
7 Deal.mqh   Biblioteca da classe  Classe para salvar as informações de uma negociação
8 Value.mqh   Biblioteca da classe  Classe para salvar os dados no buffer de estado do indicador
9 OneBufferArray.mqh  Biblioteca da classe  Classe para salvar os dados históricos de indicadores de um buffer
10 StaticOneBuffer.mqh  Biblioteca da classe  Classe para coletar e análisar as estatísticas de indicadores de um buffer
11 ADXValue.mqh  Biblioteca da classe  Classe para salvar os dados do estado do indicador ADX
12 ADX.mqh  Biblioteca da classe  Classe para salvar os dados históricos do estado do indicador ADX
13 StaticADX.mqh  Biblioteca da classe  Classe para coleta e análise de estatísticas do indicador ADX
14 AlligatorValue.mqh  Biblioteca da classe  Classe para salvar os dados do estado do indicador Alligator
15 Alligator.mqh  Biblioteca da classe  Classe para salvar os dados históricos do estado do indicador Alligator
16 StaticAlligator.mqh  Biblioteca da classe  Classe para coleta e análise de estatísticas do indicador Alligator
17 MACDValue.mqh  Biblioteca da classe  Classe para salvar os dados do estado do indicador MACD
18 MACD.mqh  Biblioteca da classe  Classe para salvar os dados históricos do estado do indicador MACD
19 StaticMACD.mqh  Biblioteca da classe  Classe para coleta e análise de estatísticas do indicador MACD
   Common.zip    
20  NewStrategy1_Report_1to1_2016-17.html  Arquivo da Internet  Gráficos analíticos da primeira etapa da criação da estratégia, lucro/risco = 1/1
21  NewStrategy1_Report_15to1_2016-17.html  Arquivo da Internet  Gráficos analíticos da primeira etapa da criação da estratégia, lucro/risco = 15/1
22  NewStrategy2_Report_1to1_2016-17.html   Arquivo da Internet  Gráficos analíticos da segunda etapa da criação da estratégia, lucro/risco = 1/1
23  NewStrategy2_Report_15to1_2016-17.html  Arquivo da Internet  Gráficos analíticos da segunda etapa da criação da estratégia, lucro/risco = 15/1
24  NewStrategy3_Report_1to1_2016-17.html   Arquivo da Internet  Gráficos analíticos da terceira etapa da criação da estratégia, lucro/risco = 1/1
25  NewStrategy3_Report_15to1_2016-17.html   Arquivo da Internet  Gráficos analíticos da terceira etapa da criação da estratégia, lucro/risco = 15/1
26  NewStrategy4_Report_1to1_2016-17.html   Arquivo da Internet  Gráficos analíticos da quarta etapa da criação da estratégia, lucro/risco = 1/1
27  NewStrategy4_Report_15to1_2016-17.html   Arquivo da Internet  Gráficos analíticos da quarta etapa da criação da estratégia, lucro/risco = 15/1
28  NewStrategy_Final_Report.html  Arquivo da Internet  Relatório do teste da estratégia

Traduzido do russo por MetaQuotes Software Corp.
Artigo original: https://www.mql5.com/ru/articles/4192

Arquivos anexados |
Common.zip (1455.62 KB)
Seleção automática de sinais promissores Seleção automática de sinais promissores

O artigo analisa os sinais de negociação, para o MetaTrader 5, com execução automática, nas contas dos assinantes. Também é estudado o desenvolvimento de ferramentas para procurar sinais de negociação promissores diretamente no terminal.

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.

Testador de estratégia personalizada com base em cálculos matemáticos rápido Testador de estratégia personalizada com base em cálculos matemáticos rápido

O artigo descreve como criar um testador de estratégias personalizado e um analisador de corridas de otimização próprio. Depois de lê-lo, você vai entender como funciona o modo de cálculos matemáticos e o mecanismo de quadros, como preparar e fazer upload de seus próprios dados para cálculos e usar algoritmos eficientes para comprimi-los. Além disso, este artigo será de interesse para quem deseje saber maneiras de armazenar informações personalizadas num EA.