Desenvolvendo um algoritmo auto-adaptável (Parte II): melhorando a eficiência

26 março 2021, 13:24
Maxim Romanov
1
534

Introdução

Antes de começar a estudar este artigo, recomendo que você leia o primeiro artigo "Desenvolvendo um algoritmo auto-adaptável (Parte I): encontrando um padrão básico". Isso não é necessário, o objetivo principal ficará claro, mas será mais interessante dessa forma.

No artigo anterior, encontramos um padrão simples e desenvolvemos um algoritmo muito simples para explorá-lo. Porém, este último não tem uma estrutura flexível e não faz sentido esperar nenhum resultado notável, uma vez que ele funciona bem.

Devemos melhorá-lo significativamente para que se torne flexível e ajuste seus parâmetros de operação dependendo da situação do mercado e, assim, tenhamos melhores resultados e maior estabilidade.

Análise de falhas

Precisamos começar a desenvolver um novo algoritmo, analisando as deficiências da versão anterior. Eu destaquei as seguintes lacunas:

  • Os sinais para abrir uma série são gerados muito raramente. O aprimoramento da qualidade do sinal reduz bastante o número de sinais para entrar e o lucro geral;
  • Uma janela de amostragem fixa é tomada para análise. Imaginemos que as amostras sejam dadas por um intervalo, nesse caso, analisar uma amostra de tamanho fixo não é uma solução muito eficaz. O mercado não é uma onda senoidal e as "caudas" afetam a qualidade do sinal atual. Os limites da amostragem não devem ser claros e influenciar a decisão final. A grosso modo, na versão anterior, foram retirados 100 candles e analisada a preponderância dos que crescem e decrescem. Se a preponderância ultrapassava o limite, um sinal de entrada era gerado. A amostra não deve ser fixa, mas, sim, dinâmica. Era necessário verificar não apenas qual situação estava na janela de análise, mas também o que estava fora da janela de análise;
  • O problema de uma janela de análise fixa não é comum a todos os métodos conhecidos;
  • A porcentagem limite tem um valor fixo para cada amostra, independentemente do número de candles nela. Esta solução é ineficaz, porque a probabilidade de uma preponderância de 75% numa amostra de 30 candles e numa de 200 candles está longe de ser a mesma, pois ela diminui de forma não linear com o aumento do número de candles na amostra;
  • A abertura de posições em cada candle é muito dispendiosa e leva ao aumento no rebaixamento. Muitas posições são abertas com frequência, e é necessário reduzir o número de posições abertas na série. Isso aumentará a eficiência do uso de capital;
  • O fechamento de posições com lucro fixo por lote reduz a estabilidade ou a lucratividade. Precisamos encontrar um meio-termo entre estabilidade e lucratividade num mercado em constante mudança. Se este parâmetro não for ajustado, o robô logo sofrerá uma perda, simplesmente porque perderá o ponto de fechamento ideal para uma série de posições;
  • A restrição inflexível do número de instrumentos para negociação simultânea reduz a lucratividade geral do sistema. Os sinais para a abertura de séries em diferentes instrumentos estão ligeiramente correlacionados entre si, portanto, uma perda para um instrumento pode estar correlacionada com uma perda para outro instrumento. É necessário desenvolver medidas para reduzir a correlação de sinais de forma que o número de instrumentos operados simultaneamente possa ser significativamente aumentado sem um aumento significativo no tamanho do rebaixamento.

Algoritmo de trabalho simplificado

Gostaria de lembrar como a primeira versão do algoritmo funcionava de forma simplificada. Na nova versão, o objetivo permanecerá o mesmo, mas cada etapa será revisada e aprimorada.

  • é examinada uma janela de N candles; 
  • é verificado quais candles estão maiores, quais são decrescentes ou crescentes;
  • se a preponderância for maior que o limite, este será o sinal para o início de uma série de posições;
  • mais candes decrescentes = sinal Buy, mais candles crescentes = Sell;
  • é calculado o lote;
  • é aberta uma nova posição a cada próximo candle até que a condição para o fechamento da série seja acionada; 
  • é atendida a condição de fechamento da série;
  • são fechadas todas as posições;
  • busca de um novo sinal.

Modernização

O robô foi desenvolvido em 2016 e foi criado para MetaTrader 4, portanto, irei anexar no final do código para este terminal.

Durante o desenvolvimento, é necessário eliminar todas as falhas identificadas, por isso dividirei todo o desenvolvimento em pontos.

  1. Porcentagem dinâmica limite do início da série

O algoritmo da primeira versão se tornou mais estável com o aumento no número de candles na janela de análise ou com o aumento no valor limite da porcentagem a nível de preponderância de candles decrescentes ou crescentes. Tivemos que fazer concessões e definir um tamanho de amostra maior para análise ou uma porcentagem maior de preponderância de candles prevalecentes. Os testes mostraram que é possível configurar uma porcentagem ótima a nível de preponderância para quase qualquer número de candles, mas para cada número maior de candles ela deve diminuir.

Com uma porcentagem limite fixa, com um aumento no número de candles na janela de análise, a probabilidade de aparecer tal combinação diminui. Por isso, o valor máximo de candles na janela de análise pode ser definido por qualquer pessoa, isso praticamente não afeta o resultado simplesmente pelo fato de que a probabilidade de encontrar tal combinação cai rapidamente. Para que haja mais sinais no início da série, é necessário reduzir a porcentagem limite da preponderância com o aumento do número de candles na amostra, para que a probabilidade de aparecimento de uma combinação permaneça aproximadamente a mesmo.

Supõe-se que a probabilidade de uma determinada porcentagem de preponderância para um determinado número de candles pode ser calculada usando combinatória.

CP,

Onde

  • С - número de combinações
  • n - número de candles na amostra
  • k - número de candles crescentes
  • P - probabilidade de o evento ocorrer
  • P2 - dobro da probabilidade de um evento ocorrer

A probabilidade do evento P deve ser multiplicada por 2, pois P é calculado para o caso em que há mais candles na mesma direção, quer para baixo quer para cima. Estamos interessados na probabilidade geral, independentemente da direção. Não precisamos multiplicar a probabilidade por 2 apenas se o número de candles decrescentes = o número de candles crescentes.

Por exemplo, vamos calcular a probabilidade de um evento ocorrer quando de 30 candles houver 24 candles numa direção e 6 em outra. Para fazer isso, fiz uma tabela na Figura 1 abaixo.

probability table

Fig. 1. Tabela de probabilidade

24 candles de uma direção em 30 correspondem a 80% de preponderância. A probabilidade de tal combinação é de 0,11%. Agora, vou comparar, usando a tabela, qual porcentagem de preponderância deveria ter sido para 100 candles na amostra, de modo que sua probabilidade de ocorrência fosse 0,11%. Não existe tal probabilidade de ocorrência de combinações para 100 candles. Existe uma probabilidade de ocorrência de 0,172% e 0,091%. Vou escolher uma variante mais rara, que corresponde à proporção de um tipo de candle em relação a outro, como 66/34 ou 66% dos candles numa direção.

É claro que combinações para 30 candles com uma margem de 80% de candles descendentes ou crescentes ocorrerão tão frequentemente quanto uma combinação de 100 candles com uma margem de 66%. A dependência da porcentagem de preponderância em relação ao número de candles não é linear, portanto, para ajustar a porcentagem com um aumento no número de candles, deve ser aplicada uma função não linear. Desenvolvi essa função:

Nonliner proc

Onde:

  • Nb - número de candles na amostra.
  • Koef_NonLiner_proc - coeficiente das configurações necessário para ajustar a porcentagem limite.

Vejamos o gráfico da Figura 2 sobre como a porcentagem de preponderância (com uma probabilidade estática de uma combinação cair) diminui com um aumento no número de candles usando o método combinatório e quão adequada é a função desenvolvida.

Chart function

Fig. 2.

A Figura 2 mostra em roxo um gráfico de uma diminuição na porcentagem de preponderância com um aumento no número de candles na amostra e uma probabilidade fixa de tal combinação. O gráfico da função desenvolvida de diminuição da porcentagem de preponderância a partir do número de candles na amostra é mostrado em vermelho. Pode-se observar que ambas as funções são não lineares, mas a função desenvolvida decai mais lentamente. Isso é feito propositalmente porque quanto mais candles na amostra, mais posições na série podem ser abertas ao retornar para 50%. Mais posições significam mais carga no depósito e mais rebaixamento. 

Isso foi feito especialmente para que com um número maior de candles o sinal apareça com menos frequência e somente se a porcentagem de preponderância for realmente alta para um determinado número de candles.

2. Melhorando a qualidade do sinal

Para melhorar a qualidade do sinal, a amostra não deve consistir num número inflexivelmente fixo de candles. Vemos uma preponderância de candles crescentes de 65% em 30 candles, mas isso é muito ou pouco? Se houver algum tipo de preponderância de candles ascendentes em 100 candles, esse fato deve tornar o sinal mais forte, mas se não houver preponderância ou, inversamente, houver uma preponderância de candles decrescentes, então o sinal deve ser enfraquecido. Desenvolvi 2 mecanismos para aumentar ou atenuar o sinal.

a) Usar uma porcentagem média ponderada é a primeira variante para melhorar a qualidade do sinal. Encontramos a porcentagem média ponderada para todas as amostras do intervalo especificado nas configurações "Min_diap_bar" e "Max_diap_bar". As amostras precisam ser feitas com algum incremento, eu prefiro um incremento par = 2. A porcentagem média ponderada será determinada para o tipo de candle que estiver em maior quantidade na primeira amostra. Se houver mais candles crescentes na primeira amostra, então, em todas as outras, deve ser contada a porcentagem de candles crescentes. A primeira amostra pode ser a maior ou a menor amostra. Para isso, a opção "Bigin_pereb_bar" foi adicionada às configurações. Os coeficientes corretores podem ser feitos usando qualquer função, mas eu os tornei proporcionais ao número de candles na amostra. 

Se a primeira amostra tiver o menor número de candles, seu coeficiente corretor será W1; para a segunda amostra, o coeficiente corretor será W2 e assim por diante até Wn.

weighted average

  • W1 - coeficiente corretor da primeira amostra;
  • W2 - coeficiente corretor da segunda amostra;
  • Wn - coeficiente corretor n da amostra;
  • Nb1 - número de candles da primeira amostra;
  • Nbn - número de candles n da amostra;
  • Pw - porcentagem média ponderada da preponderância dos candles;
  • P1 - porcentagem de candles decrescentes/crescentes da primeira amostra;
  • Pn - porcentagem de candles decrescentes/crescentes da amostra n;
  • Nbm - número de candles na maior amostra.

Se a primeira amostra tiver o maior número de candles, os pesos precisarão ser invertidos

 inverted weights
Para receber um sinal no início da série, a porcentagem média ponderada deve ser comparada com um valor separado especificado na configuração "Porog_Weighted_proc".

b) Usar a amostragem de conjunto é a segunda variante para melhorar a qualidade do sinal. A partir do intervalo, precisamos coletar várias amostras cuja preponderância possui mais um tipo de candle do que o limite. Aqui, assumiremos que quanto maior o número de amostras, para as quais a porcentagem de preponderância é maior que o limite, maior é a qualidade do sinal. Uma porcentagem não linear será usada como uma porcentagem não linear. Ou seja, para cada amostra com seu próprio número de candles, deve ser usado seu próprio limite de porcentagem de preponderância.
Na configuração "Kol_vibor", irei definir o número mínimo de amostras nas quais a preponderância deve ser maior que o limite. O tipo de candles para as que a porcentagem de preponderância será determinada dependerá de qual tipo de candles prevalece na primeira amostra. Neste caso, para a primeira amostra, é tomada aquela cuja preponderância está acima do limite. Tornei possível iterar no intervalo do menor ao maior e vice-versa para comparar como funcionaria melhor.
Essa técnica ajuda a levar em consideração o sinal numa janela mais ampla e não nos amarrar a uma janela de análise fixa. Por exemplo, o intervalo da janela de análise é definido de 30 a 300 candles com um incremento de 2 e, para gerar um sinal, precisamos coletar pelo menos 5 amostras deste intervalo com uma preponderância maior que o limite. A preponderância pode ser gerada para 30, 52, 100, 101, 200 candles. Além disso, cada amostra é comparada com sua própria porcentagem limite, uma vez que está sendo usada uma porcentagem não linear. Isso torna mais eficiente avaliar o que acontece dentro da ampla faixa do número de candles e não há vinculação a um valor fixo.

Price Chart

Fig. 3.

A Figura 3 mostra esquematicamente um exemplo. Pode-se observar que existe uma área em que os candles ascendentes prevalecem e há um sinal para abrir posições Sell. Embora este não seja um número claro de candles, é uma área.  

No primeiro artigo, escrevi que o número de candles (e, consequentemente, o número de posições na série) para o qual a preponderância resultante teoricamente será compensada é calculado com base no número de candles com que surgiu. Graças a essa abordagem, são dados os primeiros passos para o surgimento da auto-adaptação. O algoritmo ainda está longe de se auto-adaptar, mas o uso das características atuais do mercado para um pequeno ajuste dos parâmetros operacionais já o aproxima do objetivo.
Um algoritmo ideal não deve conter parâmetros ajustáveis, cada parâmetro deve ser calculado com absoluta precisão com base nas características atuais do mercado. Precisamos saber exatamente que parâmetros de trabalho devem ser definidos a cada momento para que o algoritmo permaneça lucrativo.
3. Diminuição do número de posições abertas na série

Havia um problema na primeira versão do algoritmo: quando a série começava, o robô abria posições em cada candle. Esta abordagem não é muito eficaz e causa grandes rebaixamentos, aumenta os requisitos para o depósito. Muitas vezes houve situações em que as posições eram abertas, mas a porcentagem de preponderância na amostra continuou a crescer ou caiu não suficientemente depressa. Este é um fator não contemplado e levou a uma perda de estabilidade. É necessário levar em consideração esse fator e, assim, aumentar a estabilidade do algoritmo.

2 medidas foram desenvolvidas para reduzir o número de posições na série.

a) Se as posições forem Sell, precisaremos abrir novas posições apenas em candles crescentes. Se as posições forem Buy, abrimos as posições apenas nos candles decrescentes. Esse mecanismo permite fazer lucros com mais eficiência, precisamente pelo fato de haver mais de um tipo de candle do que de outro.

Abertura de posições de venda em candles decrescentes leva a uma diminuição no preço médio de abertura da posição e, se o preço subir, leva a uma carga adicional no depósito. Ao mesmo tempo, as "posições extras" praticamente não agregam lucro e não aceleram o fechamento das séries tirando lucros. A lógica é semelhante para posições Buy.

b) Abertura com controle do percentual de preponderância. Este é um filtro adicional para abrir posições numa série. É necessário verificar a porcentagem de preponderância em toda a amostra com o aparecimento de cada novo candle. O tamanho da amostra aumentará em um com o aparecimento de um novo candle. Se, com o aparecimento de um novo candle, a porcentagem de preponderânicia aumentou em relação à medição anterior, portanto, a posição pode ser aberta, caso contrário, não deverá ser aberta.

Este ponto funciona quase como ponto (a), mas um pouco diferente. Seu sentido é completamente semelhante ao modo do ponto (a): para evitar que o preço médio de abertura de uma série para posições Sell diminua e para evitar um aumento no preço médio de abertura de uma série para posições Buy.

Se a porcentagem média ponderada for usada como a porcentagem limite, este método pode ajustar a abertura de posições adicionais comparando o valor atual da porcentagem média ponderada com o valor do candle anterior.

Esses 2 pontos podem ser usados juntos ou separadamente. Eles reduzem o nível de lucratividade, mas aumentam significativamente a estabilidade, e isso é mais importante para mim do que o lucro. Houve um fator não contemplado a menos e, consequentemente, a estabilidade do trabalho aumentou.

open positions befor

open positions after

Fig. 4. Um exemplo de redução do número de posições numa série

Na Figura 4 acima, as posições são abertas sem restrições, na figura abaixo, usando o algoritmo do ponto (b). Percebe-se que menos posições foram abertas, os resultados comparativos deste trade estão listados na tabela abaixo.


Lucro Perda máxima Número de posições Profit factor
Abertura em cada candle (imagem superior) +71.99$ -463.96$ 92 1.56
Abertura com controle da porcentagem de preponderância (figura inferior) +42.26$ -263.86$ 48 1.68

A tabela mostra que tanto o rebaixamento máximo como a lucratividade caíram. Mais importante ainda, o número de posições diminuiu 1,91 vezes, o que, em última análise, terá um efeito positivo na estabilidade do algoritmo nos momentos em que os parâmetros de mercado se desviam de seus valores típicos.

Outros métodos foram desenvolvidos para reduzir o número de posições na série, e eles estão descritos nos termos de referência, mostrei aqueles que me parecem mais eficientes. 

4. Modernização do fechamento de posições fazendo lucro

Na primeira versão do algoritmo, foi introduzido o conceito de lucro por lote. Este valor foi definido na moeda de depósito para um lote igual a um. Em seguida, o número de lotes de posições abertas da série foi calculado e o valor das configurações foi multiplicado pelo lote total atual de posições abertas da série. Por exemplo, é definido nas configurações para fechar uma série de posições quando o lucro ultrapassar US $ 15 por lote. Agora, 11 posições estão abertas para 0,01 lotes, o que significa que a posição total é 0.01*11=0.11. Além disso, o lucro por lote é multiplicado pelo número de lotes recebidos $15*0.11=$1.65. Se o lucro total nas posições abertas atingir $ 1,65, a série de posições deve ser concluída.

Definir um lucro fixo por lote na moeda de depósito não é a solução mais eficaz. Quando a volatilidade de um instrumento cai, o risco de perder o ponto de fechamento correto aumenta. Por outro lado, quando a volatilidade aumenta, o robô perde lucro. Como resultado, durante a otimização, o lucro médio por lote é obtido, o que não funciona com eficiência suficiente. 

A solução mais simples seria ajustar o parâmetro "lucro por lote" da volatilidade atual. Quanto mais volatilidade, mais lucro por lote e vice-versa. Já posso dizer que usar a volatilidade média também não é a solução ideal, mas é melhor do que um valor fixo.

Esta é outra pequena função de auto-adaptação, o parâmetro não é configurado rigidamente, e, em vez disso, é definida a dependência do estado atual do mercado. Sabe-se que o lucro numa série depende diretamente do tamanho dos candles, e essa dependência deve ser usada para aumentar a estabilidade.

Recusei-me a controlar o lucro na moeda de depósito, porque o preço do pip não é constante para pares de moedas como USD/XXX e alterações do valor do preço atual. O lucro será monitorado em pontos. Para fazer isso, devemos pegar o valor atual do indicador ATR (em pontos) e multiplicá-lo pelo valor das configurações do "Koef_multi_ATR". Obtivemos o número de pontos para fechar com lucro. Além disso, para cada posição, é calculado quantos pontos passaram desde o preço de abertura até o valor atual, e é encontrado o valor médio para todas as posições. O valor médio resultante é comparado com o número de pontos para fechar com lucro. Se o número médio de pontos for maior ou igual ao número de pontos a serem fechados, então a série termina, caso contrário, o procedimento é repetido no próximo candle. 

O lucro atual deve ser monitorado a cada tick ou por meio de um temporizador. Para não se sobrecarregar com cálculos desnecessários um sistema como este, é normal verificar o lucro com base no temporizador 1 vez por segundo ou mesmo 1 vez por 10 segundos.

  5. Trabalhando com vários instrumentos de negociação

A versão anterior do robô era capaz de negociar 10 instrumentos ao mesmo tempo. Isso não era suficiente, e tivemos que iniciar simultaneamente várias cópias do robô. A nova versão pode negociar simultaneamente usando 28 instrumentos de negociação, isso é feito para melhor controle do trading.

Como escrevi anteriormente, os sinais do início da série em diferentes instrumentos são ligeiramente correlacionados, e isso leva à sincronização de rebaixamentos para diferentes instrumentos, a um aumento nos requisitos de depósito e a uma diminuição na lucratividade relativa. 

Idealmente, a correlação entre os sinais de início de uma série em diferentes instrumentos de negociação deve ser negativa. Ou seja, um rebaixamento atual grande num instrumento deve coincidir com pequenas negociações lucrativas em qualquer outro instrumento de negociação. Proibir a abertura simultânea de séries para mais de um instrumento também não é a melhor solução, pois a lucratividade geral diminui.

A correlação de sinais no início de uma nova série ocorre pelo fato de uma das moedas poder começar a cair ou subir em relação às demais. Um sinal para vender ou comprar esta moeda em relação a outras moedas pode aparecer em vários pares de moedas ao mesmo tempo, devemos nos proteger de tal situação.

Para tornar a correlação entre os sinais de abertura de séries em diferentes instrumentos o menor possível, devemos dividir os pares de moedas em moedas diferentes e assumir que as posições são abertas para estas últimas. Se uma posição Sell for aberta para EURUSD, essa posição será dividida numa posição Sell para EUR e uma posição Buy para USD. Antes de iniciar cada nova série, é necessário verificar se há posições para as moedas incluídas no par. Se houver uma posição Sell para EUR, precisaremos proibir o início de qualquer série em que precisemos vender EUR. Mas não há necessidade de proibir sinais para comprar EUR. 


Fig. 5

Um exemplo de como dividir moedas em pares é mostrado na Figura 5. Abaixo, na Figura 6, é mostrado esquematicamente quais posições podem ser abertas se uma posição Buy para EURUSD estiver aberta. Para o resto das opções, tudo funciona da mesma maneira. 

Currencies 2

Fig. 6.

Com essa abordagem não é mais necessário limitar o número máximo de instrumentos para abertura simultânea de posições, no entanto, deixei a função nas configurações.

6. Correção do lote a partir da volatilidade atual

Na segunda versão do algoritmo, recusei o refinanciamento automático, por isso, o lote não mudará quando o tamanho do depósito for alterado. Fiz este robô para negociação real e não preciso desse recurso. Porém, desenvolvi uma função de correção de lote diferente. Os lucros e perdas desse algoritmo dependem do tamanho dos candles ou da volatilidade. É lógico tentar fazer o gráfico de rendimento o mais plano possível, sem quedas e picos. 

Para estabilizar o gráfico de rendimento, precisamos alterar o tamanho do lote em relação à volatilidade atual. Quanto maior for, menos precisamos usar o lote, já quanto menor a volatilidade, maior podemos definir o lote. O lote mudará na proporção da volatilidade atual. Para fazer isso, as configurações definirão o valor do lote normal e a volatilidade normal.

Para calcular o lote atual, precisamos pegar o valor ATR atual e dividi-lo por "Norm_ATR" nas configurações. Em seguida, "Lot" das configurações deve ser dividido pelo coeficiente resultante. Arredondamos o valor obtido para o valor correto. Portanto, o lote diminuirá com o aumento do tamanho dos candles, e o gráfico de rendimento será o mais estável possível.

Após o início da série, a volatilidade pode mudar, por isso, forneci 2 opções de trabalho. Na primeira, o lote é determinado antes do início da série e é estável até o final da série.

Na segunda variante, o lote muda da volatilidade atual após o início da série. Mas nesse caso, ao calcular o lucro atual, o tamanho da posição afetará o lucro total na moeda do depósito e os resultados podem melhorar ou piorar. A função será experimental, se você gosta de como funciona, na próxima versão ela pode ser modificada.

Testes

O artigo não descreve todas as modificações e modos de operação desenvolvidos, apenas os principais e mais interessantes. Muito mais foi implementado do que foi escrito e todos os modos podem ser combinados entre si. Vou anexar uns termos de referência para o algoritmo anexado ao artigo, tudo é descrito em detalhes. 

Vou fazer os testes com base nos mesmos pares de moedas que usei para testar a primeira versão do algoritmo, e vou comparar visualmente o que aconteceu. Como a primeira versão, esse algoritmo funciona com o fechamentos dos candles, por isso, podemos testar com segurança no modo "pontos de controle". Dentro do candle, ele apenas controla o lucro atual e garante que os fundos atuais não caiam abaixo do valor limite definido nas configurações. Como antes, os testes serão realizados com um spread superestimado e irei definir um spread de 40 para GBPUSD.

Como na primeira versão do algoritmo, podemos negociar e otimizar qualquer timeframe. O timeframe mínimo é limitado pelo tamanho dos candles em relação aos spreads e comissões. Quanto mais pequeno for o timeframe, maiores serão os requisitos de qualidade do sinal e expectativa de lucro. Com um aumento no timeframe, o tamanho dos candles aumenta e, consequentemente, o nível de rebaixamentos também. Por isso, o timeframe maior é limitado pelas preferências em termos de estilo de negociação.

Realizei a otimização em 2017, com um robô para negociar em contas reais, nessa altura, apenas peguei as configurações antigas e não executei a otimização agora.

GBPUSD 2000 tester chart

GBPUSD 2000 Tester report

Fig. 7. GBPUSD H1 2000.01.01 - 2020.12.08 lote estático

A Figura 7 mostra um teste de GBPUSD para o timeframe H1, durante um período de quase 21 anos de 01.01.2000 a 2.012.08. Aqui são usadas várias amostragens do intervalo. O intervalo de análise é de 68-200 candles e são usadas 15 amostras.

Se a primeira versão do algoritmo passou no teste apenas desde 2001, a segunda versão passou desde 2000 sem problemas. Em comparação com a primeira versão do algoritmo, o número de posições triplicou e o lucro aumentou 1,9 vezes. O fator de lucro diminuiu de 7,5 para 2,74, mesmo assim, permanece num nível decente. Os sinais para o início da série são gerados com mais frequência e o número médio de posições na série diminuiu. Provavelmente, podemos escolher configurações melhores, mas eu peguei as que usei para negociação.

Anteriormente, foi desenvolvida uma função para ajustar o lote a partir do valor ATR atual. A Figura 8 mostra o mesmo teste da Figura 7, mas com um lote dinâmico dependente da volatilidade. Visto que para US $ 3 000 foi usado o lote de 0,01, para a operação correta do algoritmo de correção de tamanho do lote, aumentei o depósito para US $ 30 000 e, consequentemente, aumentei o lote para 0,1.

GBPUSD 2000 tester chart dyn lot

GBPUSD 2000 Tester report dyn lot

Figura 8. GBPUSD H1 2000.01.01 - 2020.12.08 lote dinâmico dependendo do ATR 

Como podemos ver na Figura 8, o gráfico de rendimento se tornou significativamente mais linear, conforme esperado durante o desenvolvimento. Ao mesmo tempo, o rendimento caiu ligeiramente, enquanto o rebaixamento máximo aumentou ligeiramente. A modalidade acabou sendo interessante e útil para obter a rentabilidade máxima prevista com um índice de Sharpe elevado.

Precisamos verificar a estabilidade dos parâmetros que usei para os testes acima. Para fazer isso, irei executar um teste do GBPUSD no período gráfico M15 com as mesmas configurações que usei no H1. Uma vez que a irregularidade da volatilidade é muito maior em períodos gráficos mais curtos, é necessário reduzir ligeiramente o fator de lucro. Como eu conheço a razão pela qual se deve fazer isso, esse parâmetro poderia ser auto-adaptável, mas esse não é o caso na versão atual do robô, e, portanto, eu o ajusto manualmente. 

GBPUSD M15 tester chart

GBPUSD 2009 m15 Tester report

Fig. 9. GBPUSD M15 2009.01.01 - 2020.12.08

A Figura 9 mostra o teste GBPUSD M15 2009.01.01 - 2020.12.08 com configurações a partir do timeframe H1. O teste foi aprovado de forma consistente desde 2009. O resultado é bom porque as configurações do timeframe não foram especialmente otimizadas para o timeframe M15. Para encontrar as configurações ideais para M15, basta otimizar a seção mais difícil, isto é, 1,5 anos de 01/01/2008 a 01/06/2009. Se otimizarmos os parâmetros de acordo com esta seção, o robô aprovará o teste de 21 anos sem problemas.

Para a primeira versão, mostrei testes do EURUSD em H1, por isso, vamos comparar os resultados. A Figura 10 mostra o resultado do EURUSD em H1 para o período de 2000.01.01 a 2020.12.08.

EURUSD 2000 tester Chart

EURUSD 2000 tester report

Fig. 10. EURUSD H1 2000.01.01 - 2020.12.08

A primeira versão passou no teste apenas desde 2007, já a nova versão, desde 2000, por 21 anos. A estabilidade melhorou significativamente. Ao mesmo tempo, o rebaixamento máximo diminuiu 1,2 vezes e o lucro aumentou 3 vezes. O número de transações aumentou 2,3 vezes.

Já que estou comparando o quão melhor a segunda versão ficou, vamos ver o teste para GBPJPY no timeframe H1. A primeira versão passou no teste desde 2009.

GBPJPY 2000 tester chart

GBPJPY 2000 tester report

Fig. 11. GBPJPY H1 2000.01.01 - 2020.12.08

Como podemos ver na Figura 11, o algoritmo começou a passar por backtests desde 2000, enquanto o rebaixamento diminuiu 1,8 vezes e o fator de lucro aumentou para 3,3.

Otimizei 28 pares de moedas que consistem em oito moedas: USD, GBP, EUR, CHF, CAD, AUD, NZD, JPY. Alguns pares de moedas apresentam ótimos resultados, outros nem por isso, mas todos estão bem otimizados e passam nos testes, via de regra, desde 2004. Apenas alguns pares de moedas passaram o teste desde 2007.

MetaTrader 4 não tem a capacidade de testar vários instrumentos ao mesmo tempo, por isso, testei cada um dos 28 instrumentos separadamente e usei um software de terceiros para combinar os relatórios. Já que fiz isso em 2017, o relatório combinado será de 2010 a 2017.

Full report

Fig. 12. Backtest combinado para 28 pares de moedas de 2010 a 2017

A Figura 12 mostra que o gráfico de rendimento do backtest para 28 pares de moedas é bastante plano, com um rendimento de cerca de 100% ao ano. O resultado é lindo, mas na realidade a rentabilidade é menor pois haverá uma limitação a nível de negociação simultânea com vários pares de moedas. Tenho usado este robô para negociar em contas reais há dois anos, e a lucratividade real estava no nível de 56% ao ano. 

A rentabilidade real é inferior à calculada porque o teste foi realizado com spreads inflacionados, e o algoritmo trabalha de forma que quanto maior o spread, maior a rentabilidade. A situação não é paradoxal, à medida que aumenta o spread, diminui a estabilidade. Além disso, na realidade, o efeito de redução do número de sinais devido à proibição de transações monetárias unidirecionais também se faz sentir.

Na negociação, usei as configurações mais conservadoras, mas o algoritmo pode ser configurado de forma muito mais agressiva. 

Funções adicionais

Um recurso adicional foi acrescentado para filtrar sinais do início de uma série por meio de outros timeframes. Por exemplo, a negociação é realizada no intervalo de tempo H1, mas os sinais são verificados adicionalmente em todos os intervalos de tempo padrão. Um sinal para o início de uma série é gerado apenas se houver também um sinal para o início de uma série nos timeframes M1, M5, M15, M30, H1, H4, D1. Um sinal para confirmar uma série de timeframes adicionais é gerado de acordo com as mesmas regras e no mesmo modo que no timeframe principal. Timeframes adicionais podem ser ativados ou desativados independentemente.

Infelizmente, não conseguimos testar este modo, houve problemas com o funcionamento correto desta função.

Existem muitas funções adicionais no robô que não considerei porque não são tão interessantes quanto a mecânica básica de trabalho. Mas vale a pena listá-las:

  • A capacidade de definir take profit e stop loss. Os valores são calculados de acordo com um algoritmo específico e podem duplicar pontos de fechamento reais ou trabalhar de forma independente.
  • A função de monitorar os fundos atuais foi implementada. Se os fundos caírem abaixo do limite definido, o robô fecha as posições e para de negociar
  • É possível limitar o número máximo de posições para um instrumento e para todos os instrumentos.
  • Implementado controle da perda atual para cada instrumento de negociação, este é um stop loss virtual adicional
  • Entre duas séries adjacentes, podemos definir uma pausa no número de candles para que a série não abra imediatamente após o fechamento da anterior. Esta função é necessária para que durante uma pausa, uma série de outros instrumentos possam ser iniciados.
  • Você pode definir o valor mínimo do ATR para o qual uma nova série do instrumento pode ser iniciada. Se a volatilidade for baixa, pode não ser lucrativo negociar.
  • O lucro não linear pode ser usado para fechar posições. Quanto mais posições forem abertas numa série, mais rápido será desejável concluir essa série. Por isso, o lucro limite cai em proporção à raiz quadrada do número de posições abertas.
  • Todas as informações necessárias sobre cada instrumento negociado são exibidas na tela para que você acompanhe o que está acontecendo na "cabeça" do robô.
  • O algoritmo processa a reinicialização do computador e do terminal, retoma suas posições abertas e continua negociando de acordo com a situação atual, para isso são utilizadas variáveis globais.

O robô possui 2337 configurações para 28 instrumentos de negociação, para que todos possam encontrar um modo de operação interessante próprio.

Conclusões e futuro desenvolvimento

  • Um padrão simples, mas compreensível, foi tomado como base e, durante o desenvolvimento, foi possível melhorar significativamente as características do algoritmo. Isso é possível precisamente porque o padrão usado é extremamente claro e podemos estudar o que exatamente afeta os lucros e as perdas.
  • O algoritmo é perfeitamente otimizado com base em diferentes instrumentos e é bastante estável por longos períodos de tempo.
  • Os parâmetros de trabalho se tornam mais flexíveis e já estão ligeiramente ajustados em função das características atuais do mercado. Foi esse recurso que tornou possível aumentar significativamente a estabilidade. Este algoritmo pode ser melhorado ainda mais, aumentando a qualidade do seu trabalho.
  • Existe um potencial significativo para melhorar o desempenho do algoritmo. A lógica pode ser invertida para as negociações de tendência e contra-tendência.
  • A otimização é necessária para cada instrumento. Isso é ruim, porque não foi desenvolvido um modelo teórico completo indicando quais parâmetros são necessários num determinado momento para um determinado instrumento de negociação e por quê.
  • A necessidade de realizar uma otimização para cada instrumento de negociação implica que não sabemos como as características das séries de preços dos diferentes instrumentos de negociação diferem. Qualquer incerteza são fatores não considerados.
  • Se não for conhecido o que torna diferente os parâmetros da série de preços em relação aos de outro instrumento, então não há como controlar a presença de um padrão no instrumento atual. Não podemos dizer exatamente quais parâmetros da série de preços afetam o lucro e a estabilidade do algoritmo.
  • Não está claro por que as configurações otimizadas são estáveis para um instrumento e instáveis para outro. Podemos escolher configurações que serão estáveis em todos os instrumentos de negociação, mas isso levará a uma queda significativa na lucratividade.
  • Ao otimizar parâmetros com base em dados históricos, não é possível se livrar de fatores não considerados. É o número de fatores não considerados que afeta a estabilidade.
  • Para alcançar estabilidade e confiabilidade reais, é necessário revisar significativamente a teoria e abandonar a otimização nas próximas versões do algoritmo.
  • Cada parâmetro das configurações deve depender de algo. Não deve haver um único parâmetro definido simplesmente porque funciona melhor assim. Precisamos de uma explicação detalhada de por que esse valor de parâmetro está sendo usado agora e quando ele deve alterar seu valor.

No próximo artigo, continuarei a desenvolver o algoritmo e revisarei significativamente o modelo teórico. O novo algoritmo será projetado para MetaTrader 5 porque é uma plataforma mais poderosa, flexível e eficiente.

Anexado ao artigo está o código do robô, os termos de referência do mesmo, as configurações com as quais os testes foram realizados, um exemplo de configurações para 28 pares de moedas e uma tabela Excel para cálculo da probabilidade de evento.

Autor da ideia e da especificação técnica, Maxim Romanov, o código foi escrito por Vyacheslav Ivanov.

Artigos anteriores sobre este tópico:

Desenvolvendo um algoritmo de auto-adaptável (Parte I): encontrando um padrão básico

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

Arquivos anexados |
robot.zip (43.21 KB)
Set.zip (152.63 KB)
technical_task.zip (67.45 KB)
Últimos Comentários | Ir para discussão (1)
Marcos De Almeida Chibly
Marcos De Almeida Chibly | 6 abr 2021 em 18:34
Poderiam converter o algoritmo para o MQL5.
O mercado e a física de seus padrões globais O mercado e a física de seus padrões globais
Neste artigo, eu tentarei testar a suposição de que qualquer sistema, mesmo com uma pequena compreensão do mercado, pode operar em escala global. Eu não inventarei nenhuma teoria ou padrão, mas apenas usarei de fatos conhecidos, traduzindo gradualmente esses fatos para a linguagem da análise matemática.
Trabalhando com séries temporais na biblioteca DoEasy (Parte 59): objeto para armazenar dados de um tick Trabalhando com séries temporais na biblioteca DoEasy (Parte 59): objeto para armazenar dados de um tick
Com este artigo, vamos começar a criar a funcionalidade de biblioteca para trabalhar com dados de preços. Hoje vamos criar uma classe de objeto que armazenará todos os dados de preços recebidos no tick a seguir.
Trabalhando com preços na biblioteca DoEasy (Parte 60): lista-série de dados de dados de tick do símbolo Trabalhando com preços na biblioteca DoEasy (Parte 60): lista-série de dados de dados de tick do símbolo
Neste artigo, criaremos uma lista para armazenar dados de tick de um símbolo e verificaremos tal criação e respectiva recepção de dados a partir dela no EA. Essas listas de dados de tick - separadamente para cada símbolo usado - formarão uma coleção de dados de tick.
Redes Neurais de Maneira Fácil (Parte 9): Documentação do trabalho Redes Neurais de Maneira Fácil (Parte 9): Documentação do trabalho
Nós já percorremos um longo caminho e o código em nossa biblioteca está se tornando cada vez maior. Isso torna difícil controlar todas as conexões e dependências. Portanto, eu sugiro criar uma documentação para o código criado anteriormente e mantê-lo atualizado a cada nova etapa. A documentação devidamente preparada nos ajudará a ver a integridade do nosso trabalho.