Algoritmo auto-adaptável (Parte III): evitando a otimização

5 abril 2021, 08:11
Maxim Romanov
0
597

Introdução

Antes de começar a estudar este artigo, recomendo que você leia o segundo artigo da série "Desenvolvendo um algoritmo de auto-adaptável (Parte II): melhorando a eficiência". A abordagem do artigo atual será significativamente diferente de tudo o que foi discutido anteriormente, mas conhecer os artigos anteriores da série será útil para entender o problema.

Análise de falhas

Como da última vez, começarei analisando as deficiências da versão anterior bem-sucedida. Durante a análise, foram identificadas as seguintes deficiências:

  • O sinal para abrir e fechar posições é gerado com base na análise de candles. Os candles são instáveis em tamanho, alguns são grandes e outros, pequenos. Muitas vezes surgem situações em que as posições são abertas com base na preponderância de candles decrescentes ou crescentes, em seguida, os decrescentes e crescentes se tornam iguais, mas o lucro nas posições abertas ainda é negativo. Surge a pergunta: "fechar posições ou esperar até que haja lucro?". Se fecharmos, todo o propósito da negociação será anulado, o algoritmo começará a receber perdas. Se não fecharmos, mais cedo ou mais tarde isso causará um rebaixamento significativo.
  • O preço se move independentemente do tipo de candle. O mercado poderá ser dominado por candles descendentes, e o preço subirá porque os candles altistas serão maiores do que os baixistas. Este momento é especialmente negativo quando há posições abertas.
  • Prever o tamanho futuro dos candles é uma tarefa que ainda ninguém resolveu.
  • Às vezes, após a abertura de posições, a preponderância de um tipo de candle não diminui por muito tempo e o preço pode continuar a se mover contra as posições abertas. Isso provoca rebaixamentos significativos e, o mais importante, não está claro se o preço irá se reverter e em que momento isso acontecerá.
  • As posições são abertas por tempo. Há momentos em que o preço fica parado durante muito tempo e as posições continuam a ser abertas porque novos candles surgem. Esses momentos são especialmente perigosos durante as férias, como o Natal, quando a atividade de negociação é baixa e o algoritmo está simplesmente acumulando posições com o passar do tempo.
  • As configurações do algoritmo devem ser otimizadas para cada instrumento de negociação individualmente. A única razão pela qual essas configurações são definidas é que assim funcionam melhor com o histórico. Na verdade, o algoritmo passou os back-test de 21 anos, mas não para todos os instrumentos, e ajustar os parâmetros com base no histórico não é a melhor solução.
  • Não é óbvio por que funciona melhor e de maneira mais estável para alguns instrumentos de negociação e de modo muito pior para outros.
  • Não se sabe quando o comportamento de um instrumento de negociação mudará de forma que o algoritmo sofra uma perda. Na verdade, não se sabe quando estaremos perante uma situação de risco. Embora possa calcular a probabilidade de ocorrência de tal momento, será um resultado muito aproximado.
  • Não existe uma teoria que explique como o comportamento do instrumento mudará no futuro e por que, portanto, é necessário usar parâmetros não ótimos antecipadamente para que haja margem para flutuações nas características estatísticas das séries de preços. Isso reduz muito a lucratividade.

Eu considero todas as desvantagens acima como significativas. Você pode continuar a modificar este algoritmo, melhorando as características uma a uma, mas é melhor tirar o melhor proveito dele, da experiência adquirida e começar o desenvolvimento praticamente do zero. Precisamos começar modernizando a base teórica.

O algoritmo deve ser totalmente auto-adaptável, pois será desenvolvido para os mercados de moedas e de ações. Não deveria fazer diferença que instrumentos negociar. Isso é importante porque deve haver uma compreensão clara de como alguns mercados diferem de outros. E se houver tal noção, faz sentido traduzi-la num algoritmo. Desta vez, mudei para a plataforma MetaTrader 5, porque esta tem um testador de estratégia mais funcional e está disponível para trabalhar não apenas com instrumentos Forex, mas também com instrumentos de bolsa.

Durante o desenvolvimento, cada vez precisamos responder à pergunta: por que um determinado parâmetro tem exatamente esse valor. Idealmente, o motivo para definir qualquer valor nas configurações deve ser justificado.

Alterando a visualização do gráfico de candles

Na nova versão, parei de usar candles por causa dos seus parâmetros instáveis. Mais precisamente, serão usados candles, porém, no timeframe M1 e apenas porque a mudança para o processamento de ticks leva a um aumento significativo no consumo de recursos. Idealmente, é melhor processar ticks.

Vou analisar blocos de N pontos. Esses são blocos semelhantes ao renko, mas construídos usando um algoritmo ligeiramente diferente. Já escrevi sobre os gráficos de blocos e suas vantagens na análise no artigo "O que são tendências e qual é a estrutura dos mercados: tendência ou lateral".

Block

Fig. 1. Visualização do gráfico de bloco

A Figura 1 mostra como são os blocos que analisarei. Abaixo está uma visão geral do gráfico de blocos, e a parte superior mostra como os blocos aparecem no gráfico de preços. Os blocos são construídos no passado e no futuro a partir de um tempo fixo. Na figura, o tempo registrado é mostrado com uma barra vertical amarela. Este é o ponto zero a partir do qual os blocos são construídos no passado e no futuro, o algoritmo de construção acaba por ser espelhado. O fato de os blocos serem construídos no passado e no futuro será importante para dar continuidade ao seu desenvolvimento no futuro.

Os blocos são necessários porque seus parâmetros principais são estáveis, controláveis e, o mais importante, o lucro/prejuízo depende principalmente do movimento do preço em pontos.

Modelo de mercado

O padrão básico será semelhante ao que usei nos algoritmos anteriores, isto é: o desvio local do número de blocos decrescentes em relação ao número de crescentes e o posterior retorno a algum equilíbrio. O padrão de comportamento é estatístico, portanto, precisamos começar analisando as características estatísticas dos gráficos de bloco. Para isso, desenvolvi um indicador especial, o Max_distribution, que foi discutido em detalhes no artigo "O que são tendências e qual é a estrutura dos mercados: tendência ou lateral"

O propósito do indicador é medir as características estatísticas de uma série de preços dividida em blocos. Ele pode exibir informações na tela simultaneamente para vários tamanhos de bloco. Por exemplo, estamos interessados em quais características estatísticas têm os gráficos com um tamanho de bloco de 10 a 1000 pontos. O tamanho mínimo do bloco é definido nas configurações do indicador e, em seguida, blocos de todos os outros tamanhos são obtidos por meio do fator de multiplicação.

O principal modo de operação do indicador é medir o número de blocos que o preço se move verticalmente em N etapas.

blocks vertically

Fig. 2. Um exemplo de medição do número de blocos verticalmente em 24 etapas

A Figura 2 mostra um exemplo. Ele mede quantos blocos verticalmente o preço passou ao longo de N etapas. Assim é coletado o número necessário de amostras (por exemplo, 100) e, em seguida, é encontrado o valor médio. Uma análise semelhante é realizada para blocos de tamanhos diferentes.

distribution

Fig. 3. Amplitude média para diferentes tamanhos de bloco

A Figura 3 mostra um exemplo da distribuição vertical da amplitude média em blocos ao longo de 24 etapas. Cada barra do histograma é o valor de amplitude médio para o tamanho do bloco. Amostras = 1 000. As medições à esquerda são para o menor tamanho de bloco e à direita para o maior. Para um tamanho de bloco de 0,00015 durante 24 etapas e 1000 amostras, o preço percorre uma média de 5,9 blocos verticalmente. Para um tamanho de bloco de 0,00967 para as mesmas 24 etapas e 1000 amostras, o preço se move verticalmente em média 4,2 blocos.

A linha vermelha mostra o valor de referência que seria se a série de preços fosse um passeio aleatório. Para 24 etapas, isso é 3.868 blocos verticais. O valor de referência é calculado pelo método combinatório e pode ser claramente representado pela tabela da Figura 4.

probability table

Fig. 4. Cálculo da referência para 24 etapas

A Figura 4 mostra o cálculo do valor de referência do número de blocos ao longo da vertical, que em média o preço passará ao longo de 24 etapas, se for um passeio aleatório. Na última coluna, esse valor é convertido em potência. Podemos dizer que a amplitude média do passeio aleatório tende para o valor 24^0,4526. Para cada número de etapas, a referência pode ser recalculada. A tabela está anexada ao artigo no formato .xlsx.

Realizei pesquisas sobre vários instrumentos de negociação: cerca de 35 pares de moedas, mais de 100 ações, 10 criptomoedas e cerca de 10 commodities. Não há desvios graves, em geral o cenário é aproximadamente semelhante para todos os instrumentos. A amplitude média varia de 7 em criptomoedas de rápido crescimento a 3,8 em pares de moedas. Algumas ações de baixa liquidez podem até cair abaixo de 3,8.

O valor da amplitude média foi obtido ao longo de 24 etapas ou durante algum outro número de etapas, mas o que isso significa? Vamos representar o gráfico na forma de uma senoide, convertida para a forma de bloco, como na Figura 5.

Sinus

Fig. 5. Senoide em forma de bloco

Imaginemos que o tamanho dos blocos seja tal que haja 24 etapas na metade do período da senoide. Então, o período será de 48 etapas. Se medirmos a amplitude média para 25 amostras de 24 etapas, obteremos uma amplitude média de 10,33 blocos ao longo de 24 etapas. Com o aumento do número de amostras, a amplitude média tenderá para 12, ou para o número de etapas dividido por 2. A série de preços não é uma onda senoidal, mas é conveniente negociar durante ela. Agora, se, ao medir a amplitude média, obtivermos um valor maior que 12, então o tamanho dos blocos não é grande o suficiente e 24 blocos não cabem na metade do período. Mas um valor menor que 12 indicará duas coisas: os blocos são muito grandes ou o movimento da tendência na série de preços não é tão linear quanto na senoidal. Agora não consideramos a inclinação da tendência, isso será depois.

De acordo com as leituras do indicador Max_distribution desenvolvido, pode-se estimar aproximadamente que tão semelhante a série de preços é a uma senoide. Para fazer isso, vamos ver na Figura 6 a aparência do histograma do indicador para uma senoide.

distribution2

Fig. 6. dependência da amplitude média em relação ao tamanho do bloco para uma senoide

A Figura 6 mostra que, com pequenos blocos, o preço se move verticalmente ao longo de 24 etapas de 24 blocos. Mas com um aumento no tamanho do bloco durante 24 etapas, o preço passa por um número cada vez menor de blocos e, então, quando o tamanho do bloco se torna comparável à amplitude das flutuações, o número de blocos cai verticalmente para zero. No gráfico da Figura 3, não foi observado um cenário como esse, em vez disso, o valor máximo era 5,9 e tendia ao padrão 3,868. Isso significa que a série de preços pode ser representada como uma senoide, porém ruidosa, sempre tendo um determinado componente de tendência em algumas escalas. Em outras palavras, o mercado deve sempre ter a escala em que a tendência está agora (a probabilidade de uma reversão é maior do que a probabilidade de continuação da tendência) e a escala em que a tendência está agora (a probabilidade de continuação é maior do que a probabilidade de uma reversão).

A razão pela qual adotei essa definição de tendência e lateralização pode ser encontrada num de meus artigos anteriores, "O que são tendências e qual é a estrutura dos mercados: tendência ou lateral".

Usando o indicador Max_distribution, medi o número médio de blocos verticalmente para diferentes instrumentos de negociação não apenas durante 24 etapas, mas também com outros valores. Um exemplo é mostrado na Figura 7.

multysample

Fig. 7. Dependência da amplitude média em relação ao número de etapas na amostra

Na Figura 7, as colunas brancas mostram a amplitude de movimento medida para valores do número de etapas de 10 a 120, com uma etapa de 2 e 1000 amostras para cada medição. As linhas vermelhas mostram o valor de referência para um determinado número de etapas. Como se pode ver, com o aumento do número de etapas, não são observados desvios significativos da tendência principal. A forma geral da curva de valor medido é semelhante à de um padrão. As medições foram feitas para GBPUSD, mas também fiz pesquisas para outros instrumentos. Existem muitos instrumentos de negociação cujos valores do histograma são superiores ao padrão, mas a tendência geral persiste e pode ser descrita por uma equação não linear.

Sabe-se que não pode haver padrões simples estáveis no mercado. Isso significa que a escala em que a tendência se encontra agora e o grau da tendência mudam constantemente. Além disso, as escalas com lateralização também se tornam tendência.

Vou pegar a amplitude média para 24 etapas da Figura 7, esse valor é 3,86. Vou supor que, por analogia com um movimento sinusoidal, o movimento consistirá numa tendência e lateralização. Desse modo, torna-se possível calcular qual será a parte da tendência para essa amplitude média. Para fazer isso, arredondarei 3,86*2=7,72 blocos verticalmente em 24 etapas até 8, porque os blocos só podem ser inteiros. Se chegarmos à área de tendência, o preço se move 8 blocos verticalmente ao longo de 24 etapas. Na verdade, o preço pode passar 24 blocos verticalmente ao longo de 24 etapas, nada é impedimento, porém, depois fica claro porque isso não é importante.

Resulta que na seção de tendência o preço passa 8 blocos verticalmente ao longo de 24 etapas. Isso significa que haverá um movimento com 16 blocos numa direção e 8 blocos em outra. Sabe-se também que a parte da tendência deve ser seguida pela parte da lateralização, de modo que a amplitude média permanece estável (e é bastante estável ao longo de um grande número de amostras). Mas o mercado não é uma senoide, e como pode ser visto na Figura 7, com o aumento do número de etapas, o número de blocos aumenta verticalmente. Por isso, assumirei que o desvio da média que ocorre em menos etapas retornará à média em mais etapas.

Usando o gráfico da Figura 7, vamos ver quanto o preço deve passar em média ao longo de 26, 28, 30, 32, 34 etapas:

26 etapas = 3,98; 28 etapas = 4,11; 30 passos = 4,2; 32 passos = 4,36.

Ao longo de 24 etapas, o preço já passou 8 blocos na vertical, mas durante 28 etapas, em média, deve passar 4,1 blocos na vertical, arredondado para um inteiro = 4. Isso significa que nas próximas 4 etapas é possível uma reversão do movimento anterior do 4º bloco. O mercado não é tão previsível, e é improvável que os eventos se desenvolvam de acordo com este cenário. No mesmo gráfico da Figura 7, podemos ver que o preço passa 8 blocos verticalmente numa média de 116 etapas.

rollback 1

rollback 2

Fig. 8. Cenários possíveis

A Figura 8 mostra 2 possíveis cenários. São exagerados, improváveis e mostrados para dar uma ideia visual. Muito provavelmente, os eventos se desenvolverão de acordo com um dos cenários intermediários. Mas agora é importante que se saiba quanto deve percorrer o preço, em média, ao longo de cada número de etapas. Pode-se ver que quanto mais brusco a reversão, mais profunda ele é, mas quanto mais plana a reversão, menor sua profundidade.

Em última análise, a amplitude de movimentos tenderá para seu valor médio. Para 24 etapas é 3,8 blocos verticalmente, já para 116 etapas é de 8 blocos verticalmente.

É assim que é construído um modelo que permite, com base nos parâmetros do movimento da tendência e no comportamento posterior do preço, calcular a característica de reversão especificamente para cada instrumento de negociação. Quanto mais brusco for o movimento da tendência e mais rápida a reversão, mais profunda será esta. Quanto mais plana a tendência e maior a reversão, mais pequena será a profundidade. Agora tudo isso pode ser expresso em números, usando as características estatísticas do instrumento como base.

rollback

Fig. 9. Exemplo de movimento de tendência e profundidade da reversão

A Figura 9 mostra isso num gráfico real. Pode-se ver que houve um movimento brusco e uma reversão brusca à esquerda, enquanto a profundidade da reversão acabou sendo superior a 60%. À direita, houve um movimento mais suave e uma reversão prolongada, resultando num recuo de 30%. Esse foi o resultado obtido porque na figura á direita o preço passou um número maior de etapas, e durante a formação do movimento sua amplitude aumentou.

As razões para este comportamento podem ser explicadas não apenas pelo fato de a série de preços ter uma amplitude média e aderir a ela, mas também pelo fato de que movimentos bruscos são causados por uma entrada/saída brusca de capital num ativo por montantes que excedam significativamente a liquidez atual. Depois que uma posição para um montante grande é aberta, ela precisa ser fechada. Nesse caso, não importa quem é o dono do dinheiro, se um player ou vários. Se fecharmos imediatamente a posição para o valor total, o preço voltará ao nível original, ou seja, a reversão será de 100%. Mas se a posição for fechada gradualmente, levando em consideração a liquidez entrante, então um montante maior causará um movimento menor. Quanto mais rápido o player sair da posição, mais forte será a reversão em relação ao movimento que ele criou com seu capital.

É importante que o padrão seja confirmado pelas características fundamentais da precificação. 

Este parágrafo não cita toda a teoria, mas é o suficiente para iniciar o desenvolvimento do algoritmo, o resto será descrito à medida que trabalhamos.

Rastreando a tendência

Como nos algoritmos anteriores, o robô operará contra-tendência e a posição será preenchida com uma série de ordens. O algoritmo irá gerar um sinal para abrir uma série e sua tarefa será determinar o ponto de entrada com a maior precisão possível. Idealmente, quanto mais frequentemente o sinal é gerado no início da série, mais lucro pode ser obtido por unidade de tempo. Isso significa que o sinal deve ser frequente e de alta qualidade.

O robô analisará o número de blocos decrescentes e crescentes. Se encontrar um desvio significativo no número de blocos crescentes em relação o valor normal, ele gera um sinal para uma série de posições Sell. Para blocos decrescentes, é o mesmo, só que a rejeição de blocos decrescentes gera um sinal da série Buy.

Agora será desenvolvido um algoritmo básico que será modificado posteriormente, por isso, seus módulos devem ser flexíveis. Como base para o sinal no início da série, pegarei o limite percentual da preponderância de blocos decrescentes/crescentes. A faixa definirá o número de blocos para análise, do valor mínimo ao máximo, como nos algoritmos anteriores, só que com um propósito diferente.

Limite percentual para início e fim da série

Como a análise usa um intervalo de blocos (por exemplo, 24-34), tomar uma porcentagem de limite fixo para cada número de blocos é uma decisão errada. A probabilidade de ocorrência de uma combinação de 24 blocos com 75% de preponderância dos blocos dominantes não é igual à probabilidade de ocorrência de tal combinação para 34 blocos. É necessário que a probabilidade de manifestação das combinações seja a mesma, o que significa que o limite porcentual deve ser utilizado de maneira dinâmica dependendo da probabilidade de ocorrência dessa combinação.

Nas configurações, o será definido pela probabilidade de cair na faixa, sendo que, em seguida, deve ser recalculada para o número necessário de blocos. A probabilidade de cair na faixa é calculada usando combinatória, para tal, desenvolvi uma tabela de acordo com a qual a probabilidade pode ser convertida num limite percentual para cada número de blocos. 

probability table

Fig. 10. Tabela de probabilidade 

A Figura 10 mostra uma tabela por meio da qual é recalculada a probabilidade de atingir a faixa como porcentagem de abertura. Na tabela é assumido que 100% dos movimentos cairão na faixa de 0 a 16 blocos verticais ao longo de 16 etapas. A probabilidade de atingir a faixa de 2,1% (para a tabela da Figura 10) significa que apenas 2,1% de todos os movimentos passarão verticalmente em 16 etapas de 10 a 16 blocos. Nas configurações, definimos a probabilidade de cair na faixa, por exemplo, 2,2, e o algoritmo procura na tabela o valor mais próximo menor ou igual a 2,2, depois, pega a porcentagem correspondente a este valor, neste caso é 81,25%. Assim, para cada número de blocos, haverá um limite percentual próprio. A tabela está anexada ao artigo no formato .xlsx.

Nas versões anteriores, as posições eram fechadas quando o lucro total de uma posição aberta ficava maior que o limite. Esta não é a melhor solução e gera muitos problemas. Como nesta versão trabalho com blocos de tamanho fixo, as posições podem ser fechadas quando a porcentagem de preponderância cai para o valor desejado. Se as posições forem abertas com um número fixo de blocos, o número de blocos na amostra aumentará durante a operação. 

O limite percentual para fechamento também é calculado através da probabilidade de cair na faixa. Mas a probabilidade de atingir a faixa tem escala inversa. Este é um momento sem importância, eu simplesmente fiz dessa maneria. Uma coluna separada é destacada na tabela para calcular a porcentagem de fechamento. Suponhamos que queiramos fechar posições quando o valor se tornar maior ou igual a 75. Então, o valor mais próximo é maior que 75. Para 16 blocos, isso é 78,9, que corresponde ao de fechamento = 62,5%. 

Ao trabalhar, o número de blocos na amostra aumenta porque novos blocos são fechados. Por isso, à medida que as posições são abertas, a cada novo bloco, o percentual para fechamento é recalculado para um número maior de blocos.

O take profit para todas as posições na série é definido como o ponto de fechamento esperado com lucro. É assim que o algoritmo de controle do valor de reversão é implementado dependendo do estado atual do mercado. Quanto mais blocos na amostra forem formados após o início da série (movimento de tendência), menor será o valor de reversão.

Esta implementação de limites de porcentagens não é ideal e foi desenvolvida no início do planeamento do algoritmo. Futuramente, atualizarei essa abordagem, e todos os valores das porcentagens de abertura e fechamento serão corrigidos com base na medição da amplitude média para um determinado número de blocos. A versão atual não leva em consideração o fato de que as características das séries de preços são assimétricas para um mercado altista e baixista. Isso pode ser ignorado no mercado Forex, mas para o mercado de ações este é um ponto importante que será levado em consideração nas próximas versões do algoritmo.

Desenvolvida a abordagem quanto ao , é possível responder à pergunta (sem usar otimização): qual usar. Para isso, foi desenvolvida uma fórmula:

%open

  • Nb - número de blocos para análise;
  • aa - amplitude média de acordo com as leituras do indicador para um determinado número de blocos;
  • Ka - fator de multiplicação da amplitude média. Para uma senoide, este é um fator de 2, mas para o mercado, precisamos torná-lo ajustável para que podamos aumentá-lo um pouco;
  • Kc - fator de multiplicação da amplitude média para cálculo do percentual de fechamento;
  • %open - porcentagem limite do início da série.

Você pode fazer este procedimento para apenas um número de blocos, o resto pode ser recalculado por meio da tabela de probabilidade.

A porcentagem de fechamento também pode ser calculada antecipadamente com base nas leituras do indicador.

%close;

A fórmula para calcular a porcentagem de fechamento parece a mesma, só que é usado um fator de multiplicação diferente Kc. É melhor torná-lo igual a 1, mas devemos prever a possibilidade de correção.

Com base na análise da amplitude média, 3,8, é possível definir o limite percentual de abertura para 24 blocos igual a 66,67%, para os demais valores, pode-se recalcular através da tabela de probabilidade.

Rastreando a tendência

Como escrevi acima, o mercado não tem padrões estáveis e amplitude de flutuações estável. Logo, é questionável analisar o grau de tendência dentro de um número fixo de blocos com um tamanho fixo. A janela para análise deve ser dinâmica e ajustada em tempo real. Assumamos que o número de blocos para análise deva ser especificado no intervalo de 24 a 28. 

Vou responder imediatamente à pergunta: "por que a janela de análise tem exatamente 24-28 blocos?". Esses valores são selecionados com base numa amplitude média = 3,8 e dependem do limite percentual de abertura/fechamento. Com este número de blocos, após o sinal de início da série, receberemos 4 blocos de lucro. Quanto mais blocos houver na janela para análise, mais preciso será o algoritmo. Não há diferença fundamental em quantos blocos é obtido lucro: 4 ou 10, se o tamanho do bloco for alterado proporcionalmente. Mas como as posições serão abertas a cada novo bloco, seu número aumentará com o aumento da precisão, e isso não terá um efeito muito bom nos resultados. 

Em seguida, precisamos determinar o tamanho mínimo do bloco que faz sentido analisar. Os blocos são construídos de acordo com os candles de minuto. A taxa de amostragem mínima é de 1 minuto. Não podemos fazer os blocos muito pequenos, porque, nesse caso, eles começarão a se formar dentro do candle, e analisar sob essas condições não fará sentido. Por isso, o tamanho mínimo do bloco será determinado com base no tamanho dos candles. Para fazer isso, podemos usar o indicador ATR durante longo período, por exemplo, 1440 minutos (dia) ou mais, e multiplicar seu valor pelo fator. Um fator de 2 a 5 deve ser aceitável, mas depende das características do instrumento de negociação.

Se o tamanho dos candles for muito irregular, é melhor usar um fator maior. O segundo critério é comissões e spread. O lucro recebido ao longo de 4 blocos deve ser significativamente maior do que as comissões que iremos pagar. Quanto menor for o tamanho do bloco, mais frequentemente serão os sinais no início da série e mais lucro podemos ganhar. Aqui precisamos encontrar um equilíbrio. Como resultado, o tamanho mínimo do bloco depende do tamanho dos candles e das comissões. Existem critérios claros para escolher o tamanho mínimo do bloco.

O método descrito para escolher o tamanho do bloco é bom o suficiente tanto do ponto de vista teórico quanto prático. Foi exatamente assim que foi implementado, mas agora desenvolvemos um mecanismo aprimorado que se baseia num modelo de mercado melhorado. A explicação do porquê um novo mecanismo requer um artigo separado, por esse motivo, neste artigo, vou me limitar à abordagem descrita acima.

Se um robô analisa um número fixo de blocos com tamanho fixo, este não será lucrativo, porque os parâmetros do mercado estão sempre mudando, as tendências do mercado são de tamanhos diferentes e reversões, respectivamente, de tamanhos diferentes, logo, é necessário um mecanismo adaptativo.

O robô irá analisar os blocos com o tamanho mínimo, mas ao encontrar uma pequena área de tendência com uma porcentagem de preponderância acima do limite, ele deve determinará a escala máxima para a presença de uma tendência. Para fazer isso, precisamos varrer uma área maior. Como o número de blocos para análise é fixo, precisamos aumentar o tamanho dos próprios blocos e ver o que acontece no bloco maior. Eu chamei o tamanho mínimo do bloco de TF1 por analogia com o timeframe. Trata-se de um timeframe em bloco sintético. Blocos maiores serão obtidos através de um fator de multiplicação, KTF, por exemplo, será 1,1.

1. Sinal para o início da série

É necessário introduzir o conceito de timeframe base (doravante, sempre que falamos em timeframes, queremos dizer timeframe em blocos). O timeframe base é aquele em que o sinal é encontrado no início da série.

O algoritmo deve criar vários timeframes adicionais em bloco e verificar se há um sinal de início de série nos timeframes mais altos. 

Para o coeficiente KTF=1,1, basta olhar para os 5 timeframes mais próximos, assim, o tamanho do bloco do timeframe mais alto será 1,6 vezes maior do que o mínimo. Se um sinal para o início da série for encontrado num dos timeframes mais altos, o algoritmo passará para este timeframe e o tornará base. Depois que um novo timeframe base foi encontrado, precisaremos criar 5 timeframes grandes novamente e repetir o procedimento de varredura. Assim será encontrado o timeframe máximo com uma preponderância acima do limite.


work

Animação 1.

Nesta fase, a tarefa é encontrar o timeframe máximo em que existe um sinal para o início da série, e torná-lo base. A animação 1 mostra um exemplo de como isso funciona. Podemos ver que o algoritmo faz a varredura de pequenos blocos e, quando encontra um sinal, aumenta o tamanho do bloco e seleciona o timeframe base com o tamanho máximo dos blocos. Ele calcula a reversão para fechar posições já para a maior tendência que ele pode determinar.

Neste ponto, torna-se importante usar um intervalo de número de blocos em vez de um valor fixo. No exemplo, o sinal é pesquisado num intervalo de 24-28 blocos. Uma amostra com grande número de blocos é considerada prioritária. Se um sinal for encontrado tanto em 24 blocos quanto em 28 blocos, então 28 blocos se tornam a amostra de base. É o mesmo em timeframes adicionais: o sinal é procurado na faixa de 24-28 blocos. O timeframe com um tamanho de bloco grande é considerado a prioridade e, dentro desse timeframe, a prioridade é dada à amostra com maior número de blocos.

Esse mecanismo é necessário porque há algum erro na construção dos blocos. Um timeframe com um tamanho de bloco grande nem sempre cobre um intervalo de dados maior.

size error

Fig. 11. Erro de construção de blocos

A Figura 11 mostra que 10 blocos grandes podem cobrir menos dados do que 10 blocos pequenos. Para minimizar este efeito, o intervalo do número de blocos para análise é 24-28. O robô pode se mover para um timeframe base maior e aumentar o número de blocos na amostra. Depois, será mais fácil para ele passar para um timeframe ainda mais alto, com menos blocos na amostra.

E respondo à pergunta: "por que KTF = 1,1?" Quanto menor o fator de multiplicação, mais preciso o algoritmo funcionará, mas mais intervalos de tempo precisaremos visualizar ao mesmo tempo. Para que o tamanho do bloco aumente 1,6 vezes em relação ao timeframe base, precisamos visualizar apenas 5 timeframes. Se fizermos KTF = 1,05, teremos que olhar para 10 timeframe já, e esta é uma carga computacional adicional. Mas quanto menor o fator de multiplicação, mais preciso ele funciona.

2. Atraso na abertura de posições

Foi encontrado um sinal para o início da série, mas se começarmos a abrir posições agora, o resultado será uma autoadaptação duvidosa, fraca. O preço pode continuar a se mover na mesma direção e é provável que isso aconteça Precisamos ter certeza de que a escala máxima foi encontrada e a tendência acabou. Para isso, é necessário que no próximo timeframe não haja sinal no início da série, e para que o algoritmo não possa aumentar o timeframe base. O sinal para o início de uma série no timeframe superior está ausente no momento, mas os blocos do timeframe mais alto cobrem um intervalo de dados maior e se tornam uma coisa do passado em relação ao início da tendência.

Após determinar o timeframe base, precisamos dar tempo ao preço para formar um sinal no timeframe mais alto. Elo deve percorrer uma distância suficiente para poder se mover para um timeframe mais alto. E apenas se tiver passado tempo suficiente para a formação de um sinal no timeframe mais alto, mas o sinal não tiver sido formado, podemos abrir uma posição. Primeiro, resolvi esse problema, como será descrito no ponto (a), depois melhorei significativamente o mecanismo e melhorou muito os resultados, vou descrevê-lo no ponto (b).

a) Atraso ao longo da seção de tendência

Os blocos do timeframe superior vão mais fundo na histórico do que os blocos do timeframe base. Isso significa que precisamos esperar até que os blocos de 24-28 do timeframe superior se encaixem no mesmo intervalo histórico que os blocos de 24 a 28 do timeframe base. Precisamos verificar cada novo candle.

delay a

Fig. 12. Atraso na abertura de posições para passar para um timeframe mais alto

A Figura 12 mostra que tivemos que esperar 2 minutos para que os blocos maiores se ajustassem ao intervalo de tempo ocupado pelos blocos menores. Se houver um atraso num dos timeframes mais altos (vários deles são vistos simultaneamente) um sinal for detectado no início da série, o timeframe base aumenta e o atraso se repete. Se, após o final do atraso, o algoritmo não for capaz de passar para um timeframe mais alto, a escala de tendência máxima será encontrada e poderemos abrir uma posição.

A abordagem geralmente funciona, mas está longe de ser ideal. Ela foi implementada numa versão inicial do algoritmo, cujos testes irei mostrar, por isso, destaquei seu trabalho. Durante o processo de modificação, um algoritmo de atraso aprimorado foi desenvolvido, o qual é descrito no parágrafo (b).

b) Atraso com base nas características estatísticas do instrumento

O objetivo deste método é semelhante ao prosseguido na ponto (a). É necessário que os blocos do timeframe superior cubram a mesma área de tendência que os blocos do timeframe base.

Neste método, usarei as características estatísticas de um instrumento de negociação para determinar quando o atraso termina. Durante o atraso, é importante para o algoritmo determinar se a tendência terminou, se mover para um timeframe mais alto ou abrir uma posição. Por isso, a melhor solução seria usar blocos de um timeframe maior para calcular o tempo de atraso. Visto que as principais características estatísticas de um instrumento de negociação já foram levadas em consideração no limite percentual %open, irei usá-las para determinar a duração do atraso.

Primeiramente, é determinado quantos blocos o preço percorre ao longo da vertical ao receber um sinal no início da série, denominado Vb na fórmula. Em seguida, a partir dos tamanhos de bloco do timeframe base e do tamanho do bloco do próximo timeframe, descobrimos quantos blocos do timeframe superior devem se mover verticalmente para formar todos os blocos Vb do timeframe mais alto, obtemos o valor Nd. Depois disso, sabendo que o preço não se move estritamente verticalmente e conhecendo a natureza do movimento, precisamos calcular o número de blocos de atraso do maior timeframe Nbd.

formula dalay;

  • Vb — número de blocos predominantes para o início da série;
  • mnb — número mínimo de blocos do intervalo para análise. Se o intervalo for 24-28, serão 24 blocos;
  • Nd — número do atraso;
  • Bsd — tamanho do bloco do timeframe mais alto;
  • BSB — tamanho do bloco do timeframe base;
  • kfd — fator de multiplicação para corrigir o número de blocos de atraso;
  • addkfd — fator de adição para corrigir o número de blocos de atraso.

Por exemplo: digamos que mbn=24; %open=75; BSB=0.00064; Bsd= 0.0007. Então Vb=18. Isso significa que de 24 blocos, 18 devem ser na mesma direção. Contamos quantos pontos o preço percorreu ao longo de 18 blocos no timeframe base. Por este 18*BSB = 0,01152, calculamos quanto o preço deve passar ao longo de 18 blocos do timeframe mais alto. Por este 18*Bsd = 0,0126, encontramos quantos pontos não são suficientes para que todos os blocos do timeframe mais alto sejam formados. Para este 0.0126-0.01152=0,00108, e dividimos o valor resultante pelo tamanho do bloco do timeframe mais alto. Nd=0.00108/0.0007=1.54. O resultado foi que o bloco 1.54 não é suficiente para passar para um timeframe mais alto.

O valor obtido é válido se o preço se move estritamente verticalmente, mas não se move estritamente assim, e dos 24 blocos existem apenas 18 numa direção e 6 em outra. Por isso, o bloco 1,5 deve ser recalculado no número correto de blocos para um determinado instrumento de negociação, de forma que o valor Nbd = 3 seja obtido. Por isso, na realidade, dadas as características do movimento de tendência deste instrumento de negociação, precisaremos aguardar a formação de três blocos do timeframe mais alto.

Mas apenas esperar que o número necessário de blocos de atraso (3 do exemplo) tenha passado é ineficaz. Faz sentido esperar apenas se o preço se mover na direção da tendência encontrada e a transição para um timeframe mais alto for possível. Precisamos pegar o número mínimo de blocos Nd, multiplicar pelo tamanho do bloco Bsd e afastar o número necessário de pontos em relação ao preço de fechamento do bloco do timeframe base em direção à tendência. Este será o ponto de controle ao qual o preço deve atingir para poder avançar para um timeframe mais alto. Agora, após o fechamento de cada novo bloco do timeframe superior, é necessário verificar se há blocos restantes suficientes para que o preço atinja o ponto de controle definido. 

Por exemplo: Nbd = 3 blocos, uma tendência de baixa. Calculamos o ponto de controle, ele está a uma distância de 1,54 blocos abaixo do preço de fechamento do bloco do timeframe base. Foi formado um bloco decrescente do timeframe mais alto, por isso, foi formado um bloco crescente e permaneceu 1 bloco de atraso. Não adianta esperar mais, porque se outro bloco de 1 atraso for formado, ele não cruzará mais o ponto de controle. Ficamos sabendo que não adianta dar continuação ao atraso, a transição para um timeframe alto não acontecerá, podemos abrir uma posição. 

A animação 2 mostra como isso funciona.

work 2

Animação 2.

Por exemplo, peguei uma onda senoidal. Embora a versão de trabalho não seja capaz de determinar as características estatísticas de um instrumento de negociação, eu defino a porcentagem de abertura e fechamento manualmente. Nas próximas versões, isso será implementado, e o próprio algoritmo determinará as características de um instrumento de negociação. Ele mesmo determina o tamanho dos blocos e o momento de abrir uma posição.

Pode-se observar que o teste começa com pequenos blocos, e então o algoritmo, rastreando a tendência, aumenta o tamanho do bloco. Depois que o tamanho máximo da tendência é determinado, uma posição é aberta. Em seguida, é calculado o retrocesso dessa tendência. Para uma senoide, a reversão é de 100%, por isso, o ponto de fechamento é calculado e o take profit é definido. Eu escolhi uma onda senoidal para visualizar e simplificar a compreensão do processo de trabalho. Pode-se ver que o algoritmo usa quase toda a amplitude da senoide para obter lucro, exceto por uma pequena seção 2 do bloco no início de uma nova seção de tendência.

3. Acompanhamento da série

Depois que a primeira posição na série é aberta, o algoritmo continua procurando uma oportunidade de passar para um timeframe mais alto a fim de corrigir seu trabalho e passar para timeframes maiores se a tendência continuar. Naturalmente, haverá situações em que algumas posições serão abertas num timeframe mais baixo e algumas posições serão abertas num timeframe mais alto. O tamanho da reversão sempre será calculado a partir da maior tendência que o robô encontrar.

O algoritmo resultante ignora duas condições extremas de mercado. Se o mercado estiver estável e não houver tendência em qualquer escala, e isso não for típico para este instrumento de negociação, o robô nunca iniciará uma série. Mas, se o mercado está tendo uma tendência estável, como no caso de colapsos bruscos ou crescimento do mercado, o algoritmo não será capaz de abrir uma posição, porque aumentará constantemente o timeframe até que a tendência termine. Nesse caso, os critérios para o fim da tendência serão ajustados na proporção da escala da própria tendência e da mudança nas características estatísticas do instrumento de negociação.

Fim do artigo

O objetivo principal é construir um algoritmo para o qual não importe que tipos de dados lhe são fornecidos. Se os dados de entrada não atenderem aos critérios de durabilidade, o algoritmo não operará. Assim, a tarefa não é desenvolver um algoritmo lucrativo para um mercado específico e tentar prever a direção do preço. A objetivo é tornar o algoritmo lucrativo sob certas condições e características estatísticas da série de preços. Ele só deve negociar quando essas condições forem atendidas. Se você conhece as condições sob as quais o algoritmo opera para obter lucro, não há necessidade de negociar quando essas circunstâncias não são cumpridas. Após a criação do algoritmo, é necessário agregar conhecimento sobre as características de formação do preço de mercado para aumentar a eficiência do algoritmo.

Embora a funcionalidade descrita ainda não seja suficiente para uma operação totalmente automática estável, um modelo teórico básico e uma base para a operação do algoritmo foram desenvolvidos. A quantidade de trabalho realizado é muito grande e é difícil encaixar tudo num artigo, portanto, continuarei a descrever as funções restantes e a testar o que aconteceu nos próximos artigos. 

Os parâmetros das funções desenvolvidas foram movidos para as configurações para que possam ser ajustados. As razões para definir determinado valor nas configurações do algoritmo têm uma explicação muito específica ou mesmo fórmulas pelas quais podem ser calculados. Haverá muitas configurações no algoritmo final, mas elas são necessárias para configurar o próprio algoritmo, porque ele se tornará complexo e seus módulos individuais devem interagir efetivamente uns com os outros. As configurações neste algoritmo não se destinam a ajustar os parâmetros de desempenho com base no histórico. As configurações são projetadas para otimizar a operação dos módulos e sua interação.

Anexados ao artigo estão códigos de indicadores que criam blocos na janela do gráfico e na janela do indicador. Trata-se dos mesmos indicadores diferindo na visualização. Anexei os termos de referência para esses indicadores e os termos de referência completos para a versão inicial do algoritmo.

Artigos anteriores sobre este tópico

Desenvolvendo um algoritmo de auto-adaptável (Parte I): encontrando um padrão básico
Desenvolvendo um algoritmo de auto-adaptável (Parte II): melhorando a eficiência



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

Arquivos anexados |
TZ-50cV3.zip (694.09 KB)
Trabalhando com preços na biblioteca DoEasy (Parte 61): coleção de séries de ticks para símbolos Trabalhando com preços na biblioteca DoEasy (Parte 61): coleção de séries de ticks para símbolos
Visto que diferentes símbolos podem ser usados durante a operação do programa, é necessário criar uma lista própria para cada um deles. Hoje vamos combinar essas listas numa coleção de dados de ticks. Na verdade, irá tratar-se de uma lista normal baseada numa classe de array dinâmico de ponteiros para instâncias da classe CObject e seus herdeiros da Biblioteca Padrão.
Busca de padrões sazonais no mercado de Forex usando o algoritmo CatBoost Busca de padrões sazonais no mercado de Forex usando o algoritmo CatBoost
O artigo considera a criação de modelos de aprendizado de máquina com filtros de tempo e discute a eficácia dessa abordagem. O fator humano pode ser eliminado agora simplesmente instruindo o modelo a negociar em uma determinada hora de um determinado dia da semana. A busca de padrões pode ser fornecida por um algoritmo separado.
Redes neurais de maneira fácil (Parte 10): Atenção Multi-Cabeça Redes neurais de maneira fácil (Parte 10): Atenção Multi-Cabeça
Nós já consideramos anteriormente o mecanismo de self-attention (autoatenção) em redes neurais. Na prática, as arquiteturas de rede neural modernas usam várias threads de self-attention paralelas para encontrar várias dependências entre os elementos de uma sequência. Vamos considerar a implementação de tal abordagem e avaliar seu impacto no desempenho geral da rede.
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.