Neo traderBot

Neo traderBot

Você sabia?

Um backtesting adequado deve buscar simular situações práticas do mercado (slippage, custo de operação, etc...)

Códigos de exemplo? Tome Snippets!

Implementação de estratégias

Leitura estimada: 5 minutos 958 views

Introdução

Esta seção visa apresentar trechos de códigos com exemplos de tarefas comuns para implementação de estratégias.

Você pode acessar os Snippets diretamente pelo menu lateral direito, ou fazendo CRL+F (CTRL+L) para localizar algum texto específico na página, uma vez que o conteúdo tende a crescer ao longo do tempo, dificultando a navegação pelo menu.

Caso tenham sugestões de código para acrescentar à lista, gentileza deixar o código nos comentários com o link para seu perfil em rede social (para devido crédito de autoria).

Snippets

Cruzamento simples entre 2 séries

Reproduzir vídeo

O exemplo abaixo visa identificar quando há um cruzamento simples entre duas séries, considerando apenas o instante atual e anterior.

				
					var
  fMedia1, fMedia2: float;
  iCruzamento: integer;


function NTB_ArredondarFloat(Value: float; nCasas: integer):float;
var
    fValor: float;
    fParteInteira: float;
    fParteDecimal: float;
begin
  fValor := Value;
  fParteInteira := IntPortion(fValor);
  fParteDecimal := Round((fValor - fParteInteira)*Power(10,nCasas));

  Result := fParteInteira + fParteDecimal/Power(10,nCasas);
end;


begin
  iCruzamento := 0;
  fMedia1 := NTB_ArredondarFloat(Media(10,Close),2);
  fMedia2 := NTB_ArredondarFloat(Media(20,Close),2);

  if  (fMedia1 > fMedia2)
  and (fMedia1[1] <= fMedia2[1]) then
    iCruzamento := 1;

  if (fMedia1 < fMedia2)
  and (fMedia1[1] >= fMedia2[1]) then
    iCruzamento := -1;

  if iCruzamento = 1 then
  begin
    // O que fazer quando houver cruzamento para cima?
    PlotText("Cruzou acima", clGreen, -1,12);
  end;

  if iCruzamento = -1 then
  begin
    // O que fazer quando houver cruzamento para baixo?
    PlotText("Cruzou abaixo", clRed, -1,12);
  end;

  //Plot apenas para visualizar graficamente o funcionamento
  //do código
  Plot(fMedia1);
  Plot2(fMedia2);
  SetPlotColor(1,clRed);
  SetPlotWidth(1,2);  
  SetPlotColor(2,clWhite);
  SetPlotStyle(2,psDash);  
  SetPlotWidth(2,2);  

end;
				
			

Cruzamento simples entre 2 séries com percentual de cruzamento

O exemplo abaixo visa identificar quando há um cruzamento simples entre duas séries, considerando apenas o instante atual e anterior, e desde que o cruzamento seja superior a um determinado valor percentual.

				
					const
  //Constante fornecida em percentual. Ex: 0.1 significa 0.1%
  fPercCruzamento = 0.1;
var
  fMedia1, fMedia2: float;
  iCruzamento: integer;

begin
  iCruzamento := 0;
  fMedia1 := Media(10,Close);
  fMedia2 := Media(20,Close);    

  //Plot apenas para visualizar graficamente o funcionamento
  //do código
  Plot(fMedia1);
  Plot2(fMedia2); 

  if (fMedia1 <> 0) and (fMedia2 <> 0) then
  begin

    if  (fMedia1 > fMedia2)
    and (fMedia1[1] <= fMedia2[1])
    and (((fMedia1-fMedia2)/fMedia1*100) >= fPercCruzamento)
    then iCruzamento := 1;
  
    if  (fMedia1 < fMedia2)
    and (fMedia1[1] >= fMedia2[1]) 
    and ((Abs((fMedia2-fMedia1)/fMedia1*100)) >= fPercCruzamento)
    then iCruzamento := -1;
  
    if iCruzamento = 1 then 
    begin
      // O que fazer quando houver cruzamento para cima?
      PlotText("Cruzou pra cima", clGreen, -1,12);
    end;
  
    if iCruzamento = -1 then 
    begin
      // O que fazer quando houver cruzamento para baixo?
      PlotText("Cruzou pra baixo", clRed, -1,12);    
    end;
  end;

end;
				
			

Cruzamento entre 2 séries nos últimos N períodos

O exemplo abaixo visa identificar qual cruzamento houve entre duas séries nos últimos N períodos (constante cJanelaCruzamento).

				
					const
  cJanelaCruzamento = 5;
var
  fMedia1,fMedia2 : float;
  iCruzamento : integer;
  iUltimoCruzamentoJanela : integer;
  iPeriodo, iPeriodoJanela : integer;
begin
  iCruzamento := 0;
  fMedia1 := Media(10,Close);
  fMedia2 := Media(20,Close);

  //Plot apenas para visualizar graficamente o funcionamento
  //do código
  Plot(fMedia1);
  Plot2(fMedia2);

  if (fMedia1 > fMedia2) and (fMedia1[1] <= fMedia2[1]) then
    iCruzamento := 1;
  if (fMedia1 < fMedia2) and (fMedia1[1] >= fMedia2[1]) then
    iCruzamento := - 1;
  
  if iCruzamento = 1 then
    begin
      // O que fazer quando houver cruzamento para cima?
      PlotText("Cruzou pra cima",clGreen, - 1,12);
    end;
  
  if iCruzamento = - 1 then
    begin
      // O que fazer quando houver cruzamento para baixo?
      PlotText("Cruzou pra baixo",clRed, - 1,12);
    end;


  // Código para proteção do início da série em backtesting
  if MaxBarsBack < cJanelaCruzamento then
    iPeriodoJanela := MaxBarsBack
  else iPeriodoJanela := cJanelaCruzamento;
  
  // Identificação do último cruzamento
  if iPeriodoJanela >= 1 then
  begin  
    iUltimoCruzamentoJanela := iCruzamento;
    iPeriodo := 1;
    while iPeriodo <= iPeriodoJanela do
    begin
      if iCruzamento[iPeriodo] <> 0 then
      begin
         iUltimoCruzamentoJanela := iCruzamento[iPeriodo];
         iPeriodo := iPeriodoJanela + 1;
      end;
      iPeriodo := iPeriodo + 1;
    end;
  
    // Escreve no gráfico qual cruzamento houve nos últimos
    // cJanelaCruzamento periodos
    if (iCruzamento = 0) and (iUltimoCruzamentoJanela <> 0) then
      if iUltimoCruzamentoJanela = 1 then
        PlotText("Cruz p/ cima",clWhite, - 1,8)
      else
        PlotText("Cruz p/ baixo",clWhite, - 1,8);
  end;

end;
				
			

Toque na média utilizando percentual de proximidade

Reproduzir vídeo

O exemplo abaixo visa identificar quando ocorre o toque do preço em uma média, utilizando como parâmetro o percentual de proximidade.

OBS: Neste exemplo foi introduzido também uma função customizada para arredondar um valor float de acordo com a quantidade de casas decimais desejada (NTB_ArredondarFloat)). Este tipo de função não tem de forma nativa no Profit (o que é uma pena!);

				
					const
  // Define o percentual que caracteriza o toque
  // Se for igual a zero, a barra tem conter a média
  // Ex: se cPercProximidade = 0.5, define como toque se
  // preço chegar a 0.5% ou menos de distância da média
  cPercProximidade = 0.0;
var
  fMedia: float;
  bTocouMedia: boolean;


function NTB_ArredondarFloat(Value: float; nCasas: integer):float;
var
    fValor: float;
    fParteInteira: float;
    fParteDecimal: float;
begin
  fValor := Value;
  fParteInteira := IntPortion(fValor);
  fParteDecimal := Round((fValor - fParteInteira)*Power(10,nCasas));

  Result := fParteInteira + fParteDecimal/Power(10,nCasas);

end;

begin
  bTocouMedia := false;
  fMedia :=  NTB_ArredondarFloat(Media(20,Close),2);

  //Plot apenas para visualizar graficamente o funcionamento
  //do código
  Plot(fMedia);
  SetPlotColor(1,clRed);
  SetPlotWidth(1,2);
  if (cPercProximidade <> 0) then
  begin
    Plot2(NTB_ArredondarFloat(fMedia*(1 + cPercProximidade/100),2));
    Plot3(NTB_ArredondarFloat(fMedia*(1 - cPercProximidade/100),2));
    SetPlotColor(2, clGray);
    SetPlotColor(3, clGray);
  end;


  //Proteção para os primeiros períodos de backtesting
  //Quando pode ocorrer divisão por zero
  if fMedia <> 0 then
  begin

    // Situação em que a media está no meio da barra
    if (fMedia >= Low) and (fMedia <= High)
    then bTocouMedia := True;

    // Situação em que a media está abaixo do preço
    // negociado e este chegou a cPercProximidade da
    // média
    if (fMedia < Low)
    and (((Low - fMedia)/fMedia*100) <= cPercProximidade)
    then
    begin
      bTocouMedia := True;
    end;

    // Situação em que a media está abaixo do preço
    // negociado e este chegou a cPercProximidade da
    // média
    if (fMedia > High)
    and (((fMedia - High)/High*100) <= cPercProximidade)
    then
    begin
    bTocouMedia := True;
    end;

   if bTocouMedia then
     PlotText("Tocou",clWhite, - 1,8);

  end;

end;
				
			

Toque na média utilizando quantidade de ticks de proximidade

Reproduzir vídeo

O exemplo abaixo visa identificar quando ocorre o toque do preço em uma média, utilizando como parâmetro a quantidade de ticks do ativo.

OBS: Neste exemplo foi introduzido também uma função customizada para arredondar um valor float de acordo com a quantidade de casas decimais desejada (NTB_ArredondarFloat)). Este tipo de função não tem de forma nativa no Profit (o que é uma pena!);

				
					const
  // Define o percentual que caracteriza o toque
  // Se for igual a zero, a barra tem conter a média
  // Ex: se cPercProximidade = 0.5, define como toque se
  // preço chegar a 0.5% ou menos de distância da média
  cTicksProximidade = 0;
var
  fMedia: float;
  bTocouMedia: boolean;


function NTB_ArredondarFloat(Value: float; nCasas: integer):float;
var
    fValor: float;
    fParteInteira: float;
    fParteDecimal: float;
begin
  fValor := Value;
  fParteInteira := IntPortion(fValor);
  fParteDecimal := Round((fValor - fParteInteira)*Power(10,nCasas));

  Result := fParteInteira + fParteDecimal/Power(10,nCasas);

end;

begin
  bTocouMedia := false;
  fMedia :=  NTB_ArredondarFloat(Media(20,Close),2);

  //Plot apenas para visualizar graficamente o funcionamento
  //do código
  Plot(fMedia);
  SetPlotColor(1,clRed);
  SetPlotWidth(1,2);
  if (cTicksProximidade <> 0) then
  begin
    Plot2(fMedia + cTicksProximidade*MinPriceIncrement);
    Plot3(fMedia - cTicksProximidade*MinPriceIncrement);
    SetPlotColor(2,clGray);
    SetPlotColor(3,clGray);
  end;

  //Proteção para os primeiros períodos de backtesting
  //Quando pode ocorrer divisão por zero
  if fMedia <> 0 then
  begin

    // Situação em que a media está no meio da barra
    if (fMedia >= Low) and (fMedia <= High)
    then bTocouMedia := True;

    // Situação em que a media está abaixo do preço
    // negociado e este chegou a cPercProximidade da
    // média
    if (fMedia < Low)
    and (((Low - fMedia)/MinPriceIncrement) <= cTicksProximidade)
    then
    begin
      bTocouMedia := True;
    end;

    // Situação em que a media está abaixo do preço
    // negociado e este chegou a cPercProximidade da
    // média
    if (fMedia > High)
    and (((fMedia - High)/MinPriceIncrement) <= cTicksProximidade)
    then
    begin
    bTocouMedia := True;
    end;

   if bTocouMedia then
     PlotText("Tocou",clWhite, - 1,8);

  end;

end;
				
			

Como acessar o Book de Ofertas em NTSL por nível de preço

Reproduzir vídeo

O exemplo abaixo demonstra como armazenar em um array os próximos N níveis de preço do book e obter as quantidades apregoadas para estes níveis no lado da compra e da venda.

OBS: Este código funciona apenas quando o mercado está aberto, não sendo possível fazer backtesting de estratégias baseadas em leitura de book. Isso é algo comum às demais plataformas de trading.

				
					const
  cQtdeNiveis = 4;

input
  cAtivo("CASH3", feedBovespa);

var
  i: integer;
  fBookSell, fBookBuy: array[0..cQtdeNiveis] of float;
  fBookSellSum, fBookBuySum: float;

begin

  for i:= 0 to cQtdeNiveis do
  begin
    fBookSellSum := TotalSellQtd(cAtivo,i+1);
    fBookBuySum :=  TotalBuyQtd(cAtivo,i+1);
    
    if i <> 0 then
    begin
      fBookSell[i] := fBookSellSum - TotalSellQtd(cAtivo,i);    
      fBookBuy[i] := fBookBuySum - TotalBuyQtd(cAtivo,i);
    end
    else
    begin
      fBookSell[i] := fBookSellSum;
      fBookBuy[i] := fBookBuySum;  
    end; 
  end;

  
  {
  // Comparando retorno das funções (Ask/Bid)Size com Total(Sell/Buy)Qtd
  plot(fBookSell[0]);
  plot2(fBookBuy[0]);
  SetPlotColor(1,clRed);
  SetPlotColor(2,clRed);

  plot3(AskSize);
  plot4(BidSize);
  SetPlotColor(3,clYellow);   
  SetPlotColor(4,clYellow);
  }

  // Comparando os 5 primeiros níveis do lado da compra
  plot(fBookBuy[0]);
  plot2(fBookBuy[1]);
  plot3(fBookBuy[2]);
  plot4(fBookBuy[3]);
  plot5(fBookBuy[4]);

  SetPlotColor(1,clRed);
  SetPlotColor(2,clRed);
  SetPlotColor(3,clRed);   
  SetPlotColor(4,clRed);
  SetPlotColor(5,clRed);
  


end
				
			

8 Comments

  • Tiago Ferreira

    Outubro 9, 2022

    Boa noite professor,
    não consegui criar o robo com os parametros de Toque na média utilizando quantidade de ticks de proximidade.Estou colocando ao final , dos parametros de compra e venda mas, não esta dando certo.
    abraço.

    Reply
    • Johnathas

      Outubro 10, 2022

      Boa noite Tiago!
      Para poder te ajudar melhor, precisamos ver o seu código fonte e indicar o que está errado.
      Abra uma pergunta no fórum, por favor, e poste uma imagem do seu código (estou vendo ferramentas melhores para compartilhar o código no fórum).

      Grande abs!

      Reply
  • Ecc1968

    Outubro 16, 2022

    Ola Boa tarde, antes de mais nada parabens pelo excelente trabalho !!! Gostaria de saber se vcs disponilizam essa função NTB_ArredondarFloat ?

    Reply
  • Jolysom Bosque

    Agosto 16, 2023

    John, como faço para identificar os 10 primeiros preço no Book de Ofertas em NTSL?
    Quero verificar o preço x quantidade apregoadas.

    Exemplo;
    Preço. Quantidade
    4.800. 100
    4.805 150
    4.810. 260

    Reply
    • Johnathas

      Agosto 23, 2023

      Olá Jolysom! Pois é…as quantidades dá para extrair conforme o snippet publicado aqui no site. No entanto, o preço é algo que não dá para extrair diretamente.
      Supondo um ativo liquido, sem gaps no book, eu comentei que poderia ser feito pelo preço de bid e ask. Mas infelizmente não tem uma forma direta de obter o preço do nível.
      Abs!

      Reply
  • Wescley Sarmento

    Outubro 11, 2023

    Fala, Johnathas!

    Tudo bem?
    Será que pode me ajudar?
    Como faço para usar o percentual de lotes do SuperDOM para fazer as entradas?

    Por exemplo

    Se percentual de lotes for maior que 55% (lotes para compra) e Valor do MACD for maior que 0, faz uma entrada comprada.

    Será que pode me dar alguma dica?

    Parabéns pelo seu trabalho!

    Reply
    • Johnathas

      Outubro 18, 2023

      Olá Wescley! Obrigado!
      Assista a esse vídeo: https://www.youtube.com/watch?v=E-xrkUkOmik.
      É uma das aulas que liberei do curso de NSL como spoiler para o pessoal ter uma ideia de como são as aulas. Nessa aula eu falo sobre tape reading em NTSL.
      Abs!

      Reply

Leave a Comment

CONTENTS