Neo traderBot

Neo traderBot

Você sabia?

A NeoTraderBot é a primeira comunidade aberta no Brasil com foco em compartilhar informações sobre automatização de estratégias

leaf leftleaf right
Notifications
Clear all

[Solucionado] Ajuda na criação de um indicador utilizando desvio padrão

17 Posts
2 Usuários
1 Reactions
364 Visualizações
(@gabrieluarian)
Membro eminente
Registrou: 2 anos atrás
Posts: 16
Iniciador do tópico  

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.


   
Citar
(@admin)
Membro Admin
Registrou: 2 anos atrás
Posts: 216
 

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;

   
ReplyCitar
(@gabrieluarian)
Membro eminente
Registrou: 2 anos atrás
Posts: 16
Iniciador do tópico  

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.


   
ReplyCitar
(@gabrieluarian)
Membro eminente
Registrou: 2 anos atrás
Posts: 16
Iniciador do tópico  

a pagina nao autorizou anexar o arquivo .xlsx


   
ReplyCitar
(@admin)
Membro Admin
Registrou: 2 anos atrás
Posts: 216
 

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?


   
ReplyCitar
(@gabrieluarian)
Membro eminente
Registrou: 2 anos atrás
Posts: 16
Iniciador do tópico  

@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.


   
ReplyCitar
(@admin)
Membro Admin
Registrou: 2 anos atrás
Posts: 216
 

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!


   
ReplyCitar
(@gabrieluarian)
Membro eminente
Registrou: 2 anos atrás
Posts: 16
Iniciador do tópico  

@admin 

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.


   
ReplyCitar
(@admin)
Membro Admin
Registrou: 2 anos atrás
Posts: 216
 

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;

   
ReplyCitar
(@gabrieluarian)
Membro eminente
Registrou: 2 anos atrás
Posts: 16
Iniciador do tópico  

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.


   
ReplyCitar
(@admin)
Membro Admin
Registrou: 2 anos atrás
Posts: 216
 

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:

  1. Calcular o range do candle (Preço máximo - preço mínimo)
  2. Calcular o desvio padrão dos últimos 100 candles (no início do dia isso irá englobar candles do dia anterior...)
  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?

 

Vamos conversando para alinhar estes pontos.

Abs!


   
ReplyCitar
(@gabrieluarian)
Membro eminente
Registrou: 2 anos atrás
Posts: 16
Iniciador do tópico  

@admin 

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


   
ReplyCitar
(@gabrieluarian)
Membro eminente
Registrou: 2 anos atrás
Posts: 16
Iniciador do tópico  

Uma das tentativas que fiz foi com o seguinte código...

 

Parâmetro
Dias(10);
Var
Dif: float;
Início
Dif:= (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

 


   
ReplyCitar
(@admin)
Membro Admin
Registrou: 2 anos atrás
Posts: 216
 

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;

   
ReplyCitar
(@gabrieluarian)
Membro eminente
Registrou: 2 anos atrás
Posts: 16
Iniciador do tópico  

@admin 

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.


   
ReplyCitar
Página 1 / 2