A NeoTraderBot é a primeira comunidade aberta no Brasil com foco em compartilhar informações sobre automatização de estratégias
Utilizo no Excel uma planilha em que pego a diferença de entre Máximas e Mínimas de 100 dias e cálculo o desvio padrão de 1. Com este resultado eu coloco no price guide e utilizando o fechamento do dia anterior me dá várias linhas que uso de parâmetro para meu operacional.
vocês conseguiriam me ajudar a fazer este indicador? Já tentei de diversas formas e me falaram que seria necessário programar com uso de array, mas aí já foge muito do meu entendimento.
E aí, @gabrieluarian! Tudo bem?
Esse código deu um trabalhinho para fazer...não que fosse algo difícil...não é simples, mas se souber conceitos de arrays circulares e entender a lógica de funcionamento do Profit dá pra fazer tranquilamente.
O problema é que a Nelogica mudou o comportamento das variáveis booleanas, que agora estão resetando de valor de um dia para outro....e estas alterações de comportamento da forma como o Editor de estratégias funciona sem nenhum aviso quebra vários códigos! Eles param de funcionar ou começar a apresentar valores incorretos...Ainda não é confiável rodar robôs pelo Profit dentro do Módulo de automação devido a isto e outros problemas! Desculpa o desabafo...kkkkk!!!
Mas vamos lá...o código está abaixo. Ele calcula a média e desvio padrão do range diário dos últimos 100 dias. Falta apenas fazer os plots do que deseja de fato...mas você pode utilizar as variáveis que estão calculadas na área de plot.
Se precisar de algo é só falar! Abs!
//Código aplicável para gráficos de temporais. //Para outros tipos de gráficos teria-se que construir outra lógica //Devido ao preenchimento de gaps diários com boxes //Utiliza-se media aritmetica. Para outros tipos de médias é necessário adequar o código const cQtdeMaxRanges = 100; var aRangeDiario: array[0..99] of float; fMaxDiaAnterior, fMinDiaAnterior, fFechDiaAnterior: float; fRangeDia, fMediaRange, fDesvioPadraoRange: float; iContadorDia, iIteradorArray, iData: integer; bMediaInicializada, bCalculouRange: boolean; begin if bMediaInicializada[1] then bMediaInicializada := true; //Verifica inicio de um novo dia de negociacao if (Date <> iData) then begin iData := Date; //No primeiro candle do dia, armazena o Range do dia anterior no array e Fechamento dia anterior aRangeDiario[iContadorDia] := fMaxDiaAnterior - fMinDiaAnterior; fFechDiaAnterior := Close[1]; //Se ainda não tem 100 dias transcorridos, acumula Ranges diários if bMediaInicializada then begin fMediaRange := 0; for iIteradorArray := 0 to (cQtdeMaxRanges-1) do fMediaRange := fMediaRange + aRangeDiario[iIteradorArray]; fMediaRange := fMediaRange/cQtdeMaxRanges; end; //Calcula-se o desvio padrão da distribuição de Ranges diários if bMediaInicializada then begin fDesvioPadraoRange := 0; for iIteradorArray := 0 to (cQtdeMaxRanges-1) do fDesvioPadraoRange := fDesvioPadraoRange + Power(aRangeDiario[iIteradorArray]-fMediaRange,2); fDesvioPadraoRange := Sqrt(fDesvioPadraoRange/cQtdeMaxRanges); end; //Verifica se já passaram cQtdeMaxRanges de dias if (iContadorDia = (cQtdeMaxRanges-1)) then bMediaInicializada := true; //Incrementa-se o contador de dias de forma circular iContadorDia := Mod(iContadorDia + 1,cQtdeMaxRanges); end; //Armazena a máxima e mínima do dia no decorrer do pregão fMaxDiaAnterior := HighD(0); fMinDiaAnterior := LowD(0); //Plot - Não entendi o que deseja plotar em relação ao fechamento do dia anterior //Pode-se utilizar fMediaRange, fDesvioPadraoRange, fFechDiaAnterior if (bMediaInicializada) then begin Plot(fMediaRange); Plot2(fDesvioPadraoRange); end; end;
Bom dia, Johnatas. Tudo bem? Muito obrigado pela ajuda.
Realmente o que estava pensando em termos de código estava muito fora, pois tentava usar o "stddevs" para tentar calcular.
Na parte final ali onde não entedeu o sobre a relação ao fechamento do dia anterior é:
begin
plot (closed(1));
plot2 (closed(1) + ((fDesvioPadraoRange)*5)*1);
plot3 (closed(1) - ((fDesvioPadraoRange)*5)*1);
plot4 (closed(1) + ((fDesvioPadraoRange)*5)*2);
plot5 (closed(1) - ((fDesvioPadraoRange)*5)*2);
plot6 (closed(1) + ((fDesvioPadraoRange)*5)*3);
plot7 (closed(1) - ((fDesvioPadraoRange)*5)*3);
plot8 (closed(1) + ((fDesvioPadraoRange)*5)*4);
plot9 (closed(1) - ((fDesvioPadraoRange)*5)*4);
plot10(closed(1) + ((fDesvioPadraoRange)*5)*5);
plot11(closed(1) - ((fDesvioPadraoRange)*5)*5);
end;
Mas infelizmente ainda não está dando certo... As linhas são plotadas, mas diferente do que eu faço no calculo manual.
Vou anexar aqui o excel que utilizo. O resultado que ele me dá no ultimo dia na coluna desvio padrao 1 é dado em pontos, para usar no priceguide que é por ticks é preciso dividir por 5.
a pagina nao autorizou anexar o arquivo .xlsx
Oi @gabrieluarian!
Habilitei o upload de planilhas para o fórum. Tenta novamente por favor!
Basicamente, você quer plotar as linhas de até 5 desvios-padrão acima e abaixo do preço de fechamento do dia anterior. certo?
@admin
Exato.
No excel é feito o calculo da (Máxima-Mínima) de 100 dias anteriores. E através do resultado que ele me dá eu insiro no price guide, adiciono o valor do dia anterior e o resultado em ticks(o priceguide utiliza ticks) e ele plota as linhas acima e abaixo do dia anterior.
Oi @gabrieluarian!
Vendo a sua planilha eu entendi o que você de fato está fazendo e o que eu fiz foi diferente.
O que você está fazendo:
Pegando os últimos 100 candles e tirando a média e desvio padrão do range. Isto é quase o que o indicador ATR faz (acho que você já deve saber). A diferença é que o ATR pega o maior valor entre o Range do candle e a diferença entre max e min em relação ao fechamento da candle anterior. Ou seja, em dias de gap, podem sugir valores grandes do TR que podem afetar bastante o ATR, dependendo da quantidade de períodos.
Eu entendi pela sua explicação outra coisa...O que eu fiz:
Eu entendi que você queria a média do range diário dos últimos 100 dias, independente de qual tempo gráfico intraday você está utilizando. E iria plotar em relação ao fechamento do dia anterior uma referência de negociação para o dia atual.
Conclusão:
O código que fiz é mais elaborado pois lida com situações que você não precisa. O código pode ser bastante simplificado...depois eu posto aqui o que de fato você faz (pela planilha excel) em código.
Abs!
Eu pego os ultimos 100 candles do grafico diário calculo a "Máxima-Mínima" deles e desse resultado é feito o desvio padrão... Dependendo da volatilidade eu coloco 1 ou 1,5 o desvio.
Tentei por diversas vezes algo parecido com o ATR usando fazendo um averagetruerange, mas nunca obtive sucesso.
E ai @Gabrieluarian!
O código que você está querendo é bem mais simples. Acredito que o código abaixo já irá atender a sua necessidade.
Abs!
const cQtdeMaxRanges = 100; var i: integer; fRangeCandle: Serie; fDesvioPadraoRange: float; begin fRangeCandle := High - Low; fDesvioPadraoRange := StdDevs(fRangeCandle,cQtdeMaxRanges); //Plot for i:=1 to 5 do begin PlotN(i+1, Close + i*fDesvioPadraoRange); PlotN(i+6, Close - i*fDesvioPadraoRange); end; SetPlotColor(2,clGreen); SetPlotColor(7,clGreen); SetPlotStyle(2,psDash); SetPlotStyle(7,psDash); SetPlotColor(3,clOlive); SetPlotColor(8,clOlive); SetPlotStyle(3,psDash); SetPlotStyle(8,psDash); SetPlotColor(4,clYellow); SetPlotColor(9,clYellow); SetPlotStyle(4,psDash); SetPlotStyle(9,psDash); SetPlotColor(5,clRed); SetPlotColor(10,clRed); SetPlotStyle(5,psDash); SetPlotStyle(10,psDash); end;
Bom dia, Johnatas. Tudo bem?
Infelizmente não é este código, o primeiro acredito que estava mais próximo...
Este segundo não traça as linhas na horizontal como fica quando inserido o price guide e as linhas ficam muito próximas.
Estou encaminhando o print de como fica na minha tela quando insiro o valor que deu do desvio de padrao de 829 (que foi de Sexta) e ele no price guide na segunda.
Bom dia, @Gabrieluarian!
Cara, estamos tendo um problema de comunicação...e isto é uma dificuldade comum sempre surge quando contratamos alguém para programar algo para nós...rsrsr....Acontece com desenvolvimento de software em geral...não é algo só de automatização de estratégias. A gente chega lá!
Agora, com essa sua imagem....ficou um pouco mais claro para mim o que você faz (Eu nem conhecia esse "Price guide"...rsrs). O que eu fiz no último código é o que você fez na planilha. Mas acho que talvez os requisitos não estejam 100% definidos...vou colocar abaixo o que eu entendi agora para que você confirme se é isso mesmo:
Vamos conversando para alinhar estes pontos.
Abs!
Boa tarde, tudo bem?
Acho que eu já faço isso a tanto tempo que ficou meio que automático... rsrsrs talvez por isso a minha falha em tentar explicar.
O "Price Guide" utilizo para nao ter que ficar colocando as linhas uma por uma todo dia rsrsrs.
Vou utilizar seu passo a passo para tentar explicar melhor como é feito.
1. Calcular o range do candle (Preço máximo - preço mínimo) - Lembrando que o range de (máxima-mínima) é feita no gráfico diário.
2. Calcular o desvio padrão dos últimos 100 candles (no início do dia isso irá englobar candles do dia anterior...) - Talvez seja aqui onde está a complicação na comunicação.
O Desvio Padrão (de 1 ou 1,5 dependendo da volatilidade) é calculado em cima do resultado da diferença (Maxima-Mínima) dos 100 dias passados do gráfico diário.
O resultado desse desvio padrão me dá um valor em pontos. Este valor que eu uso para as distâncias multiplas.
3.Plotar linhas horizontais em relação a um preço de referência com distâncias múltiplas de um valor. Qual seria a referência: preço de abertura do dia? Qual seria a distância entre as linhas: o desvio padrão do range dos últimos 100 candles na frequencia do gráfico?
A base de referência para plotar é o fechamento do dia anterior. A partir dele é iniciado plot das distâncias multiplas em cima do valor do desvio padrão.
Acho que agora consegui explicar como é feito certinho até jogar lá no price guide. rsrsrs
Uma das tentativas que fiz foi com o seguinte código...
ParâmetroDias(10);VarDif: float;InícioDif:= (highd(dias) - lowd(dias));Plot(closed(1));Plot2 ((closed(1) + (stddevs(dif,1)))*1);Plot3 ((closed(1) - (stddevs(dif,1)))*1);Plot4 ((closed(1) + (stddevs(dif,1)))*2);Plot5 ((closed(1) - (stddevs(dif,1)))*2);Fim;
porém foi tentativa frustrada rsrsrs
E aí, @gabrieluarian!
Tudo bem!? Foi mal a demora...estava apertado com outras demandas por aqui.
Refiz o código e acho que agora está da forma esperada.
Deixei como constantes a quantidade de dias que deseja obter o desvio padrão (cQtdeMaxRanges), bem como a quantidade de linhas que deseja plotar acima e abaixo do fechamento do dia anterior (cQtdeLinhasStdevs).
Esse código roda corretamente independente do tempo gráfico intradiário que utilizar.
Qualquer coisa, estamos por aqui!
Grande abs!
//Código aplicável para gráficos de temporais. //Para outros tipos de gráficos teria-se que construir outra lógica //Devido ao preenchimento de gaps diários com boxes //Utiliza-se media aritmetica. Para outros tipos de médias é necessário adequar o código const cQtdeMaxRanges = 100; cQtdeLinhasStdevs = 5; var aRangeDiario: array[0..99] of float; fMaxDiaAnterior, fMinDiaAnterior, fFechDiaAnterior: float; fRangeDia, fMediaRange, fDesvioPadraoRange: float; iContadorDia, iIteradorArray, iData: integer; bMediaInicializada, bCalculouRange: boolean; iStd: integer; begin if bMediaInicializada[1] then bMediaInicializada := true; //Verifica inicio de um novo dia de negociacao if (Date <> iData) then begin iData := Date; //No primeiro candle do dia, armazena o Range do dia anterior no array e Fechamento dia anterior aRangeDiario[iContadorDia] := fMaxDiaAnterior - fMinDiaAnterior; fFechDiaAnterior := CloseD(1); //Se ainda não tem 100 dias transcorridos, acumula Ranges diários if bMediaInicializada then begin fMediaRange := 0; for iIteradorArray := 0 to (cQtdeMaxRanges-1) do fMediaRange := fMediaRange + aRangeDiario[iIteradorArray]; fMediaRange := fMediaRange/cQtdeMaxRanges; end; //Calcula-se o desvio padrão da distribuição de Ranges diários if bMediaInicializada then begin fDesvioPadraoRange := 0; for iIteradorArray := 0 to (cQtdeMaxRanges-1) do fDesvioPadraoRange := fDesvioPadraoRange + Power(aRangeDiario[iIteradorArray]-fMediaRange,2); fDesvioPadraoRange := Sqrt(fDesvioPadraoRange/cQtdeMaxRanges); end; //Verifica se já passaram cQtdeMaxRanges de dias if (iContadorDia = (cQtdeMaxRanges-1)) then bMediaInicializada := true; //Incrementa-se o contador de dias de forma circular iContadorDia := Mod(iContadorDia + 1,cQtdeMaxRanges); end; //Armazena a máxima e mínima do dia no decorrer do pregão fMaxDiaAnterior := HighD(0); fMinDiaAnterior := LowD(0); //Plot - Não entendi o que deseja plotar em relação ao fechamento do dia anterior //Pode-se utilizar fMediaRange, fDesvioPadraoRange, fFechDiaAnterior if (bMediaInicializada) then begin Plot(fFechDiaAnterior); SetPlotColor(1,clGreen); SetPlotWidth(1,2); for iStd := 2 to (cQtdeLinhasStdevs +1) do begin PlotN(iStd, fFechDiaAnterior + (iStd-1)*fDesvioPadraoRange); PlotN(iStd + cQtdeLinhasStdevs, fFechDiaAnterior - (iStd-1)*fDesvioPadraoRange); SetPlotColor(iStd, clWhite); SetPlotColor(iStd + cQtdeLinhasStdevs, clWhite); SetPlotStyle(iStd, psDash); SetPlotStyle(iStd + cQtdeLinhasStdevs, psDash); end; end; end;
Caramba... ficou PERFEITO!! agradeço muito ajuda.
Agora é comigo, vou tirar uns dias aqui para estudar a automação usar este junto do IFR automatizar a estratégia que uso.
Vão me ver muito por aqui ainda rsrsrs...
Ótima semana para nós.