O que precisa saber antes de começar…
Neste documento vamos apresentar aspectos importantes antes que você comece a criar seu robô ou outro tipo de estratégia (indicador, coloração, screening).
Se fossemos classificar as dúvidas apresentadas por pessoas nas redes sociais sobre automatização de estratégias, dividiríamos em 3 grupos: Dúvidas de lógica de programação, Dúvidas sobre funções do Editor de Estratégias e Dúvidas sobre como implementar o operacional desejado.
Para as dúvidas de lógica de programação não há muito segredo, basta fazer um curso introdutório no assunto. Clique aqui e assista à primeira aula do Curso Básico de Lógica de Programação da NeoTraderBot (disponível em uma playlist no Youtube). Trata-se de um curso bem objetivo e que tem a meta de em 5 vídeos curtos te explicar os principais conceitos sobre lógica de programação, sendo o último vídeo uma aula prática de Pascal que é a linguagem de programação mãe da NTSL. Caso ainda não saiba, a NTSL é a sigla para Nelogica Trading System Language, que é a linguagem adaptada do Pascal para uso no Profit Chart.
Para as dúvidas relacionadas às funções do Editor de Estratégias…eu acho bastante compreensível a existência delas. Acredito até que haja mais dúvidas que o esperado devido ao fato da documentação da Nelógica ser muito ruim, além de ser difícil achar boas referências pela Internet (principalmente gratuitas). Pensando nisso, estamos estruturando uma área neste site, aberta para qualquer visitante, explicando melhor as funções embutidas no editor de estratégias, com exemplos e comentários das dúvidas mais frequentes. Além disso, haverá uma seção de Templates (modelos para montar suas estratégias) e Snipets (trechos de código fontes prontos para você utilizar como exemplo e acelerar o seu desenvolvimento).
Chegamos então a parte principal deste texto e que se relaciona com as dúvidas referentes à implementação de setups operacionais.
Algumas dessas dúvidas sobre implementação de operacionais podem recair sobre limitações já conhecidas do Profit. Assista este vídeo que é bem interessante e trata sobre as Limitações do Profit referentes à automatização de estratégias. No decorrer deste texto abordaremos tópicos diferentes, porém complementares.
Ok…Se tirarmos aquilo que o Profit não permite fazer, e que esperamos que sejam disponibilizadas melhorias para sanar, teremos as dúvidas que derivam do fato de as pessoas não entenderem como funciona o processamento das estratégias no Profit. Se os traders que estão buscando automatizar as estratégias entendessem sobre isso, talvez mais da metade dos problemas já seriam resolvidos.
Então vamos abordar a seguir dois pontos muito importantes que você deve saber antes de implementar estratégias no Profit Chart, incluindo robôs: Modelo de dados utilizado pelo Profit e Processamento das Estratégias.
Modelo de dados OHLCV
O modelo de dados utilizado pelo Profit é o OHLCV. Este é o modelo usado por quase 100% das plataformas de backtesting e a sigla OHLCV significa Open, High, Low, Close e Volume.
Trata-se dos dados de preço e volume disponibilizados para realização de backtesting. Quanto maior for a frequência demandada de dados, por exemplo, dados de 1 minuto, maior é o espaço demandado para armazenamento dessas informações.
Se fossemos salvar em nosso computador os dados de cada tick, ou seja, para cada alteração mínima de preço do ativo que estamos negociando, precisaríamos de muito espaço e banda de internet para requisitar os dados. Então torna-se impraticável disponibilizar por padrão dados tick a tick…É claro que isto poderia ser fornecido sob demanda, para não sobrecarregar sua plataforma e os servidores da Nelógica (se houvesse funcionalidade para tal no Profit!).
Então quando realizamos backtesting de uma estratégia, nós não temos os dados tick a tick, temos apenas dados por candle fechado, os já mencionados OHLCV.
Grandes empresas do mercado financeiro operam algoritmos em alta frequencia, em inglês, High Frequency Trading. Mas eles tem muito dinheiro, os melhores recursos de TI e mentes brilhantes (vários PHDs) para programar e monitorar os algoritmos. Além disso, eles colocam os melhores servidores possíveis de se adquirir, que executam seus algoritmos dentro da B3, fisicamente ao lado dos servidores da B3, a poucos metros de cabo de distância, para reduzir ao máximo a latência, que é o tempo entre envio e a execução da ordem.
Para se ter uma ideia…se quando enviamos uma ordem para nossa corretora, o processo demora 100 milisegundos para a execução, a ordem dessas empresas leva 1 milisegundo para ser executada. Esses não são os valores exatos, é só para ilustrar que a diferença entre a sua latência e deles é muito significativa!
E se isso foi técnico demais, visualize essa cena…você está em uma pista de fórmula 1, dentro de um fusca e vai apostar uma corrida contra um trader de um grande fundo que opera HFT, só que ele está pilotando um Bugatti Veyron…
Acho melhor não compertirmos com esses caras….Nossa chance de sucesso é quase nula!
E por quê estamos tanto tempo falando sobre isso? Para concluirmos que tentar implementar estratégias SCALP, que dependam de dados tick a tick, não é viável para nós pobres mortais. Nós até conseguimos rodar uma estratégia em tempo real utilizando dados tick a tick, mas não conseguimos fazer backtesting tick a tick, porque não temos os dados, e mesmo se tivéssemos precisaríamos ter um supercomputador para armazenar os dados e processar esse enorme volume de informação. E se não temos como fazer um backtesting adequado, colocar um robô para executar é como jogar na sorte…Não é o que queremos! Queremos rodar um robô que em backtesting tenha um histórico de desempenho favorável para nos dar confiabilidade para rodá-lo em conta real.
O dado OHLCV de maior frequência que conseguimos ter acesso no Profit Chart são dados de 1 minuto, e mesmo assim, atualmente, só conseguimos acessar os 3 últimos meses históricos. Este volume de dados é insuficiente para otimizar e realizar backtesting com confiabilidade adequada. Ou seja, se quiséssemos implementar uma estratégia para gráficos de 1 minuto, encontraríamos também bastante dificuldade.
Então uma dica importante é que as estratégias automatizadas começam a ser uma realidade factível com dados de 5 minutos em diante. A partir dessa frequência gráfica, você começa a ter mais chance de sucesso.
Processamento de Estratégias
Se entendermos bem o que está exposto abaixo, teremos a capacidade de resolver muito mais rapidamente eventuais problemas na hora de implementar nossas estratégias, ou talvez, até não tenhamos tantos problemas assim.
Toda estratégia no Profit Chart é processada sequencialmente, linha a linha, começando pelo begin do seu código fonte até o end.
Para cada novo dado, que em backtesting é sempre um novo candle ou renko fechado, a estratégia é processada novamente. Então se você tivermos, por exemplo, uma janela histórica de dados com 2000 elementos, a estratégia será processada 2000 vezes. Ou seja, uma vez para cada elemento de dado OHLCV, começando pelo mais antigo até o mais recente.
O pulo do gato está nas variáveis globais e a forma como elas são tratadas ao longo dos processamentos.
Por mais que declaremos variáveis globais com tipos básicos como integer ou float, no final das contas, as variáveis globais podem ser tratadas como arrays, ou no vocabulário da Nelogica, como séries. O que isto significa? Vamos a um exemplo.
Suponha que eu tenhamos uma variável global do tipo integer chamada iNum que é inicializada com o valor 1. E o código fonte da estratégia será apenas a atribuição iNum = iNum + 1. No primeiro processamento, antes de executar a linha de atribuição de iNum, iNum tem o valor 1, depois que executar a atribuição, iNum terá o valor igual a 2., Na próxima execução, iNum começa como 2, mas depois de rodar a linha de atribuição iNum será igual a 3.
Perceba uma coisa interessante, os valores das variáveis globais são mantidos de um processamento para o próximo processamento. E, além disso, outro ponto importante é que cada execução do seu código empilha os valores das variáveis globais.
Apesar de termos declarado iNum como um integer, esta variável pode ser acessada como se fosse um array. Se fizéssemos a referência de iNum[1], estaríamos acessando o valor de iNum da última execução (no caso, 6). Se nos referíssemos a iNum[2] estaríamos acessando o valor de iNum 2 barras antes do momento atual (no caso, 5), e assim por diante.
Compreender o empilhamento das variáveis globais é muito importante, pois fará diferença na hora de você implementar a sua estratégia/robô.
Um ponto importante a salientar é que, infelizmente, não temos como inicializar as variáveis globais antes de executar o robô ou da estratégia. É uma limitação da plataforma, mas nesse caso ainda tem como dar um jeitinho. Os templates disponibilizados aqui no site da NeoTraderBot já contemplam uma forma de inicializar as variáveis globais.
Seguindo….Como verificamos o impacto de executar o código da estratégia em backtesting apenas quando uma barra é encerrada? Se tivermos uma estratégia aplicada no backtesting a gráficos de 5 minutos, essa estratégia só vai atuar depois que fechar 5 minutos. Se a estratégia disparar uma ordem de compra ou venda a mercado, ela será executada apenas no preço de abertura da próxima barra de dados. Isso ocorre para manter premissas mais coerentes de simulação, uma vez que como não há informação sobre a dinâmica de movimento do preço dentro de uma barra fechada, o preço à mercado só pode ria ser o preço de abertura da próxima barra.
Veja o exemplo abaixo de um robô baseado em um setup de cruzamento de 3 médias, a ordem de compra/venda é realizada no candle no qual há o cruzamento da média, mas a execução sempre ocorre no preço de abertura da próxima barra.
É muito importante entender este aspecto do backtesting porque quando se roda um robô ou estratégia em tempo real, o novo dado OHLCV não é necessariamente de uma barra fechada. Para cada tick, antes de encerrar a barra de 5 minutos, o código da sua estratégia é processado. Então, se não forem tomados os devidos cuidados na programação, o comportamento em tempo real do robô será diferente do comportamento em backtesting…porque no backtesting não havia os dados tick a tick….e isso pode fazer uma grande diferença de desempenho….para melhor ou pior…não tem como saber.
Enquanto o Profit apenas permitia visualizar a estratégia de execução nos gráficos isso era um problema pequeno, porque não efetivava nenhuma ordem automaticamente…mas a partir do momento que os robôs puderem ser executados em conta real, e isto poderá ocorrer agora dia 29/setembro com o lançamento oficial do módulo de Automação de Estratégias, precisaremos ser ainda mais criterioso na escrita do código fonte das estratégias. Se quisermos manter o mesmo comportamento entre backtesting e conta real (e o ideal é isso mesmo), precisaremos garantir que as ações geradas pelo robô sejam feitas apenas no fechamento de uma barra.
É importante observar que na execução de uma estratégia em tempo real, a referência a uma variável global, mesmo que implícita (série de dados de preço do ativo), tal como High ou Máxima, um período antes será sempre o valor da variável global da barra fechada anterior (ex: HIgh[1] é sempre o preço máximo da barra fechada anterior e não o valor no tick anterior!). O valor atual da variável global não será empilhado, pois a barra está aberta, ele será apenas atualizado para cada processamento do código da estratégia, ocorrendo o empilhamento apenas quando a barra atual fechar.
Bônus: Dicas de Backtesting
Por fim, um ponto muito importante para realização adequada de backtesting de uma estratégia é SER CONSERVADOR!
É muito fácil fazer backtesting de estratégias com um desempenho tão incrível que nos faria milionários em pouco tempo de execução na conta real. Sempre desconfie desses bons resultados! Geralmente é sinal de que há algum problema no código fonte da estratégia. Ainda que não tenha gerado erro de compilação, pode ter gerado uma situação não factível no mundo real.
Uma situação muito frequente, seja por desconhecimento ou inexperiência, é programar as estratégias de execução (robôs) com ordens OCO, ou seja, com ordens de stoploss e take profit, enviando primeiramente a ordem de take profit.
Isto não é uma boa prática porque como no backtesting lidamos apenas com dados de barra fechada, o simulador não tem como saber dentro de uma barra OHLCV que engloba tanto o preço do stop quanto do take profit, qual preço foi atingido primeiro.
O simulador então utilizará a ordem que foi enviada primeiro. Assim, é uma boa prática sempre colocar o envio de ordens de stoploss antes das ordens de take profit. Fazendo isso, estaremos sendo conservadores. O desempenho da estratégia pode até ser pior do que seria se houvesse dados de tempo real, mas estremos gerenciando melhor nossa expectativa em relação ao desempenho provável em conta real.
Outra boa prática de backtesting é analisar a sensibilidade do robô a condições de Slippage.
Slippage é o escorregamento de preço de ordens enviadas para corretora. O que significa isso? É a diferença entre o preço da ordem enviada e o preço de execução. Por exemplo, se enviamos uma ordem de compra a mercado quando determinado ativo é negociado a R$ 23,50, mas a ordem acaba sendo executada a R$ 23,53, tivemos um slippage de 3 centavos.
Felizmente, no Profit Chart é possível simular o desempenho de um robô com slippage de forma bem simples, bastando informar a quantidade de ticks. O slippage será aplicado para cada ordem a mercado enviada. Veja na figura abaixo onde configurar o slippage no backtesting.
Finalizando...
Se achou interessante o conteúdo deste documento e acha que existem outros pontos a serem conhecidos antes que um trader implemente sua primeira estratégia automatizada, deixe seu comentário abaixo!
Nos próximos documentos passaremos enfim para a parte prática: escrever as estratégias em código fonte!
Olá, sou leigo quanto a programação. Entretanto, um dedicado estudioso e amante do mercado financeiro. Sobre o modelo de dados OHLCV, é possível estruturar comandos de execução de ordens apenas baseados na máxima ou mínima do candle anterior tendo como ponto base seu volume?
Té + parabéns pelo trabalho.