A NeoTraderBot é a primeira comunidade aberta no Brasil com foco em compartilhar informações sobre automatização de estratégias
Objetivo do código: Calcular de forma precisa a volatilidade de preço de um ativo, desconsiderando efeito de Gap de abertura
Motivação: Indicador para compor um conjunto de ferramentas base para que traders possam elaborar estratégias e robôs
Observações importantes: O Indicador está disponível GRATUITAMENTE COM CÓDIGO FONTE ABERTO no Profit Char. Este ambiente destina-se a coletar sugestões e aperfeiçoarmos o indicador de maneira colaborativa.
Link Youtube com explicação do indicador.
Versão 1.0
input pQtdePeriodosVolat(100); var fMediaMax, fMediaMin, fMediaVolatilidade: float; begin if GraphicInterval = itMinute then begin fMediaMax := Summation(High,pQtdePeriodosVolat); fMediaMin := Summation(Low,pQtdePeriodosVolat); fMediaVolatilidade := (fMediaMax - fMediaMin)/pQtdePeriodosVolat; Plot(fMediaVolatilidade); end; end;
Muito bom esse indicador. Tenho feito alguns testes e estou querendo acrescentar uma estratégia de execução, porém não estou conseguindo inserir uma Média Móvel Exponencial de 9 dentro desse indicador. Eu tentei fazer conforme está no código que eu modifiquei, mas as duas médias parecem estar em escalas diferentes. Poderia me ajudar?
input pQtdePeriodosVolat(50); pMediaRapida(9); var fMediaMax, fMediaMin, fMediaVolatilidade, fEMA9 : float; begin if GraphicInterval = itMinute then begin fMediaMax := Summation(High,pQtdePeriodosVolat); fMediaMin := Summation(Low,pQtdePeriodosVolat); fMediaVolatilidade := (fMediaMax - fMediaMin)/pQtdePeriodosVolat; Plot(fMediaVolatilidade); fEMA9 := MediaExp(pMediaRapida, Fechamento); Plot2(fEMA9); SetPlotColor(2,clBlue); end; end;
Oi @estevao-cruz-da-mott! Tudo bem?
Cara, o plot do indicador refere-se à media do range das barras (Máximo - mínimo de cada barra). Vamos supor o caso no WIN no tempo gráfico de 5 min: estariamos falando de um valor que oscila entre 300 a 400 pts.
Quando você inseriu o cálculo de média (variável fEMA9) você fez isso utilizando a série de dados de preço de fechamento do ativo. No caso do WIN, isso vai ser algo em torno de 114 mil.
Se você deseja calcular a média exponencial da volatilidade, você teria que criar a variável fRange (atribuir o range das barras) e modificar a chamada da função de MediaExp, conforme código abaixo:
input pQtdePeriodosVolat(50); pMediaRapida(9); var fMediaMax, fMediaMin, fMediaVolatilidade, fEMA9 : float; fRange: float; begin if GraphicInterval = itMinute then begin fMediaMax := Summation(High,pQtdePeriodosVolat); fMediaMin := Summation(Low,pQtdePeriodosVolat); fMediaVolatilidade := (fMediaMax - fMediaMin)/pQtdePeriodosVolat; Plot(fMediaVolatilidade); fRange := High - Low; fEMA9 := MediaExp(pMediaRapida, fRange); Plot2(fEMA9); SetPlotColor(2,clBlue); end; end;
Grande abs!
Valeu Jhon. Mais uma lição importante!kk
Muito Obrigado!
Boa tarde Johnathas. Tudo bem?
Cara, eu fiz a estrategia de execução baseado nesse indicador(período de 50d) + média móvel exponencial de 9 que você me ajudou a configurar na resposta acima. Eu fiquei realmente surpreso com o desempenho do robô quando rodado no backtest (Ativo WINFUT: Tempo gráfico de 15minutos, take profit 250pts e stope loss de 175pts). Realmente o robô se mostra muito consistente e alta taxa de acerto.
Também fiz o teste no simulador com ordens OCO com breakeven de 150pts e parcial de 200pts e alvo final de 300 pontos (Tempo gráfico de 5 minutos e 10 minutos). Percebi que o desempenho ficou ainda melhor!!
Acontece que o Profit está dando bug no BackTest do editor de estratégia quando eu tento rodar no Tempo gráfico de 10 minutos ou 30 minutos. O ProfitChart apresenta um bug como se, apartir de uma data, o robô tivesse parado de executar ordens.
Eu ficarei imensamente grato se você puder testar o código nas condições que eu falei acima (no tempo gráfico de 15 minutos do WINFUT) e desse uma opinião a respeito. Tenho você como referência sobre programação e seria de extremo valor ter algum conselho.
// ----------------------------------------------------------------------- // ---------------------- DADOS DA ESTRATÉGIA ---------------------------- // ----------------------------------------------------------------------- // // NOME DA ESTRATÉGIA: _VMME // DESENVOLVIDO POR: Estevão Cruz da Motta // DATA DE CRIAÇÃO: 01/2023 // VERSÃO: 1.0 // ATUALIZADA EM: // TIPO DE ESTRATÉGIA: (X) Indicador (X) Coloração (X) Execução // ( ) Screening ( ) Texto ( ) Alarme // // DESCRIÇÃO DA ESTRATÉGIA: // Identificar falso rompimento em padrões de 2 candles e avaliar em // confluência com o indicador de Volatilidade Média as melhores oportunidades // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // // ######################### FIM DO CABEÇALHO ############################ input pQtdePeriodosVolat(50); pMediaRapida(9); var fMediaMax, fMediaMin, fMediaVolatilidade, fEMA9 : float; fRange: float; bSinalCompra, bSinalVenda : boolean; bSinalIndc, bSinalIndv : boolean; begin if GraphicInterval = itMinute then begin fMediaMax := Summation(High,pQtdePeriodosVolat); fMediaMin := Summation(Low,pQtdePeriodosVolat); fMediaVolatilidade := (fMediaMax - fMediaMin)/pQtdePeriodosVolat; Plot(fMediaVolatilidade); fRange := High - Low; fEMA9 := MediaExp(pMediaRapida, fRange); Plot2(fEMA9); SetPlotColor(2,clBlue); ////SINAL E REGRA DE COLORAÇÃO//// bSinalCompra := (Fechamento > Fechamento[1]) e (Minima < Minima[1]) e (Maxima < Maxima[1]); Se (bSinalCompra) entao begin Paintbar(clGreen); end; bSinalVenda := (Fechamento < Fechamento[1]) e (Minima > Minima[1]) e (Maxima > Maxima[1]); Se (bSinalVenda) entao begin Paintbar(clRed); end; ///"NÃO EXECUTAR O SINAL SE..."(condições/restrições)://// /// Restrições com Médias Móveis para COMPRA///// bSinalIndc := (fMediaVolatilidade > fEMA9) e bSinalCompra; bSinalIndv := (fMediaVolatilidade < fEMA9) e bSinalVenda; end; Se (Isbought) entao Início SellToCoverLimit(BuyPrice+250); SellToCoverStop(BuyPrice-175); Fim; Se (IsSold) entao Início BuyToCoverLimit(SellPrice-250); BuyToCoverStop(SellPrice+175); Fim; Se (BuyPosition = 0) e (SellPosition = 0) entao Inicio Se (bSinalIndc) então BuyAtMarket; Se (bSinalIndv) então SellShortAtMarket; end; end;
Se conseguir explicar também porquê é que o Profit está dando esse bug quando a estratégia roda nos 10 minutos e 30 minutos (no backtest do editor) eu ficarei muito feliz.
Mais uma vez obrigado pela ajuda!
O que aconteceu com você é bem comum quando se utiliza gráficos temporais maiores. Sua estratégia ficou presa na sua lógica de stop loss.
O que isso significa? Em alguns momentos, você abriu uma posição no preço de abertura de uma barra. Essa barra andou contra a sua posição o suficiente para o seu gatilho de stop não estar no range da próxima barra. Assim, sua estratégia ficou presa...você ficou posicionado e o Profit não encerrou mais a posição.
Fiz dois ajustes pontuais no seu código, logo abaixo das ordens stops para evitar essa armadilha. Agora o backtesting em 15 minutos está executando ordens em toda a janela histórica. (Segue código abaixo).
Caso sua estratégia seja de daytrade, sugiro colocar as restrições temporais para abertura de posição e encerramento no mesmo dia.
Quanto a uma estratégia ser boa ou não, depende não apenas do valor absoluto que você obtém no backtesting, mas também da comparação desse retorno com outras formas de investimento. Ex: se você deixasse seu dinheiro na renda fixa, e ele rendesse mais do que sua estratégia, certamente a estratégia não seria uma boa opção. Lembrando também que o backtesting pode ser melhorado utilizando os custos de operação e slippage.
Enfim, validar uma estratégia em backtesting que apresente bons resultados é algo difícil e muito oneroso em termos de tempo de simulação, otimização e análise.
Grande abs!
// ----------------------------------------------------------------------- // ---------------------- DADOS DA ESTRATÉGIA ---------------------------- // ----------------------------------------------------------------------- // // NOME DA ESTRATÉGIA: _VMME // DESENVOLVIDO POR: Estevão Cruz da Motta // DATA DE CRIAÇÃO: 01/2023 // VERSÃO: 1.0 // ATUALIZADA EM: // TIPO DE ESTRATÉGIA: (X) Indicador (X) Coloração (X) Execução // ( ) Screening ( ) Texto ( ) Alarme // // DESCRIÇÃO DA ESTRATÉGIA: // Identificar falso rompimento em padrões de 2 candles e avaliar em // confluência com o indicador de Volatilidade Média as melhores oportunidades // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // // ######################### FIM DO CABEÇALHO ############################ input pQtdePeriodosVolat(50); pMediaRapida(9); var fMediaMax, fMediaMin, fMediaVolatilidade, fEMA9 : float; fRange: float; bSinalCompra, bSinalVenda : boolean; bSinalIndc, bSinalIndv : boolean; begin if GraphicInterval = itMinute then begin fMediaMax := Summation(High,pQtdePeriodosVolat); fMediaMin := Summation(Low,pQtdePeriodosVolat); fMediaVolatilidade := (fMediaMax - fMediaMin)/pQtdePeriodosVolat; Plot(fMediaVolatilidade); fRange := High - Low; fEMA9 := MediaExp(pMediaRapida, fRange); Plot2(fEMA9); SetPlotColor(2,clBlue); ////SINAL E REGRA DE COLORAÇÃO//// bSinalCompra := (Fechamento > Fechamento[1]) e (Minima < Minima[1]) e (Maxima < Maxima[1]); Se (bSinalCompra) entao begin Paintbar(clGreen); end; bSinalVenda := (Fechamento < Fechamento[1]) e (Minima > Minima[1]) e (Maxima > Maxima[1]); Se (bSinalVenda) entao begin Paintbar(clRed); end; ///"NÃO EXECUTAR O SINAL SE..."(condições/restrições)://// /// Restrições com Médias Móveis para COMPRA///// bSinalIndc := (fMediaVolatilidade > fEMA9) e bSinalCompra; bSinalIndv := (fMediaVolatilidade < fEMA9) e bSinalVenda; end; Se (Isbought) entao Início SellToCoverLimit(BuyPrice+250); SellToCoverStop(BuyPrice-175); if Close <= BuyPrice-175 then ClosePosition; Fim; Se (IsSold) entao Início BuyToCoverLimit(SellPrice-250); BuyToCoverStop(SellPrice+175); if Close >= SellPrice+175 then ClosePosition; Fim; Se (BuyPosition = 0) e (SellPosition = 0) entao Inicio Se (bSinalIndc) //and (Time <= 1630) então BuyAtMarket; Se (BuyPosition = 0) e (SellPosition = 0) entao Se (bSinalIndv) //and (Time <= 1630) então SellShortAtMarket; end; end;
Muito obrigado pelas orientações.
Estou fazendo alguns simuladores da estratégia no m1 e estou me surpreendendo com os resultados.
A partir de amanhã vou rodar em conta real com 1 contrato. Vou deixar rodando no profit em uma nuvem da amazon (aws). Quero fazer um teste no mês de fevereiro já que o backteste está apresentando uma alta taxa de acerto com um gerenciamento conservador.