English Русский 中文 Español Deutsch 日本語
Expert Advisors baseado em sistemas de trading populares e alquimia da otimização de robô de trading (Parte IV)

Expert Advisors baseado em sistemas de trading populares e alquimia da otimização de robô de trading (Parte IV)

MetaTrader 4Sistemas de negociação | 5 fevereiro 2016, 09:29
578 0
Nikolay Kositsin
Nikolay Kositsin

Introdução

Nos meus artigos anteriores nº. 2 e 3 eu descrevi o básico dos testes de simulação. Na minha opinião, o propósito principal dos testes de simulação é uma análise qualitativa do comportamento do EA dentro de um determinado período de tempo desde que os parâmetros do EA sejam mudados de tempos em tempos. A estratégia de usar resultados de otimização neste processo será alguma regra estrita para selecionar parâmetros a partir de todas as variantes recebidas como resultado de cada otimização. Por exemplo, uma variante com rentabilidade máxima e perda mínima.

Tal variante é selecionada entre todas as outras variantes de uma otimização separada, independente do que fizemos em otimizações anteriores. Se você detectar que tal estratégia é rentável em alguns períodos de tempo e em alguns períodos ela está próxima de um patamar de nivelamento, podemos concluir que seu sistema de negociação com tal estratégia usando parâmetros otimizados tem possibilidade de ser rentável no futuro em determinados períodos de tempo.

Esse é um caso perfeito. Mas o que devemos fazer se um EA com uma lógica operacional aparentemente bastante racional parece perdido e gerando perdas em metade dos casos de testes de simulação? Na verdade, estratégias baseadas na seleção de parâmetros de EA dentro de cada otimização separadamente não é o único método possível. É mais interessante conduzir análises estatísticas e comparar parâmetros de EA de diferentes otimizações.

Adicionalmente, otimizações nos testes de simulação tomam muito tempo e não é razoável conduzir essas operações somente para o propósito dos testes de simulação. Por exemplo, junto das otimizações podemos salvar resultados de execuções de otimizações rentáveis em um arquivo na forma de uma tabela que pode ser facilmente processada por meio de análise estatística de tabelas disponíveis em programas como o Microsoft Excel. O terminal do MetaTrader oferece a possibilidade de salvar os resultados de otimização no formato de uma tabela HTML:


que pode ser facilmente enviado para o Microsoft Excel. Mas para o processamento somente relatórios finais de cada execução de otimização são apresentados na forma de uma tabela. Parâmetros externos de um Expert Advisor não são inclusos na tabela:


Adicionalmente é o resultado de somente uma otimização. E para análise nós precisamos de resultados de todas as otimizações gravadas em um arquivo. Na verdade tudo isso pode ser implementado pelos recursos do MQL4, então nesse artigo eu gostaria de oferecer minha própria variação da solução.

Registrando resultados de otimização do EA na forma de uma tabela HTML em um arquivo

Para implementar tal registro em um arquivo, escrevi a seguinte função:

void Write_Param_htm
(
bool ToResolveWrite_Up, int Timeframe_Up, string ExtrVarblsNemes_Up, string ExtrVarblsVelues_Up, 
bool ToResolveWrite_Dn, int Timeframe_Dn, string ExtrVarblsNemes_Dn, string ExtrVarblsVelues_Dn
)

Essa função permite que sejam registrados os resultados de execuções rentáveis de todas as otimizações realizadas para um par, em somente um período de tempo e em uma direção de negociação. Essa função chamada é colocada no bloco de deinicialização do EA (dentro da função deinit()):

int deinit()
{
//----+
//---- Recording EA parameters into a text file
if (IsOptimization())
{ 
//---- +------------------------------------------+
//Here is the code of external variables initialization of the Write_Param_htm() function
//---- +------------------------------------------+
//---- RECORDING STRINGS INTO A HTML FILE
Write_Param_htm(Test_Up, Timeframe_Up, ExtVarNemes_Up, ExtVarVelues_Up, Test_Dn, Timeframe_Dn, 
ExtVarNemes_Dn, ExtVarVelues_Dn);
//----+ +-------------------------------------------------------+
}
//---- End of the EA deinitialzation
return(0);
//----+ 
}

Essa função escreve três arquivos na pasta C:\, dois arquivos de resultados de otimização (para posições longas e curtas, correspondentemente) e um arquivo de texto (MetaTraderTester.log), no qual os caminhos e nomes destes dois arquivos são escritos. Os nomes dos dois arquivos se parecem com esse (OptReport_Exp_5_2_GBPUSD_240_Long.htm):


A função Write_Param_htm() está inclusa no arquivo pela diretiva:

#include <TestReport.mqh>

que deve ser feita de modo melhor antes da declaração das variáveis externas do EA. Além desta função, o arquivo TestReport.mqh contém outras funções que são usadas no código da função Write_Param_htm(); Explicarei o significado delas posteriormente. O arquivo também contém a função já conhecida IsBackTestingTime() com variáveis externas para testes de simulação (a função foi descrita no artigo anterior). A chamada da função deve ser feita no bloco da função start():

//----+ Execution of backtesting conditions
if (!IsBackTestingTime())
return(0);

Então, o uso mais simples do arquivo TestReport.mqh é absolutamente análogo ao uso do arquivo IsBackTestingTime.mqh do artigo anterior, mas nesse caso durante a compilação do EA todas as outras funções do EA não serão usadas. Como parâmetros externos nas funções Write_Param_htm() oito variáveis são usadas. Essas variáveis podem ser divididas em dois grupos: para registrar em um arquivo os resultados da otimização do EA com posições longas terminando em _Up e para gravar em um arquivo com as posições curtas terminando em _Dn.

Vamos analisar um grupo, o segundo é análogo. O parâmetro ToResolveWrite_Up passa para a função a permissão ou proibição para registrar no arquivo. O parâmetro Timeframe_Up passa o período de tempo no qual o algoritmo longo do EA funciona. O parâmetro ExtrVarblsNemes_Up passa para a função uma linha consistindo de nomes dos parâmetros externos do EA para posições longas. Do mesmo modo o parâmetro ExtrVarblsVelues_Up é usado para passar uma linha que consiste de valores dos parâmetros externos do EA para posições longas.

Vamos discutir sobre a inicialização das duas últimas variáveis. Suponha que temos as seguintes variáveis para posições longas:

n_ExternParam_1, n_ExternParam_2, d_ExternParam_3, n_ExternParam_4, b_ExternParam_5, d_ExternParam_6, 
d_ExternParam_7, n_ExternParam_8

O prefixo "n_" denota que o parâmetro é do tipo integral "d_" que significa que um parâmetro é do tipo duplo, "b_" - do tipo booleano. Antes da inicialização do ExtrVarblsNemes_Up eExtrVarblsVelues_Up, um par de variáveis de linha adicionais deve ser declarado e inicializado por partes de código html:

string n_Width = "</td><td><center>";
string d_Width = "</td><td class=mspt><center>";

Após isso podemos montar as linhas necessárias. Para a variável externa ExtrVarblsNemes_Up esse código se parecerá com isso:

ExtVarNemes_Up =
StringConcatenate
(
n_Width, "n_ExternParam_1", 
n_Width, "n_ExternParam_2", 
n_Width, "d_ExternParam_3", 
n_Width, "n_ExternParam_4", 
n_Width, "b_ExternParam_5", 
n_Width, "d_ExternParam_6", 
n_Width, "d_ExternParam_7", 
n_Width, "n_ExternParam_8"
);

A inicialização da variável externa ExtVarVelues_Up é um pouco mais complicada:

ExtVarVelues_Up = 
StringConcatenate
(
n_Width, n_ExternParam_1, 
n_Width, n_ExternParam_2, 
d_Width, d_ExternParam_3, 
n_Width, n_ExternParam_4, 
n_Width, b_ExternParam_5, 
d_Width, d_ExternParam_6, 
d_Width, d_ExternParam_7, 
n_Width, n_ExternParam_8
);

Nesse código antes dos parâmetros externos do EA, a variável d_Width é sempre colocada, antes de todos os outros parâmetros n_Width serem escritos. Em tal disposição da última linha todos os parâmetros do tipo duplo serão passados para a função Write_Param_htm() com quatro sinais após um ponto decimal. Se outra quantidade de sinais for necessária, use a seguinte função:

DoubleToStr( double value, int digits)

Note que essas linhas não podem conter mais do que 255 símbolos. Se o tamanho for maior do que isso, símbolos em excesso serão omitidos e o compilador mostrará um alerta correspondente. Há somente uma maneira para sair dessa situação: no ExtVarNemes_Up nomes de variáveis externas devem ser encurtados, em ExtVarVelues_Up o número de variáveis para montagem da linha deve ser cortado. Mas para a maioria das tarefas 255 símbolos são mais do que suficientes>

Aqui está a variante da implementação do registro em um arquivo HTML no exemplo de Exp_5_2.mq4:

//+==================================================================+
//| expert deinitialization function |
//+==================================================================+ 
int deinit()
{
//----+
//---- Recording EA parameters into a text file
if (IsOptimization())
{
string ExtVarNemes_Up, ExtVarVelues_Up;
string ExtVarNemes_Dn, ExtVarVelues_Dn, n_Width, d_Width;

//---- INITIALIZATION OF STRINGS FOR THE Write_Param_htm FUNCTION
//----+ +-------------------------------------------------------+ 
n_Width = "</td><td><center>";
d_Width = "</td><td class=mspt><center>";
//---- 
ExtVarNemes_Up =
StringConcatenate( 
n_Width, "IndLevel_Up",
n_Width, "FastEMA_Up",
n_Width, "SlowEMA_Up",
n_Width, "SignalSMA_Up",
n_Width, "STOPLOSS_Up",
n_Width, "TAKEPROFIT_Up",
n_Width, "TRAILINGSTOP_Up",
n_Width, "PriceLevel_Up",
n_Width, "ClosePos_Up");

ExtVarVelues_Up = 
StringConcatenate(
d_Width, DoubleToStr(IndLevel_Up, Digits), // 9
n_Width, FastEMA_Up, // 10
n_Width, SlowEMA_Up, // 11
n_Width, SignalSMA_Up, // 12
n_Width, STOPLOSS_Up, // 13
n_Width, TAKEPROFIT_Up, // 14
n_Width, TRAILINGSTOP_Up, // 15
n_Width, PriceLevel_Up, // 16
n_Width, ClosePos_Up); // 17 
//----+ +-------------------------------------------------------+
ExtVarNemes_Dn =
StringConcatenate( 
n_Width, "IndLevel_Dn",
n_Width, "FastEMA_Dn",
n_Width, "SlowEMA_Dn",
n_Width, "SignalSMA_Dn",
n_Width, "STOPLOSS_Dn",
n_Width, "TAKEPROFIT_Dn",
n_Width, "TRAILINGSTOP_Dn",
n_Width, "PriceLevel_Dn",
n_Width, "ClosePos_Dn"); 

ExtVarVelues_Dn = 
StringConcatenate(
d_Width, DoubleToStr(IndLevel_Dn, Digits), // 9
n_Width, FastEMA_Dn, // 10
n_Width, SlowEMA_Dn, // 11
n_Width, SignalSMA_Dn, // 12
n_Width, STOPLOSS_Dn, // 13
n_Width, TAKEPROFIT_Dn, // 14
n_Width, TRAILINGSTOP_Dn, // 15
n_Width, PriceLevel_Dn, // 16
n_Width, ClosePos_Dn); // 17 

//---- RECORDING STRINGS INTO HTML FILE
Write_Param_htm
(Test_Up, Timeframe_Up, ExtVarNemes_Up, ExtVarVelues_Up, 
Test_Dn, Timeframe_Dn, ExtVarNemes_Dn, ExtVarVelues_Dn);
//----+ +-------------------------------------------------------+
}
//---- End of the EA deinitialization
return(0);
//----+ 
}

Aqui está a tabela HTML resultante de parâmetros para esse EA aberto no Microsoft Excel:


A tabela contém resultados de todas as otimizações conduzidas. A tabela em si tem o seguinte formato (as primeiras oito colunas contém os resultados de negociações do EA):

Note que os parâmetros Drawdown $ and Drawdown % (Perda $ e Perda %) são calculados somente para negociações concluídas, é por isso que elas serão diferentes destas disponíveis em um testador de estratégia. Também, leve em consideração que o parâmetro 'Fator de Rentabilidade' somente faz sentido se existe pelo menos uma negociação com perda, não fazendo sentido se não existiam negociações com perda. Inicialmente a tabela não contém negociações com perdas, é por isso que para essas situações sem perdas eu defini esse parâmetro igual a zero.

Para a direita dos resultados de negociação do EA existem parâmetros otimizados do EA:

Assim temos na forma de uma tabela todos os valores necessários de cada execução da otimização e todas as otimizações ao mesmo tempo. Isso permite deixar algum tempo para que o testador e o terminal conduzam análises estatísticas com base na informação contida em um arquivo html utilizando meios bem eficientes disponíveis nos analisadores atualizados do programa, do conteúdo da tabela.

Mais uma coisa. O arquivo html descrito registrado dessa maneira terá um código html incompleto devido à adição constante de dados no arquivo. Se você não for adicionar dados no arquivo depois, as linhas a seguir devem ser escritas no fim do código html (abra-o com um editor de texto):

</table>
</body></html>

Algumas explicações do conteúdo do TestReport.mqh

Esse arquivo que eu usei para escrever o código MQL4 fornecendo a exportação de dados em tabelas HTML contém muitas funções universais definidas pelo usuário. Essas funções em um formato pronto podem ser úteis para qualquer escritor de EA, então eu gostaria de considerar essas funções em detalhes:

O arquivo começa com a declaração de variáveis externas para testes de simulação e o IsBackTestingTime() descrito no artigo anterior. Após isso vai a declaração de uma função especializada CountTime() que é usada em algumas funções do arquivo, mas dificilmente será usada por um leitor.

A diretiva

#include <Read_Write_File.mqh>

inclui no arquivo TestReport.mqh o conteúdo do arquivo Read_Write_File.mqh: importação das funções para registro e leitura de arquivos em qualquer pasta dos módulos do sistema operacional Windows:

#include <WinUser32.mqh>
#import "kernel32.dll"
int _lopen (string path, int of);
int _lcreat (string path, int attrib);
int _llseek (int handle, int offset, int origin);
int _lread (int handle, int& buffer[], int bytes);
int _lwrite (int handle, string buffer, int bytes);
int _lclose (int handle);
#import

O significado do uso dessa função pode ser entendido a partir do código de quatro funções universais definidas pelo usuário contidas nesse arquivo:

int _FileSize
(
string path
)

bool WriteFile 
(
string path, string buffer
) 

bool ReadFile
(
string path, string&amp;amp; StrBuffer[]
)

SpellFile
(
string path, string&amp; SpellBuffer[]
)

Essas funções contém o caminho da variável que introduz uma linha contendo um caminho para um arquivo de texto e seu nome.

A função _FileSize() retorna o tamanho do arquivo em bytes.

A função WriteFile() registra no fim do arquivo o conteúdo da linha 'buffer'. Se você quiser que cada linha seja escrita a partir de uma nova linha, adicione "\n" no fim de cada linha:

buffer = buffer + "\n";

A função ReadFile() muda o tamanho da linha de buffer StrBuffer[] e envia para ela o conteúdo do arquivo por linhas que consistem de quatro letras dentro de uma célula de buffer.

A função SpellFile() muda o tamanho da linha de buffer e envia o conteúdo do arquivo letra por letra.

Após a diretiva #include no arquivo TestReport.mqh há um grupo de funções universais definidas pelo usuário, usadas para calcular os ditos parâmetros de otimização,

CountProfit(int cmd) 
CountMaxDrawdownPrs(int cmd) 
CountMaxDrawdown(int cmd) 
CountAbsDrawdown(int cmd) 
CountProfitFactor(int cmd) 
CountProfitTrades(int cmd) 
CountTotalTrades(int cmd) 
CountExpectedPayoff(int cmd)

que são análogas a estas que aparecem na aba "Resultados de Otimização" de um Testador de Estratégia. Estas funções fazem cálculos somente baseados em dados de negociações concluídas, é por isso que as funções CountMaxDrawdownPrs(), CountMaxDrawdown(), CountAbsDrawdown() retornam seus valores de modo diferente destas obtidas em um testador de estratégia. Se a variável 'cmd' aceita o valor OP_BUY, cálculos em todas as funções são conduzidos somente para posições longas fechadas, se OP_SELL - para posições curtas fechadas. Qualquer outro valor dessa variável fornece cálculos para todas as outras operações de negociação fechadas.

Após essas funções, mais quatro outras funções são declaradas no arquivo - para registrar os resultados de otimização e parâmetros otimizados nos arquivos:

void Write_Param_htm
(
bool ToResolveWrite_Up, int Timeframe_Up, string ExtrVarblsNemes_Up, string ExtrVarblsVelues_Up, 
bool ToResolveWrite_Dn, int Timeframe_Dn, string ExtrVarblsNemes_Dn, string ExtrVarblsVelues_Dn
)

void Write_Param_1htm
(
int Timeframe, string ExtrVarblsNemes, string ExtrVarblsVelues
)

void Write_Param_txt
(
bool ToResolveWrite_Up, int Timeframe_Up, string ExtrVarblsVelues_Up,
bool ToResolveWrite_Dn, int Timeframe_Dn, string ExtrVarblsVelues_Dn
)

void Write_Param_1txt
(
int Timeframe, string ExtrVarblsVelues
)

E quanto ao Write_Param_htm(), ele é descrito acima.

A função Write_Param_1htm() é totalmente análoga à função anterior, mas é criada para Expert Advisors, nos quais os parâmetros externos não são divididos nestes para posições longas e curtas. A função ToResolveWrite não é necessária aqui e é por isso que foi excluída.

A função Write_Param_txt() é análoga à de Write_Param_htm(), ela registra os mesmos dados mas sem a indicação html. A variável adicional para montar uma linha consistindo de resultados de otimização e parâmetros de otimização é inicializada da seguinte forma:

Width = " ";

Cada nova linha é registrada no arquivo a partir de uma nova linha, no fim de cada linha no arquivo de texto ";" é escrito. Entre os valores de variáveis externas de uma linha os espaços são escritos no arquivo de texto.

A função Write_Param_1txt() é totalmente análoga à função anterior Write_Param_txt(), mas é criada para Expert Advisors, nos quais os parâmetros externos não são divididos nestes para posições longas e curtas.

E as duas últimas funções

void Write_Param_htm_B
(
bool ToResolveWrite_Up, int Timeframe_Up, string ExtrVarblsNemes_Up, string ExtrVarblsVelues_Up, 
bool ToResolveWrite_Dn, int Timeframe_Dn, string ExtrVarblsNemes_Dn, string ExtrVarblsVelues_Dn
)

void Write_Param_1htm_B
(
int Timeframe, string ExtrVarblsNemes, string ExtrVarblsVelues
)

são totalmente análogas de Write_Param_htm() e Write_Param_1htm(), mas arquivos html recebidos com sua ajuda possuem coloração inversa. Aqui está um exemplo:

Provavelmente, existem pessoas que preferem trabalhar com estes arquivos. Eu pessoalmente gosto desse tipo de apresentação da informação.

Sistema de negociação parabólica


O indicador de funcionamento desse sistema está incluso em todas as plataformas populares de negociação para trabalhar com os mercados de ações e Forex.

Aqui introduzirei um sistema com pedidos pendentes do tipo BuyLimit e SellLimit.

Aqui está uma variante de implementação de algoritmo para BuyLimit:


A variante do algoritmo para pedidos SellLimit será análoga:

Aqui está a implementação para o código do programa para um Expert Advisor:

//+==================================================================+
//|                                                        Exp_8.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR BUY TRADES 
extern bool   Test_Up = true;//filter of trade calculations direction
extern int    Timeframe_Up = 240;
extern double Money_Management_Up = 0.1;
extern double Step_Up = 0.02; 
extern double Maximum_Up = 0.2;
extern int    STOPLOSS_Up = 50;  // stop loss
extern int    TAKEPROFIT_Up = 100; // take profit
extern int    TRAILINGSTOP_Up = 0; // trailing stop
extern int    PriceLevel_Up =40; // difference between the current price and
                          // pending order triggering price
extern bool   ClosePos_Up = true; // forced position closing 
                                              //is allowed
//----+ +------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR SELL TRADES 
extern bool   Test_Dn = true;//filter of trade calculations direction
extern int    Timeframe_Dn = 240;
extern double Money_Management_Dn = 0.1;
extern double Step_Dn = 0.02; 
extern double Maximum_Dn = 0.2;
extern int    STOPLOSS_Dn = 50;  // stop loss
extern int    TAKEPROFIT_Dn = 100; // take profit
extern int    TRAILINGSTOP_Dn = 0; // trailing stop
extern int    PriceLevel_Dn = 40; // difference between the current price and 
                          // pending order triggering price
extern bool   ClosePos_Dn = true; // forced position closing
                                              //is allowed
//----+ +------------------------------------------------------------+
//---- Integer variables for the minimum of calculation bars
int MinBar_Up, MinBar_Dn;
//+==================================================================+
//| TimeframeCheck() functions                                       |
//+==================================================================+
void TimeframeCheck(string Name, int Timeframe)
  {
//----+
   //---- Checking the correctness of Timeframe variable value
   if (Timeframe != 1)
    if (Timeframe != 5)
     if (Timeframe != 15)
      if (Timeframe != 30)
       if (Timeframe != 60)
        if (Timeframe != 240)
         if (Timeframe != 1440)
           Print(StringConcatenate("Parameter ",Name,
                     " cannot ", "be equal to ", Timeframe, "!!!"));    
//----+ 
  }
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| Custom Expert initialization function                            |
//+==================================================================+
int init()
  {
//---- Checking the correctness of Timeframe_Up variable value
   TimeframeCheck("Timeframe_Up", Timeframe_Up);                                                          
//---- Checking the correctness of Timeframe_Dn variable value 
   TimeframeCheck("Timeframe_Dn", Timeframe_Dn);  
//---- Initialization of variables             
   MinBar_Up  = 5;
   MinBar_Dn  = 5;                               
//---- end of initialization
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- End of the EA deinitialization
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Declaring local variables
   double SAR1, SAR2, CLOSE1, CLOSE2;
   //----+ Declaring static variables
   //----+ +---------------------------------------------------------------+
   static datetime StopTime_Up, StopTime_Dn; 
   static int LastBars_Up, LastBars_Dn;
   static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop;
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR LONG POSITIONS 1
   if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      
      if (IBARS_Up >= MinBar_Up)
       {
         if (LastBars_Up != IBARS_Up)
          {
           //----+ Initialization of variables 
           BUY_Sign = false;
           BUY_Stop = false;
           LastBars_Up = IBARS_Up;
           StopTime_Up = iTime(NULL, Timeframe_Up, 0)
                                           + 60 * Timeframe_Up;
           
           //----+ CALCULATING INDICATOR VALUES AND UPLOADING THEM TO BUFFERS                                        
           SAR1 = iSAR(NULL, Timeframe_Up, Step_Up, Maximum_Up, 1);         
           SAR2 = iSAR(NULL, Timeframe_Up, Step_Up, Maximum_Up, 2);
           //---
           CLOSE1 = iClose(NULL, Timeframe_Up, 1);
           CLOSE2 = iClose(NULL, Timeframe_Up, 2);
           
           //----+ DEFINING SIGNALS FOR TRADES                                           
           if (SAR2 > CLOSE2)
             if (SAR1 < CLOSE1)
                          BUY_Sign = true;
                          
           if (SAR1 > CLOSE1)
                          BUY_Stop = true;                                           
          }
          //----+ EXECUTION OF TRADES
          if (PriceLevel_Up == 0)
           {           
            if (!OpenBuyOrder1(BUY_Sign, 1, 
                Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up))
                                                                return(-1);
           }
          else
           {           
            if (!OpenBuyLimitOrder1(BUY_Sign, 1, 
                Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up,
                                            PriceLevel_Up, StopTime_Up))
                                                                return(-1);
           }
           
          if (ClosePos_Up)
                if (!CloseOrder1(BUY_Stop, 1))
                                        return(-1);
                                        
          if (!Make_TreilingStop(1, TRAILINGSTOP_Up))
                                                  return(-1);
        }
     }
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR SHORT POSITIONS 1
   if (Test_Dn) 
    {
      int IBARS_Dn = iBars(NULL, Timeframe_Dn);
      
      if (IBARS_Dn >= MinBar_Dn)
       {
         if (LastBars_Dn != IBARS_Dn)
          {
           //----+ Initialization of variables 
           SELL_Sign = false;
           SELL_Stop = false;
           LastBars_Dn = IBARS_Dn;
           StopTime_Dn = iTime(NULL, Timeframe_Dn, 0)
                                           + 60 * Timeframe_Dn;
           
           //----+ CALCULATING INDICATOR VALUES AND UPLOADING THEM TO BUFFERS                                        
           SAR1 = iSAR(NULL, Timeframe_Dn, Step_Dn, Maximum_Dn, 1);         
           SAR2 = iSAR(NULL, Timeframe_Dn, Step_Dn, Maximum_Dn, 2);
           //---
           CLOSE1 = iClose(NULL, Timeframe_Dn, 1);
           CLOSE2 = iClose(NULL, Timeframe_Dn, 2);
           
           //----+ DEFINING SIGNALS FOR TRADES                                           
           if (SAR2 < CLOSE2)
             if (SAR1 > CLOSE1)
                          SELL_Sign = true;
                          
           if (SAR1 < CLOSE1)
                          SELL_Stop = true;                                           
          }
          //----+ EXECUTION OF TRADES
          if (PriceLevel_Dn == 0)
           {           
            if (!OpenSellOrder1(SELL_Sign, 2, 
                Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn))
                                                                return(-1);
           }
          else
           {           
            if (!OpenSellLimitOrder1(SELL_Sign, 2, 
                Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn,
                                            PriceLevel_Dn, StopTime_Dn))
                                                                return(-1);
           }
           
          if (ClosePos_Dn)
                if (!CloseOrder1(SELL_Stop, 2))
                                        return(-1);
                                        
          if (!Make_TreilingStop(2, TRAILINGSTOP_Dn))
                                                  return(-1);
        }
     }
   //----+ +---------------------------------------------------------------+
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

O bloco de execução da negociação é mais complicado neste EA. Aqui as funções para entrar no mercado OpenBuyOrder1() e OpenSellOrder1() e funções para colocar pedidos pendentes OpenBuyLimitOrder1() e OpenSellLimitOrder1() são usadas juntas. Isso é feito para o caso em que as variáveis externas PriceLevel_Up e PriceLevel_Dn são iguais a zero. Em tal situação o EA abrirá negociações do mercado, enquanto um EA trabalhando somente com pedidos pendentes fará esses pedidos na distância mínima do mercado.

Sistema de negociação por rompimento

Quanto a sistemas de negociação baseados em níveis de rompimento, existem muitos deles e você pode sempre inventar mais um sistema de rompimento. Nesse artigo vou descrever tal sistema, onde os níveis de rompimento são definidos pelos lados de um canal construído com base de um movimento:

O nível de rompimento será definido em barras fechadas. Além do mais, usarei um sistema de negociação de rompimento com algum rebote seguido do rompimento. Aqui está a variação desse sistema de negociação com pedidos BuyLimit:

O mesmo para SellLimit:

O código do EA não possui nenhuma peculiaridade de construção, é por isso que não o incluí nesse artigo. Você pode encontrar o código anexado ao EA (Exp_9.mq4). Não há fechamento forçado de posição no EA. Novas variáveis globais são inicializadas no bloco de inicialização do EA.

dMovLevel_Up = MovLevel_Up * Point;
dMovLevel_Dn = MovLevel_Dn * Point;

essas variáveis são usadas para calcular os valores dos níveis de UpMovLeve1 e DownMovLevel1.

Negociando em lançamentos de notícias

Muito frequentemente uma situação ocorre no mercado quando movimentos fortes ocorrem, invariavelmente em um, e ao mesmo tempo. É difícil dizer com antecedência e certeza em qual direção o movimento aparecerá. Mas podemos dizer antecipadamente que existirá este movimento. Por exemplo, tais movimentos fortes podem resultar de Folhas de Pagamento Não-Agrícola. Muitos investidores gostam de captar tais movimentos fortes. Seria interessante verificar se tal sistema de negociação é razoável. A ideia do sistema consiste em colocar duas ordens pendentes de tipo BuyStop e SellStop (Parar Compra e Parar Venda) e esperar até que um movimento forte de uma delas abra uma negociação e seja fechada por Take Profit (Obter Lucros):



Essa é mais uma variação de um sistema de ruptura. A implementação de tal sistema em um código de programa não é muito difícil:

//+==================================================================+
//|                                                       Exp_10.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR PLACING PENDING ORDERS
extern int    NewsWeekDay = 5;  // Weekday for news release
// if parameter is less than 1 or more than 5 any working day is used
extern int    NewsHour = 15;  // hour of news release
extern int    NewsMinute = 0;  // minute of news release
extern int    OrderLife = 30;  // Number of minutes of pending order validity
//----+ +------------------------------------------------------------+
//---- ea INPUT PARAMETERS FOR CLOSING POSITIONS
extern int    PosLife = 120;  // Number of minutes of an opened position validity
                                              //from news release time
//----+ +------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR BUY TRADES 
extern bool   Test_Up = true;//filter of trade calculations direction
extern double Money_Management_Up = 0.1;
extern int    STOPLOSS_Up = 50;  // stop loss
extern int    TAKEPROFIT_Up = 100; // take profit
extern int    TRAILINGSTOP_Up = 0; // trailing stop
extern int    PriceLevel_Up =40; // difference between the current price and
                          // the price of pending order triggering
extern bool   ClosePos_Up = true; // forced position closing
                                              //is allowed
//----+ +------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR SELL TRADES 
extern bool   Test_Dn = true;//filter of trade calculations direction
extern double Money_Management_Dn = 0.1;
extern int    STOPLOSS_Dn = 50;  // stop loss
extern int    TAKEPROFIT_Dn = 100; // take profit
extern int    TRAILINGSTOP_Dn = 0; // trailing stop
extern int    PriceLevel_Dn = 40; // difference between the current price and 
                          // the price of pending order triggering
extern bool   ClosePos_Dn = true; // forced position closing
                                              //is allowed
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| Custom Expert initialization function                            |
//+==================================================================+
int init()
  {
//---- 
    if (NewsHour > 23) 
             NewsHour = 23;
    if (NewsMinute > 59)
           NewsMinute = 59;                               
//---- end of initialization
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- End of the EA deinitialization
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Declaring static variables
   //----+ +---------------------------------------------------------------+
   static datetime StopTime, PosStopTime; 
   static bool BUY_Sign, SELL_Sign, BUY_Stop, SELL_Stop;
   //----+ +---------------------------------------------------------------+
   
   //----+ DEFINING SIGNALS FOR TRADES 
   if (DayOfWeek() == NewsWeekDay || NewsWeekDay < 1 || NewsWeekDay > 5)
     if (Hour() == NewsHour)
        if (Minute() == NewsMinute)
    {
     StopTime = TimeCurrent() + OrderLife * 60;
     PosStopTime = TimeCurrent() + PosLife * 60;
     BUY_Sign = true;
     SELL_Sign = true;
    }
    
    
    
   //----+ +---------------------------------------------------------------+ 
   //----++ CODE FOR LONG POSITIONS 1
   if (Test_Up) 
    {
      //----+ EXECUTION OF TRADES          
      if (!OpenBuyStopOrder1(BUY_Sign, 1, 
                Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up,
                                            PriceLevel_Up, StopTime))
                                                                return(-1);
      if (TimeCurrent() >= PosStopTime)                                                                    
          if (ClosePos_Up)
                if (!CloseOrder1(BUY_Stop, 1))
                                           return(-1);
                                        
      if (!Make_TreilingStop(1, TRAILINGSTOP_Up))
                                           return(-1);
     }
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR SHORT POSITIONS 1
   if (Test_Dn) 
     {
      //----+ EXECUTION OF TRADES
      if (!OpenSellStopOrder1(SELL_Sign, 2, 
                Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn,
                                            PriceLevel_Dn, StopTime))
                                                                return(-1);
      if (TimeCurrent() >= PosStopTime)            
          if (ClosePos_Dn)
                if (!CloseOrder1(SELL_Stop, 2))
                                           return(-1);
                                        
      if (!Make_TreilingStop(2, TRAILINGSTOP_Dn))
                                           return(-1);
     }
   //----+ +---------------------------------------------------------------+
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

Conclusão

Nesse artigo eu ofereci a você uma abordagem universal para exportar várias informações sobre resultados de otimização no formato de planilhas de trabalho, o que abre grandes oportunidades para análise profunda dessa informação e uma enorme melhoria nos resultados das negociações usadas pelos Expert Advisors nas negociações automatizadas. Espero que minha abordagem seja útil para qualquer escritor de EA.


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

Arquivos anexados |
EXPERTS.zip (13.19 KB)
INCLUDE.zip (22.68 KB)
indicators.zip (5.2 KB)
TESTER.zip (7.93 KB)
xtjmytfz9oqg.zip (161.41 KB)
Metalinguagem dos pedidos-linhas de gráfico. Trading e aprendizagem qualificada em trading Metalinguagem dos pedidos-linhas de gráfico. Trading e aprendizagem qualificada em trading
O artigo descreve uma linguagem simples e acessível de pedidos gráficos de trading compatíveis com análises técnicas tradicionais. O Gterminal em anexo é um Expert Advisor semiautomatizado usado em resultados de trading de análises gráficas. Melhor usado para autoaprendizagem e treinamento de traders iniciantes.
Diagnósticos de mercado por pulso Diagnósticos de mercado por pulso
Nesse artigo, faremos uma tentativa de visualizar a intensidade de mercados específicos e seus segmentos de tempo para detectar as regularidades e padrões de comportamento.
Expert Advisors baseado em sistemas de trading populares e alquimia da otimização de robô de trading (Parte V) Expert Advisors baseado em sistemas de trading populares e alquimia da otimização de robô de trading (Parte V)
Nesse artigo o autor oferece formas para melhorar os sistemas de trading descritos nos artigos anteriores. O artigo será interessante para traders que já tem alguma experiência em escrever Expert Advisors.
Expert Advisors baseado em sistemas de trading populares e alquimia da otimização de robô de trading (Parte III) Expert Advisors baseado em sistemas de trading populares e alquimia da otimização de robô de trading (Parte III)
Nesse artigo o autor continua a analisar algoritmos de implementação dos sistemas de negociação mais simples e introduz a automação de simulações. O artigo será útil para investidores iniciantes e desenvolvedores de EA.