Neo traderBot

Neo traderBot

Você sabia?

Confira os nossos eBooks, Snippets e Fóruns produzidos para cada plataforma!

Códigos de exemplo? Tome Snippets!

Ordens e Administração de Trade

Leitura estimada: 14 minutos 6563 views

Introdução

Esta seção visa apresentar trechos de códigos com exemplos de envio de ordens e administração de trade utilizando técnicas de stoploss (fixo, móvel, breakeven) e take profit.

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

Como limitar a quantidade de trades por dia

Reproduzir vídeo

O código abaixo apresenta a funcionalidade em código fonte para limitar a quantidade de trades realizados pela sua estratégia/ robô (constante cQtdeMaxOperacoesNoDia).

Apesar do Módulo de Automação possui um limite de perda e ganho diário, ele não possui esta funcionalidade. Idealmente, a Nelogica deveria disponbilizar funções para verificação do resultado bruto alcançado até o momento para permitir outras forma de gestão de risco em código fonte.

				
					const
  // Mude aqui a qtde maxima de trades por dia 
  cQtdeMaxOperacoesNoDia = 5;

var 
  iQtdeOperacoesNoDia: integer;
  iDataAtual: integer;
  bJaContouOperacao: boolean;
  fMedia: float;

begin
  // Inicialização do contador de ordens do dia  
  if Date <> iDataAtual then
  begin
    iDataAtual := Date;
    iQtdeOperacoesNoDia := 0;
    bJaContouOperacao := false;
  end;
  
  // Setup de cruzamento de Media movel só para gerar operações
  fMedia := Media(3,Close);

  // Realiza abertura de posições apenas se número maximo de operação
  // não tiver sido atingido
  if iQtdeOperacoesNoDia < cQtdeMaxOperacoesNoDia then
  begin
    // COMPRA se fechamento cruzar media para cima e
    // VENDE se fechamento cruzar media pra baixo
    if (Close > fMedia) and (Close[1] <= fMedia[1]) and Not HasPosition then BuyAtMarket;       
    if (Close < fMedia) and (Close[1] >= fMedia[1]) and Not HasPosition then SellShortAtMarket;
  end;
  
  // Contabiliza a abertura da posição como mais uma operação no dia   
  if (isBought or isSold) and Not bJaContouOperacao then
  begin
    iQtdeOperacoesNoDia := iQtdeOperacoesNoDia + 1;
    bJaContouOperacao := true;  
  end;

  // Posiciona ordens para gestão do trade
  if isBought then
  begin
    SellShortStop(buyPrice - 5*MinPriceIncrement);
    SellShortLimit(buyPrice + 15*MinPriceIncrement);
  end;

  // Posiciona ordens para gestão do trade
  if isSold then
  begin
    BuyStop(sellPrice + 5*MinPriceIncrement);
    BuyLimit(sellPrice - 15*MinPriceIncrement);
  end;
  
  // Encerra posicao no mesmo dia
  if (Time >= 1645) and hasPosition then ClosePosition;

  // Se posição for encerrada ativa novamente o contador
  if Not IsBought and Not isSold and bJaContouOperacao then bJaContouOperacao := false;  

  // Apenas para inspeção gráfica do sinal
  Plot(fMedia);
  
end
				
			

Como limitar trades por objetivo de ganho ou limite de perda

Reproduzir vídeo

O código abaixo apresenta a funcionalidade em código fonte para limitar a realização de trades baseado no resultado do dia.

Caso o resultado das operações da estratégia atinja o objetivo de ganho ou o limite de perda, fornecidos em valores absolutos e unidade financeira pelos parâmetros pLimitePerdaDiaria e pObjetivoGanhoDiario, a estratégia não realiza mais operações e encerra posições abertas.

O parâmetro pPlotarResultado pode receber os valores “FECHADO”, “ABERTO” e “TOTAL”, para se referir ao resultado de trades fechados, resultado do trade em aberto e resultado total do dia (FECHADO + ABERTO), respectivamente.

				
					input
  pPlotarResultado("ABERTO");
  pLimitePerdaDiaria(200.00);
  pObjetivoGanhoDiario(600.00);

var
  fResultado: float;
  fResultadoDiario: float;
  iDataTeste: integer;
  iHora: integer;
begin
  //-----------------------------------------------------------
  //Plots podem ser excluídos...servem apenas para demonstração

  // Resultado fechado do dia
  If pPlotarResultado = "FECHADO" then
  begin
    fResultado := DailyResult(false);
    plot(fResultado);
    SetPlotStyle(1,psSolid);
    SetPlotColor(1,clWhite);
  end;

  // Resultado até o momento no dia (fechado + aberto)
  If pPlotarResultado = "TOTAL" then
  begin
    fResultado := DailyResult(true);
    plot2(fResultado);
    SetPlotStyle(2,psDash);
    SetPlotColor(2,clRed);
  end;

  // Resultado do trade aberto
  If pPlotarResultado = "ABERTO" then
  begin
    fResultado := DailyResult(true) - DailyResult(false); 
    if fResultado <> 0 then
      plot3(fResultado);
    SetPlotStyle(3,psDash);
    if fResultado >= 0  then SetPlotColor(3,clGreen)
    else SetPlotColor(3,clRed);
    SetPlotType(3, igHistogram);
  end;
  //-----------------------------------------------------------


  // Estratégias apenas opera se resultado do dia não 
  // tiver atingido objetivo de ganho ou limite de perda
  iDataTeste := ELDate(2023,2,10);
  fResultadoDiario := DailyResult(true);
  
  if (fResultadoDiario > -1*pLimitePerdaDiaria)
  and (fResultadoDiario < pObjetivoGanhoDiario) then
  begin
    // SIMULAÇÃO DE ORDENS PARA FINS DE EXEMPLO
    for iHora := 0 to 8 do
    begin
      if (Date = iDataTeste) and (Time = (0900 + iHora*100)) then
        if random(2) = 0 then BuyAtMarket else SellShortAtMarket;
  
      if (Date = iDataTeste) and (Time = (0930 + iHora*100)) then
        ClosePosition;
    end;

  end
  //Se resultado excedeu objetivo de ganho ou limite de perda
  //e houver posição aberta, então encerra a posição.
  else if hasPosition then ClosePosition;
                
            
end;
				
			

Limite de horário para encerramento de posição

Reproduzir vídeo

O código abaixo apresenta a funcionalidade em código fonte para encerramento de posição a partir de um determinado horário. É um exemplo útil para quem opera daytrade e não deseja/não pode correr o risco de carregar operação para o dia seguinte.

				
					var
  bBarraDesejada                 : boolean;
  pDataDesejada,pHorarioDesejado : integer;
  //Util apenas para Backtesting em Gráfico de Renko  
  pMargemMinutos: integer;  
begin
  pHorarioDesejado := 1645;
  pMargemMinutos := 15;
  //Para Gráficos de Candle/Renko executados em tempo real
  //if Time > pHorarioDesejado then

  //Para Gráficos de Renko, em backtesting, utiliza-se uma margem de tempo em torno do horário desejado
  if  (Time >= CalcTIme(pHorarioDesejado, -pMargemMinutos)) then
    begin
      bBarraDesejada := true;
      //Encerra posição caso esteja comprado/vendido
      if isBought or isSold then ClosePosition;
    end
  else
    bBarraDesejada := false;
end;
				
			

Stoploss simples (fixo)

Reproduzir vídeo

O código abaixo apresenta um exemplo de stoploss fixo e take profit (alvo de lucro da operação), para uma relação de risco/ganho de 3:1 em função de quantidade de ticks, aplicado a uma estratégia de posicionamento. O código tem um limite de horário para abertura e fechamento de posição, o qual pode ser alterado pelos parâmetros.

OBS 1: A versão é compatível com o Editor de Estratégias e Módulo de Automação de Estratégias. Devido a um bug do Profit, é necessário ter um comando ClosePosition, pois do contrário a ferramenta informa equivocadamente que não existem ordens para encerrar posição.

				
					const
 //Relação risco/ganho de 3:1
 cStopEmTicks = 10;
 cAlvoEmTicks = 30;
 cStopOffsetEmTicks = 50;

input
  bGestaoDeRiscoPelaEstrategia(true);
  iHorarioInicioAberturaPosicao(0905);
  iHorarioFimAberturaPosicao(1630);
  iHorarioEncerramentoDaytrade(1645);

var
  iCaraCoroa: integer;
  bSinalCompra, bSinalVenda, bPosicionado: boolean;
  fPrecoStop, fPrecoAlvo, fPrecoStopOffset: float;
  bConfigurouRisco: boolean;

begin

  bSinalCompra := false;
  bSinalVenda := false;
  bPosicionado := hasPosition;

  //ESTRATÉGIA CARA OU COROA!
  //Gera um numero aleatorio de 0 a 9. Se for menor igual a 4, gera
  //sinal de compra, se for maior que 4 geral sinal de venda
  if Not bPosicionado
  and (Time >= iHorarioInicioAberturaPosicao)
  and (Time <= iHorarioFimAberturaPosicao)
  then
  begin
    //Número aleatório foi substituido por minuto par ou impar para permitir depurar
    //melhor o robô quando a estratégia é inserida multiplas vezes: como indicador  e como execução
    //iCaraCoroa := Random(10);
    iCaraCoroa := mod(Time,2);
    if iCaraCoroa = 0 then bSinalCompra := true
    else bSinalVenda := true;
  end;


  //Gera ordem de compra a mercado quando há um Sinal de COMPRA
  //e define ordem stoploss e take profit
  if bSinalCompra then BuyAtMarket;

  //Gera ordem de venda a mercado quando há um Sinal de VENDA
  //e define ordem stoploss e take profit
  if bSinalVenda then SellShortAtMarket;

  if bGestaoDeRiscoPelaEstrategia then
  begin
    //POSIÇÃO COMPRADA
    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isBought then
    begin
      if not bConfigurouRisco then
      begin
        fPrecoStop := BuyPrice - cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := BuyPrice + cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop - cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRisco := true;
      end;

      SellToCoverStop(fPrecoStop,fPrecoStopOffset);
       SellToCoverLimit(fPrecoAlvo);
    end;

    //POSIÇÃO VENDIDA
    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isSold then
    begin
      if not bConfigurouRisco then
      begin
        fPrecoStop := SellPrice + cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := SellPrice - cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRisco := true;
      end;

      BuyToCoverStop(fPrecoStop,fPrecoStopOffset);
      BuyToCoverLimit(fPrecoAlvo);

    end;

    //Encerra posicao
    if (Time >= iHorarioEncerramentoDaytrade)
    and HasPosition
    then ClosePosition;

    if Not HasPosition then bConfigurouRisco := false;

  end;

  // Plot de Stop e Alvo para inspeção visual do código
  bPosicionado := hasPosition;
  if bPosicionado or bPosicionado[1] or bPosicionado[2] then
  begin
    PlotN(1,fPrecoStop);
    PlotN(2,fPrecoStopOffset);
    PlotN(3,fPrecoAlvo);
    SetPlotColor(1,clRed);
    SetPlotColor(2,clRed);
    SetPlotColor(3,clGreen);
    SetPlotStyle(1,psDash);
    SetPlotStyle(2,psDash);
    SetPlotStyle(3,psDash);
    SetPlotWidth(1,2);
    SetPlotWidth(2,2);
    SetPlotWidth(3,2);

end;


end;
				
			

Stoploss com Breakeven

Reproduzir vídeo

O código abaixo apresenta um exemplo de Stoploss fixo + Breakeven (alvo de lucro da operação), para uma relação de risco/ganho de 3:1 em função de quantidade de ticks, aplicado a uma estratégia de posicionamento aleatório com uma operação por dia.

OBS 1: A versão é compatível com o Editor de Estratégias e Módulo de Automação de Estratégias. Devido a um bug do Profit, é necessário ter um comando ClosePosition, pois do contrário a ferramenta informa equivocadamente que não existem ordens para encerrar posição.

				
					const
 //Relação risco/ganho de 3:1
 cStopEmTicks = 30;
 cStopOffsetEmTicks = 20;
 cBreakevenEmTicks = 30;
 cAlvoEmTIcks = 90;

input
  bGestaoDeRiscoPelaEstrategia(true);
  iHorarioInicioAberturaPosicao(0905);
  iHorarioFimAberturaPosicao(1630);
  iHorarioEncerramentoDaytrade(1645);

var
  iCaraCoroa: integer;
  bSinalCompra, bSinalVenda, bPosicionado: boolean;
  fPrecoStop, fPrecoAlvo, fPrecoStopOffset: float;
  bConfigurouRiscoInicial: boolean;
begin

  bSinalCompra := false;
  bSinalVenda := false;
  bPosicionado := hasPosition;

  //ESTRATÉGIA CARA OU COROA!
  //Gera um numero aleatorio de 0 a 9. Se for menor igual a 4, gera
  //sinal de compra, se for maior que 4 geral sinal de venda
  if Not bPosicionado
  and (Time >= iHorarioInicioAberturaPosicao)
  and (Time <= iHorarioFimAberturaPosicao)
  then
  begin
    //Número aleatório foi substituido por minuto par ou impar para permitir depurar
    //melhor o robô quando a estratégia é inserida multiplas vezes: como indicador  e como execução
    //iCaraCoroa := Random(10);
    iCaraCoroa := mod(Time,2);
    if iCaraCoroa = 0 then bSinalCompra := true
    else bSinalVenda := true;
  end;

  //Gera ordem de compra a mercado quando há um Sinal de COMPRA
  //e define ordem stoploss e take profit
  if bSinalCompra then BuyAtMarket;

  //Gera ordem de venda a mercado quando há um Sinal de VENDA
  //e define ordem stoploss e take profit
  if bSinalVenda then SellShortAtMarket;

  if bGestaoDeRiscoPelaEstrategia then
  begin
    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isBought then
    begin
      if Not bConfigurouRiscoInicial then
      begin
        fPrecoStop := BuyPrice - cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := BuyPrice + cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop - cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRiscoInicial := true;
      end;

      if Close >= (BuyPrice + cBreakevenEmTicks*MinPriceIncrement) then
      begin
        fPrecoStop := BuyPrice;
        fPrecoStopOffset := fPrecoStop-cStopOffsetEmTicks*MinPriceIncrement;
      end;

      SellToCoverStop(fPrecoStop,fPrecoStopOffset);
      SellToCoverLimit(fPrecoAlvo);
    end;

    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isSold then
    begin
      if Not bConfigurouRiscoInicial then
      begin
        fPrecoStop := SellPrice + cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := SellPrice - cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRiscoInicial := true;
      end;

      if Close <= (SellPrice - cBreakevenEmTicks*MinPriceIncrement) then
      begin
        fPrecoStop := SellPrice;
        fPrecoStopOffset := fPrecoStop+cStopOffsetEmTicks*MinPriceIncrement;
      end;

      BuyToCoverStop(fPrecoStop,fPrecoStopOffset);
      BuyToCoverLimit(fPrecoAlvo);

    end;


    //Encerra posicao
    if (Time >= iHorarioEncerramentoDaytrade)
    and HasPosition
    then ClosePosition;

    if Not hasPosition and bConfigurouRiscoInicial then bConfigurouRiscoInicial := false;


  end;

  bPosicionado := hasPosition;

  // Plot de Stop e Alvo para inspeção visual do código
  if bPosicionado or bPosicionado[1] or bPosicionado[2] then
  begin
    PlotN(1,fPrecoStop);
    PlotN(2,fPrecoStopOffset);
    PlotN(3,fPrecoAlvo);
    SetPlotColor(1,clRed);
    SetPlotColor(2,clRed);
    SetPlotColor(3,clGreen);
    SetPlotStyle(1,psDash);
    SetPlotStyle(2,psDash);
    SetPlotStyle(3,psDash);
    SetPlotWidth(1,2);
    SetPlotWidth(2,2);
    SetPlotWidth(3,2);
  end;

end;
				
			

Stoploss móvel (Versão contínua)

Reproduzir vídeo

O código abaixo apresenta um exemplo de stoploss móvel (Versão contínua), ou seja, valor de stop é atualizado a cada fechamento de candle. Só não é atualizado a cada tick por uma limitação do Profit.

O stop será alterado para cOffsetStopEmTicks em relação ao preço de fechamento do candle, não podendo o valor do stop retroceder. O código pode ser alterado para calcular o stop móvel em relação ao valor máximo do candle.

O exemplo também conta com ordem take profit (alvo de lucro da operação) para uma relação de risco/ganho de 3:1 em função de quantidade de ticks, aplicado a uma estratégia de posicionamento aleatório com uma operação por dia.

OBS 1: A versão é compatível com o Editor de Estratégias e Módulo de Automação de Estratégias. Devido a um bug do Profit, é necessário ter um comando ClosePosition, pois do contrário a ferramenta informa equivocadamente que não existem ordens para encerrar posição.

				
					const
 //Relação risco/ganho de 3:1
 cStopEmTicks = 15;
 cAlvoEmTicks = 45;
 cTraillingStopTrigger = 20;
 cTrailingStopOffset = 10;
 cStopOffsetEmTicks = 50;

input
  bGestaoDeRiscoPelaEstrategia(true);
  iHorarioInicioAberturaPosicao(0905);
  iHorarioFimAberturaPosicao(1630);
  iHorarioEncerramentoDaytrade(1645);

var
  iCaraCoroa: integer;
  bSinalCompra, bSinalVenda, bPosicionado: boolean;
  fPrecoStop, fPrecoAlvo, fPrecoStopOffset: float;
  bConfigurouRiscoInicial: boolean;
  bTrailingStopAtivado: boolean;
begin

  bSinalCompra := false;
  bSinalVenda := false;
  bPosicionado := hasPosition;

  //ESTRATÉGIA CARA OU COROA!
  //Gera um numero aleatorio de 0 a 9. Se for menor igual a 4, gera
  //sinal de compra, se for maior que 4 geral sinal de venda
  if Not bPosicionado
  and (Time >= iHorarioInicioAberturaPosicao)
  and (Time <= iHorarioFimAberturaPosicao)
  then
  begin
    //Número aleatório foi substituido por minuto par ou impar para permitir depurar
    //melhor o robô quando a estratégia é inserida multiplas vezes: como indicador  e como execução
    //iCaraCoroa := Random(10);
    iCaraCoroa := mod(Time,2);
    if iCaraCoroa = 0 then bSinalCompra := true
    else bSinalVenda := true;
  end;


  //Gera ordem de compra a mercado quando há um Sinal de COMPRA
  //e define ordem stoploss e take profit
  if bSinalCompra then BuyAtMarket;

  //Gera ordem de venda a mercado quando há um Sinal de VENDA
  //e define ordem stoploss e take profit
  if bSinalVenda then SellShortAtMarket;

  if bGestaoDeRiscoPelaEstrategia then
  begin

    //POSIÇÃO COMPRADA
    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isBought then
    begin
      if Not bConfigurouRiscoInicial then
      begin
        fPrecoStop := BuyPrice - cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := BuyPrice + cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop - cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRiscoInicial := true;
      end;

      if ((Close >= (BuyPrice + cTraillingStopTrigger*MinPriceIncrement))
          or (cTraillingStopTrigger = 0))
      and (not bTrailingStopAtivado) then bTrailingStopAtivado := true;

      if ((Close - cTrailingStopOffset*MinPriceIncrement) >= fPrecoStop)
      and (bTrailingStopAtivado) then
      begin
        fPrecoStop := Close - cTrailingStopOffset*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop - cStopOffsetEmTicks*MinPriceIncrement;
      end;

      SellToCoverStop(fPrecoStop,fPrecoStopOffset);
      SellToCoverLimit(fPrecoAlvo);

    end;


    //POSIÇÃO VENDIDA
    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isSold then
    begin
      if Not bConfigurouRiscoInicial then
      begin
        fPrecoStop := SellPrice + cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := SellPrice - cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRiscoInicial := true;
      end;

      if ((Close <= (SellPrice - cTraillingStopTrigger*MinPriceIncrement))
          or (cTraillingStopTrigger = 0))
      and (not bTrailingStopAtivado) then bTrailingStopAtivado := true;

      if ((Close + cTrailingStopOffset*MinPriceIncrement) <= fPrecoStop)
      and (bTrailingStopAtivado) then
      begin
        fPrecoStop := Close + cTrailingStopOffset*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement;
      end;

      BuyToCoverStop(fPrecoStop,fPrecoStopOffset);
      BuyToCoverLimit(fPrecoAlvo);

    end;

    //Encerra posicao comprada no horario limite
    if (Time >= iHorarioEncerramentoDaytrade)
    and HasPosition
    then ClosePosition;

    if Not hasPosition and bConfigurouRiscoInicial then
    begin
      bConfigurouRiscoInicial := false;
      bTrailingStopAtivado := false;
    end;


  end;

  // Plot de Stop e Alvo para inspeção visual do código
  bPosicionado := hasPosition;
  if bPosicionado or bPosicionado[1] or bPosicionado[2] then
  begin
    PlotN(1,fPrecoStop);
    PlotN(2,fPrecoStopOffset);
    PlotN(3,fPrecoAlvo);
    SetPlotColor(1,clRed);
    SetPlotColor(2,clRed);
    SetPlotColor(3,clGreen);
    SetPlotStyle(1,psDash);
    SetPlotStyle(2,psDash);
    SetPlotStyle(3,psDash);
    SetPlotWidth(1,2);
    SetPlotWidth(2,2);
    SetPlotWidth(3,2);
  end;

end;
				
			

Stoploss móvel (Versão baseada em passos)

Reproduzir vídeo

O código abaixo apresenta um exemplo de stoploss móvel (Versão discreta, baseada em passos), ou seja, valor de stop é atualizado cada vez que o preço de fechamento do candle supera o passo definido em cTrailingStepEmTicks. Só não é atualizado a cada tick por uma limitação do Profit.

O stop será alterado para cOffsetStop em relação ao preço do último passo alcançado, não podendo o valor do stop retroceder. O código pode ser alterado para calcular o stop móvel em relação ao valor máximo do candle.

O exemplo também conta com ordem take profit (alvo de lucro da operação) em posições compradas, para uma relação de risco/ganho de 3:1. O raciocínio para posições vendidas é análogo.

OBS 1: A versão é compatível com o Editor de Estratégias e Módulo de Automação de Estratégias. Devido a um bug do Profit, é necessário ter um comando ClosePosition, pois do contrário a ferramenta informa equivocadamente que não existem ordens para encerrar posição.

				
					const
 //Relação risco/ganho de 3:1
 cStopEmTicks = 15;
 cAlvoEmTicks = 45;
 cTraillingStopTrigger = 0;
 cTrailingStopOffset = 8;
 cTrailingStepEmTicks = 10;
 cStopOffsetEmTicks = 10;

input
  bGestaoDeRiscoPelaEstrategia(true);
  iHorarioInicioAberturaPosicao(1000);
  iHorarioFimAberturaPosicao(1630);
  iHorarioEncerramentoDaytrade(1645);

var
  iCaraCoroa: integer;
  bSinalCompra, bSinalVenda, bPosicionado: boolean;
  fPrecoStop, fPrecoAlvo, fPrecoStopOffset: float;
  fFloorTraillingStop : float;
  bConfigurouRiscoInicial: boolean;
  bTrailingStopAtivado: boolean;

begin

  bSinalCompra := false;
  bSinalVenda := false;
  bPosicionado := hasPosition;

  //ESTRATÉGIA CARA OU COROA!
  //Gera um numero aleatorio de 0 a 9. Se for menor igual a 4, gera
  //sinal de compra, se for maior que 4 geral sinal de venda
  if Not bPosicionado
  and (Time >= iHorarioInicioAberturaPosicao)
  and (Time <= iHorarioFimAberturaPosicao)
  then
  begin
    //Número aleatório foi substituido por minuto par ou impar para permitir depurar
    //melhor o robô quando a estratégia é inserida multiplas vezes: como indicador  e como execução
    //iCaraCoroa := Random(10);
    iCaraCoroa := mod(Time,2);
    if iCaraCoroa = 0 then bSinalCompra := true
    else bSinalVenda := true;
  end;


  //Gera ordem de compra a mercado quando há um Sinal de COMPRA
  //e define ordem stoploss e take profit
  if bSinalCompra then BuyAtMarket;

  //Gera ordem de venda a mercado quando há um Sinal de VENDA
  //e define ordem stoploss e take profit
  if bSinalVenda then SellShortAtMarket;


  if bGestaoDeRiscoPelaEstrategia then
  begin
    //POSIÇÃO COMPRADA
    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isBought then
    begin
      if Not bConfigurouRiscoInicial then
      begin
        fPrecoStop := BuyPrice - cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := BuyPrice + cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop - cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRiscoInicial := true;
      end;

      if ((Close >= (BuyPrice + cTraillingStopTrigger*MinPriceIncrement))
         or (cTraillingStopTrigger = 0))
      and (not bTrailingStopAtivado) then bTrailingStopAtivado := true;

      fFloorTraillingStop := BuyPrice
          + floor((Close - BuyPrice)/(cTrailingStepEmTicks*MinPriceIncrement))
          *cTrailingStepEmTicks*MinPriceIncrement;

      if ((fFloorTraillingStop-cTrailingStopOffset*MinPriceIncrement) >= fPrecoStop)
      and bTrailingStopAtivado then
        fPrecoStop := fFloorTraillingStop - cTrailingStopOffset*MinPriceIncrement;


      SellToCoverStop(fPrecoStop,fPrecoStopOffset);
      SellToCoverLimit(fPrecoAlvo);
    end;

    //POSIÇÃO VENDIDA
    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isSold Then
    begin
      if Not bConfigurouRiscoInicial then
      begin
        fPrecoStop := SellPrice + cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := SellPrice - cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRiscoInicial := true;
      end;

      if ((Close <= (SellPrice - cTraillingStopTrigger*MinPriceIncrement))
          or (cTraillingStopTrigger = 0))
      and (not bTrailingStopAtivado) then bTrailingStopAtivado := true;

      if Close <= SellPrice then
        fFloorTraillingStop := SellPrice
            - floor((SellPrice - Close)/(cTrailingStepEmTicks*MinPriceIncrement))
            *cTrailingStepEmTicks*MinPriceIncrement;

      if ((fFloorTraillingStop+cTrailingStopOffset*MinPriceIncrement) <= fPrecoStop)
      and bTrailingStopAtivado then
        fPrecoStop := fFloorTraillingStop + cTrailingStopOffset*MinPriceIncrement;


      BuyToCoverStop(fPrecoStop,fPrecoStopOffset);
      BuyToCoverLimit(fPrecoAlvo);
    end;

    //Encerra posicao
    if (Time >= iHorarioEncerramentoDaytrade)
    and HasPosition
    then ClosePosition;

    if Not hasPosition and bConfigurouRiscoInicial then
    begin
      bConfigurouRiscoInicial := false;
      bTrailingStopAtivado := false;
    end;

  end;

  // Plot de Stop e Alvo para inspeção visual do código
  bPosicionado := hasPosition;
  if bPosicionado or bPosicionado[1] or bPosicionado[2] then
  begin
    PlotN(1,fPrecoStop);
    PlotN(2,fPrecoStopOffset);
    PlotN(3,fPrecoAlvo);
    SetPlotColor(1,clRed);
    SetPlotColor(2,clRed);
    SetPlotColor(3,clGreen);
    SetPlotStyle(1,psDash);
    SetPlotStyle(2,psDash);
    SetPlotStyle(3,psDash);
    SetPlotWidth(1,2);
    SetPlotWidth(2,2);
    SetPlotWidth(3,2);
  end;



end;
				
			

Stoploss móvel (Versão contínua) + Breakeven

Reproduzir vídeo

O código abaixo apresenta um exemplo avançado de stoploss móvel com Breakeven na versão contínua, ou seja, valor de stop é atualizado para cada valor de fechamento de candle encerrado. Só não é atualizado a cada tick por uma limitação do Profit.

O stop será alterado para cOffsetStop em relação ao maior preço de fechamento alcançado desde a abertura da posição. O código pode ser alterado para calcular o stop móvel em relação ao valor máximo do candle.

O exemplo também conta com ordem take profit (alvo de lucro da operação) em posições compradas, para uma relação de risco/ganho de 3:1. O raciocínio para posições vendidas é análogo.

OBS 1: A versão é compatível com o Editor de Estratégias e Módulo de Automação de Estratégias. Devido a um bug do Profit, é necessário ter um comando ClosePosition, pois do contrário a ferramenta informa equivocadamente que não existem ordens para encerrar posição.

				
					const
 //Relação risco/ganho de 3:1
 cStopEmTicks = 30;
 cStopOffsetEmTicks = 10;
 cTrailingStopOffset = 15;
 cBreakevenEmTicks = 10;
 cTraillingStopTrigger = 20;
 cAlvoEmTicks = 90;


input
  bGestaoDeRiscoPelaEstrategia(true);
  iHorarioInicioAberturaPosicao(0905);
  iHorarioFimAberturaPosicao(1630);
  iHorarioEncerramentoDaytrade(1645);

var
  iCaraCoroa: integer;
  bSinalCompra, bSinalVenda, bPosicionado: boolean;
  fPrecoStop, fPrecoAlvo, fPrecoStopOffset: float;
  bBreakevenAtivado: boolean;
  bConfigurouRiscoInicial: boolean;
  bTrailingStopAtivado: boolean;

begin

  bSinalCompra := false;
  bSinalVenda := false;
  bPosicionado := hasPosition;

  //ESTRATÉGIA CARA OU COROA!
  //Gera um numero aleatorio de 0 a 9. Se for menor igual a 4, gera
  //sinal de compra, se for maior que 4 geral sinal de venda
  if Not bPosicionado
  and (Time >= iHorarioInicioAberturaPosicao)
  and (Time <= iHorarioFimAberturaPosicao)
  then
  begin
    //Número aleatório foi substituido por minuto par ou impar para permitir depurar
    //melhor o robô quando a estratégia é inserida multiplas vezes: como indicador  e como execução
    //iCaraCoroa := Random(10);
    iCaraCoroa := mod(Time,2);
    if iCaraCoroa = 0 then bSinalCompra := true
    else bSinalVenda := true;
  end;

  //Gera ordem de compra a mercado quando há um Sinal de COMPRA
  //e define ordem stoploss e take profit
  if bSinalCompra then BuyAtMarket;

  //Gera ordem de venda a mercado quando há um Sinal de VENDA
  //e define ordem stoploss e take profit
  if bSinalVenda then SellShortAtMarket;

  if bGestaoDeRiscoPelaEstrategia then
  begin
    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isBought then
    begin
      if Not bConfigurouRiscoInicial then
      begin
        fPrecoStop := BuyPrice - cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := BuyPrice + cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop - cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRiscoInicial := true;
      end;

      if ((Close >= (BuyPrice + cTraillingStopTrigger*MinPriceIncrement))
          or (cTraillingStopTrigger = 0))
      and (not bTrailingStopAtivado) then bTrailingStopAtivado := true;

      if ((Close - cTrailingStopOffset*MinPriceIncrement) >= fPrecoStop)
      and bTrailingStopAtivado then
          fPrecoStop := Close - cTrailingStopOffset*MinPriceIncrement;

      if (Close >= (BuyPrice + cBreakevenEmTicks*MinPriceIncrement))
      and (not bBreakevenAtivado) then
      begin
        bBreakevenAtivado := true;
        if fPrecoStop < BuyPrice then fPrecoStop := BuyPrice;
      end;


      fPrecoStopOffset := fPrecoStop-cStopOffsetEmTicks*MinPriceIncrement;
      SellToCoverStop(fPrecoStop,fPrecoStopOffset);
      SellToCoverLimit(fPrecoAlvo);
    end;


    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isSold then
    begin
      if Not bConfigurouRiscoInicial then
      begin
        fPrecoStop := SellPrice + cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := SellPrice - cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRiscoInicial := true;
      end;

      if ((Close <= (SellPrice - cTraillingStopTrigger*MinPriceIncrement))
          or (cTraillingStopTrigger = 0))
      and (not bTrailingStopAtivado) then bTrailingStopAtivado := true;

      if ((Close + cTrailingStopOffset*MinPriceIncrement) <= fPrecoStop)
      and bTrailingStopAtivado then
          fPrecoStop := Close + cTrailingStopOffset*MinPriceIncrement;

      if (Close <= (SellPrice - cBreakevenEmTicks*MinPriceIncrement))
      and (not bBreakevenAtivado) then
      begin
        bBreakevenAtivado := true;
        if fPrecoStop > SellPrice then fPrecoStop := SellPrice;
      end;


      fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement;
      BuyToCoverStop(fPrecoStop,fPrecoStopOffset);
      BuyToCoverLimit(fPrecoAlvo);
    end;


    //Encerra posicao
    if (Time >= iHorarioEncerramentoDaytrade)
    and HasPosition
    then ClosePosition;

    if Not hasPosition and bConfigurouRiscoInicial then
    begin
      bConfigurouRiscoInicial := false;
      bBreakevenAtivado := false;
      bTrailingStopAtivado := false;
    end;

  end;

  // Plot de Stop e Alvo para inspeção visual do código
  bPosicionado := hasPosition;
  if bPosicionado or bPosicionado[1] or bPosicionado[2] then
  begin
    PlotN(1,fPrecoStop);
    PlotN(2,fPrecoStopOffset);
    PlotN(3,fPrecoAlvo);
    SetPlotColor(1,clRed);
    SetPlotColor(2,clRed);
    SetPlotColor(3,clGreen);
    SetPlotStyle(1,psDash);
    SetPlotStyle(2,psDash);
    SetPlotStyle(3,psDash);
    SetPlotWidth(1,2);
    SetPlotWidth(2,2);
    SetPlotWidth(3,2);
  end
  else
  begin
    NoPlot(1);
    NoPlot(2);
    NoPlot(3);
  end;


end;
				
			

Stoploss móvel (Versão baseada em passos) + Breakeven

O código abaixo apresenta um exemplo avançado de stoploss móvel com Breakeven na versão discreta (baseada em passos), ou seja, valor de stop é atualizado para cada valor de fechamento que supera o passo definido (cTrailingStepEmTicks). Só não é atualizado a cada tick por uma limitação do Profit.

O stop será alterado para cOffsetStop em relação ao último passo alcançado pelo maior preço de fechamento de candle desde a abertura da posição. O código pode ser alterado para calcular o stop móvel em relação ao valor máximo do candle.

O exemplo também conta com ordem take profit (alvo de lucro da operação) em posições compradas, para uma relação de risco/ganho de 3:1. O raciocínio para posições vendidas é análogo.

OBS 1: A versão é compatível com o Editor de Estratégias e Módulo de Automação de Estratégias. Devido a um bug do Profit, é necessário ter um comando ClosePosition, pois do contrário a ferramenta informa equivocadamente que não existem ordens para encerrar posição.

				
					const
 //Relação risco/ganho de 3:1
 cStopEmTicks = 30;
 cBreakevenEmTicks = 10;
 cTraillingStopTrigger = 20;
 cTrailingStepEmTicks = 20;
 cTrailingStopOffset = 10;
 cStopOffsetEmTicks = 10;
 cAlvoEmTIcks = 90;

input
  bGestaoDeRiscoPelaEstrategia(true);
  iHorarioInicioAberturaPosicao(0905);
  iHorarioFimAberturaPosicao(1630);
  iHorarioEncerramentoDaytrade(1645);

var
  iCaraCoroa: integer;
  bSinalCompra, bSinalVenda, bPosicionado: boolean;
  fPrecoStop, fPrecoAlvo, fPrecoStopOffset: float;
  fFloorTraillingStop: float;
  bBreakevenAtivado: boolean;
  bConfigurouRiscoInicial: boolean;
  bTrailingStopAtivado: boolean;

begin

  bSinalCompra := false;
  bSinalVenda := false;
  bPosicionado := hasPosition;

  //ESTRATÉGIA CARA OU COROA!
  //Gera um numero aleatorio de 0 a 9. Se for menor igual a 4, gera
  //sinal de compra, se for maior que 4 geral sinal de venda
  if Not bPosicionado
  and (Time >= iHorarioInicioAberturaPosicao)
  and (Time <= iHorarioFimAberturaPosicao)
  then
  begin
    //Número aleatório foi substituido por minuto par ou impar para permitir depurar
    //melhor o robô quando a estratégia é inserida multiplas vezes: como indicador  e como execução
    //iCaraCoroa := Random(10);
    iCaraCoroa := mod(Time,2);
    if iCaraCoroa = 0 then bSinalCompra := true
    else bSinalVenda := true;
  end;

  //Gera ordem de compra a mercado quando há um Sinal de COMPRA
  //e define ordem stoploss e take profit
  if bSinalCompra then BuyAtMarket;

  //Gera ordem de venda a mercado quando há um Sinal de VENDA
  //e define ordem stoploss e take profit
  if bSinalVenda then SellShortAtMarket;

  if bGestaoDeRiscoPelaEstrategia then
  begin
    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isBought then
    begin
      if Not bConfigurouRiscoInicial then
      begin
        fPrecoStop := BuyPrice - cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := BuyPrice + cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop - cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRiscoInicial := true;
      end;

      if ((Close >= (BuyPrice + cTraillingStopTrigger*MinPriceIncrement))
          or (cTraillingStopTrigger = 0))
      and (not bTrailingStopAtivado) then bTrailingStopAtivado := true;

      fFloorTraillingStop := BuyPrice
          + floor((Close - BuyPrice)/(cTrailingStepEmTicks*MinPriceIncrement))
          *cTrailingStepEmTicks*MinPriceIncrement;

      if ((fFloorTraillingStop-cTrailingStopOffset*MinPriceIncrement) >= fPrecoStop)
      and (Close >= BuyPrice+cTrailingStepEmTicks*MinPriceIncrement)
      and bTrailingStopAtivado then
        fPrecoStop := fFloorTraillingStop - cTrailingStopOffset*MinPriceIncrement;

      if (Close >= (BuyPrice + cBreakevenEmTicks*MinPriceIncrement))
      and (not bBreakevenAtivado) then
      begin
        bBreakevenAtivado := true;
        if fPrecoStop < BuyPrice then fPrecoStop := BuyPrice;
      end;

      fPrecoStopOffset := fPrecoStop-cStopOffsetEmTicks*MinPriceIncrement;

      SellToCoverStop(fPrecoStop,fPrecoStopOffset);
      SellToCoverLimit(fPrecoAlvo);
    end;


    //Código responsável pela manutenção das ordens de stoploss e take profit
    if isSold then
    begin
      if Not bConfigurouRiscoInicial then
      begin
        fPrecoStop := SellPrice + cStopEmTicks*MinPriceIncrement;
        fPrecoAlvo := SellPrice - cAlvoEmTicks*MinPriceIncrement;
        fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement;
        bConfigurouRiscoInicial := true;
      end;

      if ((Close <= (SellPrice - cTraillingStopTrigger*MinPriceIncrement))
          or (cTraillingStopTrigger = 0))
      and (not bTrailingStopAtivado) then bTrailingStopAtivado := true;

      if Close <= SellPrice then
        fFloorTraillingStop := SellPrice
            - floor((SellPrice - Close)/(cTrailingStepEmTicks*MinPriceIncrement))
            *cTrailingStepEmTicks*MinPriceIncrement;


      if ((fFloorTraillingStop+cTrailingStopOffset*MinPriceIncrement) <= fPrecoStop)
      and (Close <= SellPrice - cTrailingStepEmTicks*MinPriceIncrement)
      and bTrailingStopAtivado then
        fPrecoStop := fFloorTraillingStop + cTrailingStopOffset*MinPriceIncrement;


      if (Close <= (SellPrice - cBreakevenEmTicks*MinPriceIncrement))
      and (not bBreakevenAtivado) then
      begin
        bBreakevenAtivado := true;
        if fPrecoStop > SellPrice then fPrecoStop := SellPrice;
      end;


      fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement;

      BuyToCoverStop(fPrecoStop,fPrecoStopOffset);
      BuyToCoverLimit(fPrecoAlvo);

    end;


    //Encerra posicao
    if (Time >= iHorarioEncerramentoDaytrade)
    and HasPosition
    then ClosePosition;

    if Not hasPosition and bConfigurouRiscoInicial then
    begin
      bConfigurouRiscoInicial := false;
      bBreakevenAtivado := false;
      bTrailingStopAtivado := false;
    end;

  end;

  // Plot de Stop e Alvo para inspeção visual do código
  bPosicionado := hasPosition;
  if bPosicionado or bPosicionado[1] or bPosicionado[2] then
  begin
    PlotN(1,fPrecoStop);
    PlotN(2,fPrecoStopOffset);
    PlotN(3,fPrecoAlvo);
    SetPlotColor(1,clRed);
    SetPlotColor(2,clRed);
    SetPlotColor(3,clGreen);
    SetPlotStyle(1,psDash);
    SetPlotStyle(2,psDash);
    SetPlotStyle(3,psDash);
    SetPlotWidth(1,2);
    SetPlotWidth(2,2);
    SetPlotWidth(3,2);
  end
  else
  begin
    NoPlot(1);
    NoPlot(2);
    NoPlot(3);
  end;




end;
				
			

Confirmação de ordens por múltiplos sinais

O código abaixo apresenta um exemplo para o conceito de confirmação de compra por meio de dois sinais distintos: um sinal baseado em IFR e outro baseado em cruzamento de média.

Os sinais podem ser adaptados para quaisquer condições que se deseje. O importante deste exemplo é entender a lógica por trás de duplas confirmações ou múltiplas confirmações com janela de timeout para abertura de posição.

OBS 1: Como o foco do snippet é a confirmação de ordens com múltiplos sinais, a gestão de risco foi implementada da forma mais simples possível apenas para tornar o código funcional. Percebe-se que há um stop e alvo fixos na relação 3:1, onde o stop está 30 ticks atrás do preço de compra e o alvo a 90 ticks acima do preço de compra.

OBS 2: A parametrização dos indicadores, bem como a seleção dos indicadores deste exemplo não representam nenhuma recomendação de setup, sendo apenas um exemplo didático.

				
					const
  // Determina a qtde de candles a se aguardar a confirmação
  // de sinal de compra 
  iTimeoutConfirmacao = 12;
  // Limite para considerar sobrevenda no IFR
  iLimiteSobreVendaIFR = 35;

input
  iQtdePeriodosMedia(16);
  iQtdePeriodosIFR(16);
  //Compatibilidade com Módulo de Automação de Estratégias
  bModuloAutomacao(false);
var
  bSinalCompraIFR, bSinalCompraCruzMedia: boolean;
  fIFR, fMedia: float;

  iInteradorTimeout: integer;
  bSinalCompraConfirmada: boolean;
  bSinalCompraIFRativou, bSinalCompraCruzMediaAtivou: boolean;
  
  bComprado: boolean;
  bConfigurouRiscoOperacao: boolean;
  fPrecoAlvo, fPrecoStop, fStopOffset: float;
begin
  // Indicadores técnicos utilizados para sinais
  bComprado := isBought;
  fIFR := RSI(iQtdePeriodosIFR,0);
  fMedia := Media(iQtdePeriodosMedia,Close);
  bSinalCompraConfirmada := false;  

  //Sinais de compra individuais para indicadores
  bSinalCompraCruzMedia := (Close > fMedia) and (Close[1] <= fMedia[1]);
  bSinalCompraIFR := (fIFR > iLimiteSobreVendaIFR) and (fIFR[1] <= iLimiteSobreVendaIFR);

  // Auxilio visual de sinais individuais
  if bSinalCompraCruzMedia and Not bComprado then PlotText("S1", clBlue,-1,9);
  if bSinalCompraIFR and Not bComprado then PlotText("S2", clYellow,0,9);

  // Lógica para multiplas confirmações
  // Se Timeout for zero a dupla confirmação de compra deve ocorrer
  // no mesmo candle/box
  if Not bComprado then
  begin
    if (iTimeoutConfirmacao = 0) and bSinalCompraCruzMedia and bSinalCompraIFR then
      bSinalCompraConfirmada := true
    else
    if (iTimeoutConfirmacao > 0) then
    begin
      bSinalCompraConfirmada := false;
      bSinalCompraIFRativou := false;
      bSinalCompraCruzMediaAtivou := false;
  
      for iInteradorTimeout := 0 to iTimeoutConfirmacao do
      begin
        if bSinalCompraCruzMedia[iInteradorTimeout] = true then bSinalCompraCruzMediaAtivou := true;
        if bSinalCompraIFR[iInteradorTimeout] = true then bSinalCompraIFRativou := true;
        if bSinalCompraCruzMediaAtivou and bSinalCompraIFRativou then bSinalCompraConfirmada := true;
      end;
    end;
  end;

  // Se houver multipla confirmação, executa ordem a mercado
  if bSinalCompraConfirmada and Not bComprado then 
  begin
    BuyAtMarket;
    bConfigurouRiscoOperacao := false;
  end;
  bComprado := isBought;

  // Configura risco da operação no Módulo de Automação (Ordem OCO)
  // Para outras configurações de STOPLOSS, consulte os snippets no site
  if bModuloAutomacao then
  begin
    if bComprado and Not bConfigurouRiscoOperacao then
    begin
      fPrecoAlvo := buyPrice + 450*MinPriceIncrement;
      fPrecoStop := buyPrice - 150*MinPriceIncrement;
      fStopOffset := fPrecoStop - 100*MinPriceIncrement;

      SellShortStop(fPrecoStop, fStopOffset);
      SellShortLimit(fPrecoAlvo);
    end
    else
    //Proteção de pulo da ordem stop devido à gaps 
    if isBought and (Close < fStopOffset) then closePosition;

  end
  // Configura alvo e stoploss para Backtesting
  else
  begin
    if bComprado then
    begin
      fPrecoAlvo := buyPrice + 450*MinPriceIncrement;
      fPrecoStop := buyPrice - 150*MinPriceIncrement;
      fStopOffset := fPrecoStop - 60*MinPriceIncrement;

      SellToCoverStop(fPrecoStop, fStopOffset);
      //Proteção de pulo da ordem stop devido à gaps
      if isBought and (Close < fStopOffset) then closePosition;
      if isBought then SellToCoverLimit(fPrecoAlvo);
    end;
  end;


end.

				
			

Gestão de Risco diária e Proteção de Ganhos

Reproduzir vídeo

O código abaixo apresenta um exemplo de programação para fazer a gestão de risco do resultado diário de um robô.

Inicialmente, são estabelecidos para a estratégia o limite de perda (pLimitePerdaDiaria) e objetivo de ganho diário (pObjetivoGanhoDiario), bem como a proteção de ganho desejada (pProtecaoGanho), tudo em valor financeiro.

A medida que o robô faz as operações, caso o resultado atinja o limite de perda inicial, a estratégia para de operar durante o resto do dia.

Caso o objetivo de ganho seja atingido, a gestão de risco do código protege parte do ganho (pProtecaoGanho) e o robô continua a operar. Caso atinja novamente o objetivo de ganho, a partir do último patamar de ganho planejado, o lucro é novamente protegido.

				
					input
  pLimitePerdaDiaria(100.00);
  pObjetivoGanhoDiario(300.00);
  pProtecaoGanho(200.00);
  pTempoReal(false);
var
  fResultado: float;
  fResultadoDiario: float;
  iHora: integer;

  fObjetivoAtualGanho, fLimiteAtualPerda: float;
  fNovaReferencia: float;

  bPrimeiraBarraDoDia : boolean;
  iDataAtual          : integer;
  bPrimeiroTickDaBarra : boolean;
  iBarraAtual          : integer;
begin
  // Configura a gestão de risco no primeiro tick da primeira
  // barra do dia. Necessário agora que tem roteamento no tick
  // SNIPPET de "Identificação do primeiro candle de cada dia"
  // +
  // SNIPPET de "Identificação do primeiro tick de uma barra"
  if (Date() <> iDataAtual) then
    begin
      iDataAtual := Date();
      bPrimeiraBarraDoDia := true;
    end;
  if bPrimeiraBarraDoDia then
    begin
      bPrimeiraBarraDoDia := false;

      if (pTempoReal and LastBarOnChart) or not pTempoReal then
      if (CurrentBar <> iBarraAtual) then
        begin
          iBarraAtual := CurrentBar;
          bPrimeiroTickDaBarra := true;
        end
      else
        bPrimeiroTickDaBarra := false;

      if bPrimeiroTickDaBarra then
        begin
          //Faz alguma coisa no primeiro tick da barra
          //Aplicável apenas em execução de tempo real
          fObjetivoAtualGanho := pObjetivoGanhoDiario;
          fLimiteAtualPerda := pLimitePerdaDiaria;
          fNovaReferencia := 0;
        end;

    end;


  //-----------------------------------------------------------
  // SNIPPET de "Como limitar trades por objetivo de ganho ou limite de perda"
  // Resultado até o momento no dia (fechado + aberto)
    fResultado := DailyResult(true);
    plot(fResultado);
    SetPlotStyle(1,psDash);
    SetPlotColor(1,clGray);
    SetPlotType(1,igHistogram);

    plot2(fNovaReferencia - fLimiteAtualPerda);
    SetPlotStyle(2,psSolid);
    SetPlotColor(2,clRed);
    SetPlotWidth(2,3);

  // Estratégia qualquer de operação!!!
  // Estratégias apenas opera se resultado do dia não
  // tiver atingido objetivo de ganho ou limite de perda
  fResultadoDiario := DailyResult(true) - fNovaReferencia;

  if (fResultadoDiario > -1*fLimiteAtualPerda)
  and (fResultadoDiario < fObjetivoAtualGanho) then
  begin
    // SIMULAÇÃO DE ORDENS PARA FINS DE EXEMPLO
    for iHora := 0 to 8 do
    begin
      if (Time = (0900 + iHora*100)) or (Time = (0930 + iHora*100)) then
        if random(2) = 0 then BuyAtMarket else SellShortAtMarket;

      if (Time = (0920 + iHora*100)) Or (Time = (0950 + iHora*100)) then
        ClosePosition;
    end;

  end
  //Se resultado excedeu objetivo de ganho cria-se novos limites
  //Se atingiu limite de perda ou proteção de ganho então para de operar
  else 
  begin
    if fResultadoDiario <= -1*pLimitePerdaDiaria then
    begin
      if hasPosition then ClosePosition;
    end
    else
    if fResultadoDiario >= pObjetivoGanhoDiario then
    begin
       fNovaReferencia := fNovaReferencia + pObjetivoGanhoDiario;
       fLimiteAtualPerda := (pObjetivoGanhoDiario - pProtecaoGanho);
    end;

  end;

end;
				
			

Identificando resultado da última operação

Reproduzir vídeo

O código abaixo apresenta um exemplo de programação para identificar o resultado da última operação realizada. Assim, o trader pode realizar outras lógicas de limitação de sequência de trades com prejuízo, lucro e outras que desejar.

				
					var
  bHasPosition: boolean;
  iDia: integer;
  fResultadoFechadoDia, fResultadoTotalDia: float;
  fResultadoUltimoTrade, fResultadoAberto: float;
begin
  if (Date <> iDia) then
  begin
    iDia := Date;
    fResultadoUltimoTrade := 0;
  end;

  // ARMAZENAMENTO DE VARIÁVEIS (FACILITA A DEPURAÇÃO)
  bHasPosition := HasPosition;
  fResultadoTotalDia := DailyResult(true);
  fResultadoFechadoDia := DailyResult(false);

  // CALCULA O RESULTADO ABERTO
  if bHasPosition 
  then fResultadoAberto := fResultadoTotalDia - fResultadoFechadoDia
  else fResultadoAberto := 0;

  // CALCULA O RESULTADO DO ÚLTIMO TRADE
  if not bHasPosition and bHasPosition[1]
  then fResultadoUltimoTrade := fResultadoAberto[1];
 
  // PLOTA GRÁFICO PARA INSPEÇÃO VISUAL
  plot(fResultadoAberto);
  SetPlotType(1,igHistogram);
  if fResultadoAberto > 0 then SetPlotColor(1,clGreen)
  else if fResultadoAberto < 0 then SetPlotColor(1,clRed)
       else SetPlotColor(1,clGray);

  plot2(fResultadoUltimoTrade);
  SetPlotColor(2,clWhite);
  SetPlotStyle(2,psDash);
  SetPlotWidth(2,2);


  //ROTEAMENTO DE ORDENS
  if (Time = 0905) then BuyAtMarket;
  if (Time >= 0915) then ClosePosition;

end;
				
			

Como obter o preço médio executado durante montagem e realização parcial

É tarefa comum quando você está com um setup de montagem e realizações parciais querer estabelecer ordens de alvo e stop de acordo com o preço executado da última ordem e não do preço médio da posição.

É possível obter esse valor pelo código abaixo. No entanto, é importante ressaltar que devido às limitações da linguagem NTSL, caso haja várias execuções de ordens na mesma barra, o preço calculado de execução será o preço médio das ordens executadas na barra tendo em vista a diferença da posição.

				
					var
  iPosicao: integer;
  fPrecoMedio: float;
  fPrecoExecutado: float;

// ----------------------------------------------------------------------------------------
function getAvgFilledOrderPrice(previousPos: integer; previousPrice: Float; 
                                currentPos:integer; currentPrice: Float): float;
begin
  if  (currentPos <> 0) and (previousPos <> 0) 
  and (currentPos <> previousPos) then
  begin
    Result := (currentPos*currentPrice - previousPos*previousPrice)/(currentPos - previousPos);
  end
  else
    Result := 0;   
end;
// ----------------------------------------------------------------------------------------


begin
  // Como calcular preço médio de execução de ordens na barra
  iPosicao := Position;
  fPrecoMedio := Price;
  fPrecoExecutado := getAvgFilledOrderPrice(iPosicao[1], fPrecoMedio[1], iPosicao, fPrecoMedio);

  plot2(fPrecoExecutado);
  SetPlotType(2,igHistogram);
  // ---------------------------------------------------------

  if (Date = LastCalcDate) and (Time = 1500) then
      SellShortAtMarket(2);

  if (Date = LastCalcDate) and (Time = 1505) then
      BuyAtMarket(1);

  if (Date = LastCalcDate) and (Time = 1515) then
    SellShortAtMarket(2);

  if (Date = LastCalcDate) and (Time = 1530) then
    SellShortAtMarket(2);

  if (Time >= 1630) and hasPosition then ClosePosition;

  if hasPosition then Plot(Price);
  SetPlotColor(1, clWhite);
  SetPlotStyle(1, psDash);

end;
				
			

45 Comments

  • ANDERSON

    Novembro 3, 2022

    Bom dia
    Pode me ajudar como posso fazer a construção de duas variáveis pra realizar entradas na operação. Ex se hilo der condição e media der condição aí efetua a compra/Venda
    Obrigado

    Reply
    • Johnathas

      Novembro 4, 2022

      Posso, sim! Vou postar um snippet sobre isso.
      Abs!

      Reply
      • Paulo Cesar Soares Filho

        Dezembro 5, 2022

        Olá Johnathas. Como faço pra acompanhar outras postagens suas como esses códigos??

        Reply
        • Johnathas

          Dezembro 6, 2022

          Oi Paulo! Tudo bem!?
          Você pode acompanhar inscrevendo no Canal do Youtube. Sempre que posto um novo snippet eu costumo gravar um vídeo explicando.
          http://www.youtube.com/@neotraderbot
          Abs!

          Reply
  • Luiz A. M. Pereira

    Novembro 23, 2022

    Área excelente ! Administração de trade tem códigos ai bem úteis !

    Reply
  • Fabio Araujo

    Dezembro 27, 2022

    Fala meu amigo… Muito bom seu conteúdo. Obrigado por compartilhar seu conhecimento.
    Será que vc poderia explicar como realizar apenas a primeira operação de compra em uma sequência de sinais de compra e depois só entrar novamente se aparecer um sinal de venda e assim sucessivamente.
    Ou seja, fazer um compra e depois só entrar em operação se aparecer uma venda… E vice versa.
    Muito grato.

    Reply
    • Johnathas

      Dezembro 28, 2022

      Olá Fábio! Primeiramente, obrigado!
      Claro posso explicar sim. Isto é bem simples de ser feito.
      Peço apenas, por favor, que você poste uma dúvida no fórum da Comunidade para que outras pessoas possam se beneficiar e encontrar a informação de maneira mais fácil.
      Grande abs!

      Reply
  • alexandrecnunes

    Fevereiro 3, 2023

    Olá 

    Estudando o snippet Stoploss móvel (Versão contínua) + Breakeven disponibilizado site, fiquei com uma duvida na seguinte linha:

    if bPosicionado or bPosicionado[1] or bPosicionado[2] then

    o que são bPosicionado[1] e bPosicionado[2] ? seriam posições em candle anteriores ou em ticks anteriores?

    Reply
    • Johnathas

      Fevereiro 3, 2023

      Boa tarde Alexandre!
      Seria a variável booleana que indica se estava posicionado nos candles anteriores.
      Não há indexação para tick em NTSL. Enquanto uma barra não fecha, as variáveis são atualizadas no valor atual.
      A indexação sempre refere-se ao valor da variável calculado no último tick da barra.
      Abs!

      Reply
      • Hermano Nunes

        Agosto 3, 2023

        Olá, Johnathas! Boa noite!

        O valor do último tick podemos identificar utilizando close[0], correto?

        Sabe infomar como pegar o valor do penúltimo tick?

        Obrigado!

        Reply
        • Johnathas

          Agosto 4, 2023

          Oi Hermano!
          Enquanto uma barra está sendo formada, ao salvar close[0] em uma variável você terá o valor do penultimo tick antes de salvar para o tick atual o valor de close[0] nessa mesma variável.
          Entendeu!?
          Abs!

          Reply
  • SERGIO ARNALDO FERNANDES DA SILVA

    Março 18, 2023

    Boa Noite Johnathas.
    Gostaria de saber como limitar o meu código para rodar só em um numero de conta especifica.

    Reply
    • Johnathas

      Março 20, 2023

      Olá, Sérgio!
      Infelizmente não há função em NTSL para verificar o código da conta ou licença do Profit na qual o código está sendo executado.
      Imagino que seja proposital da Nelogica, pois isso iria gerar uma concorrência com a Loja de Estratégias.

      Grande abs!

      Reply
  • eduardo cardoso

    Junho 1, 2023

    Johnathas, há como utilizar os medidores de pressão em algum indicador no editor de estratégias? preciso da informação de volume de ofertas no livro, tanto para venda quanto para compra, mas não consigo essa informação de modo a ser utilizada no editor de estratégias. Pode me ajudar?

    Reply
    • Johnathas

      Junho 6, 2023

      Olá Eduardo! Sim, tem como…e a solução é bem recente ainda nem está na documentação da NTSL. As funções são TotalBuyQtd,TotalSellQtd, BuyOfferCount e SellOfferCount.
      Essas funções retornam os valores do medidor de pressão. No entanto, quando testei há 1 ou 2 semanas atrás ainda estavam com bug para fornecer a qtde de níveis de preço a serem consolidados.
      Grande abs!

      Reply
  • Bruno Chimenti

    Julho 6, 2023

    Olá! Muito grato pelo seu trabalho. Tenho uma dúvida que talvez seja de muita gente… Estou executando uma estratégia em que ao identificar um sinal de compra, é colocada uma ordem stop na máxima do candle que deu condição. Acontece que ele só executa a ordem caso a máxima seja superada imediatamente no candle seguinte. Existe alguma forma de manter essa ordem para que ela seja executada mesmo que só rompa o valor em candles subsequentes, mesmo que não seja logo após esse candle que deu condição? Agradeço desde já . Grande abraço!

    Reply
    • Johnathas

      Julho 24, 2023

      Olá Bruno! Esse é o comportamento padrão da engine NTSL, mas é possível programar para que o sinal perdure ao longo do tempo como desejar. Respondi você lá no fórum!
      Grande abs!

      Reply
  • Leandro

    Julho 8, 2023

    Johnathas não estou conseguindo executar o comando closeposition no início do candle. Eu envio a instrução, mas ela só é executada no fechamento do candle e acaba sendo executado no próximo candle.

    Reply
    • Johnathas

      Julho 24, 2023

      Olá Leandro!
      Cara, esse é o comportamento esperado das estratégias de execução em gráficos e no backtesting. O módulo de Automação tem uma configuração para que a execução de ordens seja realizada no tick.
      Assiste a esse vídeo para entender um pouco mais sobre esse assunto: https://www.youtube.com/watch?v=g8oWovIxGgs.

      Grande abs!

      Reply
  • Bruno Chimenti

    Julho 25, 2023

    Olá! é impressao minha ou o codigo que esta aqui na pagina para a versao “Stoploss móvel (Versão contínua) + Breakeven” está errado… Pelo que vi, parece que o codigo que esta ali seria da versão baseada em passos.

    Por hora, vou pausar o video para estudar linha a linha o codigo e agradeço de montao os conteudos. ja nao esta facil contornar todas as limitacoes do profit. imagino sem a ajuda de alguem como voce… bom trabalho!

    Reply
    • Johnathas

      Julho 27, 2023

      Fala Bruno! Vlw pelo reconhecimento!
      O código está correto sim. Depois olha com mais cuidado.
      Abs!

      Reply
  • Bruno Chimenti

    Julho 26, 2023

    John, é possível fazer um trailing Stop que va atualizando no tick, para que ele se comporte como as estrategias OCO, configuradas na interface gráfica do Editor de Estrategias Stop? Mesmo na execucao tick a tick do modo de automação, se eu coloco uma ordem stop cujo alvo esta referenciado ao fechamento ou a máxima (Ex: maxima-StopOffset), ele aparentemente nao move o stop no tick a tick, subindo conforme o preço sobe, como acontece nas ordens OCO,que se move na frequência de ajuste definida nos parâmetros da estrategia OCO .

    Caso a ordem nao possa ser atualizada no tick, uma solução seria fazer uma condição if -> then, tipo:
    if close< maxima-StopOffset then closeposition;

    Dessa forma voce acha que ele funcionaria como um stop móvel desse tipo das ordens OCO?

    Reply
    • Johnathas

      Julho 27, 2023

      Olá Bruno! Infelizmente não…Hoje do jeito que é, as ordens OCO são atualizadas apenas no fechamento da Barra.
      Se você fizer isto que está sugerindo no Módulo de Automação configurado para execução no tick você terá o mesmo efeito que deseja de stop. Único detalhe é que você não precisa colocar o StopOffset na sua condição.
      Como você vai fazer um encerramento de posição a mercado quando o preço for menor que Máxima, você vai incorrer no slippage…e é só isso!
      Grande abs!

      Reply
  • carlosdigital13

    Agosto 2, 2023

    Olá John, muito bom todo o conteúdo postado aqui e no youtube, sensacional. Seria possível vc fazer um vídeo explicativo pra nós colocando no código o TrailingStop, Breakeven e Parcial junto?

    Muito obrigado pela atenção

    Reply
    • Johnathas

      Agosto 4, 2023

      Oi Carlos! Obrigado!
      Trailling stop com Breakeven já tem snippet. A questão de parcial é mais complicadinho porque não tem muita liberdade para fazer parcial de maneira genérica. Tem que fazer já com quantidade de saídas parciais fixas.
      Meu plano é liberar um Framework avançado que contempla parametros para você colocar isso tudo junto, sem ter que programar…apenas parametrizar as entradas e saidas.
      No início da semana que vem já devo ter lançado a primeira versão do framework para você ter uma ideia do que estou falando.

      Abs!

      Reply
  • Nelson Martins Brudeki

    Setembro 6, 2023

    Johnathas, boa tarde!

    É possível fazer um stop móvel para ser utilizado no profit plano básico? Quanto custaria?

    Obrigado

    Nelson

    Reply
  • tarrierbr

    Setembro 11, 2023

    Boa tarde Johnathas. Será que poderias me ajudar a colocar a estratégia de como obter o preço médio executado durante montagem e realização parcial, em uma automação da estratégia Gradiente? Exemplo estou operando, no momento estou com 9 contratos comprados e 6 vendidos, gostaria de sair da operação em algum momento que desse lucro. Digamos que a estratégia tenha 6 pontos de compra e 6 pontos de venda. Algum código já pronto?

    Reply
    • Johnathas

      Setembro 29, 2023

      Olá tarrier! Infelizmente eu não tenho códigos prontos em NTSL para o setup de gradiente linear.
      O que posso lhe dizer é que é possível personalizar qualquer lógica de entrada e saída (uma vez que não esbarre em limitações da plataforma).
      Minha sugestão seria que avaliasse fazer o curso de “Automatização de Trading em NTSL” onde certamente você encontrará material e suporte para criar as suas próprias estratégias com autonomia. Veja esse link para mais informações: https://neotraderbot.com/curso-automatizacao-de-trading-em-ntsl/.
      Grande abs!

      Reply
  • Raquel

    Setembro 20, 2023

    Boa noite. Excelente teus vídeos. Colocando para execução o código do Gestão de Risco diária e Proteção de Ganhos, percebo que é desconsiderado o pavio e feita a execução na abertura da barra, de maneira que fica referenciada a saída da operação no tempo passado, trazendo irreal resultado do backtest. Certo? As saídas aparecem nas máximas ou mínimas e não na pProtecaoGanho. Alguma forma de resolver? Ainda que a ordem de saída fosse executada no fechamento da barra em que a pProtecaoGanho foi atingida, seria melhor. Porém na abertura dela acabada sendo irreal. Agradeço.

    Reply
    • Johnathas

      Setembro 29, 2023

      Oi Raquel! É possível modificar o snippet para que ele atue com ordens limitadas e stop, ao invés de ordens a mercado. Como pode perceber as ordens a mercado no backtesting são preenchidas com o preço de abertura da próxima barra.
      Minha sugestão seria que avaliasse fazer o curso de “Automatização de Trading em NTSL” onde certamente você encontrará material e suporte para criar as suas próprias estratégias com autonomia. Veja esse link para mais informações: https://neotraderbot.com/curso-automatizacao-de-trading-em-ntsl/.
      Grande abs!
      Grande abs!

      Reply
  • Cezar A M Mello

    Setembro 27, 2023

    Bom dia.
    Seria possível uma instrução para o bot efetuar só uma compra , e depois só uma venda , e assim consecutivamente ?

    Reply
    • Johnathas

      Setembro 29, 2023

      Olá Cezar!
      Esse tipo de alternância de lógica é possível sim. Basta criar uma variável booleana para fazer esse chaveamento.
      Grande abs!

      Reply
  • Marco

    Outubro 8, 2023

    Boa noite Johnathas , teria álbum snippt que além de Identificar o resultado da última operação, em caso de loss, identificar se foi de compra ou venda?

    Reply
    • Johnathas

      Outubro 18, 2023

      Olá Marco!
      Não lembro de ter colocado isso em snippet. Mas é uma lógica simples. Basta você armazenar no momento da compra ou venda em uma variável qual foi a ordem executada.
      Assim quando você verificar o resultado da última operação, encontrará nessa variável temporária qual foi a posição que estava aberta (comprado ou vendido).
      Abs!

      Reply
  • Sergio kaike da silva fernandes

    Outubro 14, 2023

    Fala Jhon Beleza, cara estou tentando utilizar o codigo de protecao de gannhos movel porém quando coloco pTempoReal(True) no replay ele nao abre operações, se eu deixo em False ele abre porem nao protege os ganhos. Poderia verificar o codigo por gentileza

    Reply
    • Johnathas

      Outubro 18, 2023

      Olá Sergio! Pode utilizar com este parâmetro em false.
      A questão é que depois que lancei esse snippet houve algumas alterações no modelo de execução da NTSL. Recentemente eu estava vendo esse snippet, mas me deparei com um bug da função DailyResult.
      O bug refere-se ao fato de contabilizar como lucro/prejuízo a variação da próxima barra, mesmo a posição tendo sido estopada.
      A Nelógica terá que corrigir esse bug para que eu possa revisar este código.
      Grande abs!

      Reply
  • Rocha75

    Novembro 4, 2023

    Inicialmente gostaria de agradecer ao Johnathas pela iniciativa do site e a ajuda oferecida a todas as duvidas e os códigos disponibilizados. Muito obrigado

    Estou estudando o código do stop móvel, tentei incluir mais uma ordem no código, a intenção é depois de fechar a posição, abrir outra entrada no mesmo preço.

    Esta funcionando corretamente, mas algumas vezes, logo depois de fazer a reversão, faz uma nova entrada em seguida, já tentei alterar de varias forma, mas esta entrada na sequencia da reversão persiste.

    O código ficou desta forma abaixo

    if Not bModuloAutomacao then
    begin
    SellToCoverStop(fPrecoStop,fPrecoStopOffset);
    SellshortStop(fPrecoStop,fPrecoStopOffset); linha incluida para fazer a reversão
    if isBought then SellToCoverLimit(fPrecoAlvo);
    end
    else
    begin
    SellShortStop(fPrecoStop,fPrecoStopOffset);
    SellToCoverStop(fPrecoStop,fPrecoStopOffset); linha incluida para fazer a reversão
    if isBought then SellShortLimit(fPrecoAlvo);
    end;

    Fora esta alteração, não fiz nenhuma outra mudança no código.

    Você poderia por gentileza me mostrar qual a alteração adequada que devo fazer no código para
    fazer a reversão no momento em que a posição fecha no stop móvel ?

    Obrigado

    Reply
    • Johnathas

      Novembro 8, 2023

      Olá Rocha75! Lembro de termos falado, quando você perguntou, sobre essa dúvida na 2ª Reunião Aberta. Se alguem tiver a mesma dúvida, a pergunta foi respondida no final da LIVE que está gravada e disponível no Youtube.
      Grande abs e sucesso!

      Reply
  • Antonio Junior

    Novembro 23, 2023

    Bom dia! Tem alguma postagem sobre parciais? Exemplo entrada de 5 contratos, fecha 4 com 50 pontos e o ultimo com 300…. simples né? Mas não estou achando para adaptar ao meu código, obrigado!

    Reply
    • Johnathas

      Dezembro 3, 2023

      Olá Antônio!
      Cara, basta você colocar dois comandos de ordens ToCover. Se você está comprado em 5 contratos, coloque:
      If isBought then
      begin
      SellToCoverLimit(Price + 50, 4);
      SellToCOverLimit(Price+300, 1);
      end;

      Abs

      Reply
  • Joao

    Novembro 30, 2023

    A função DailyResult só retorna 0,00. Por que não funciona mais?

    Reply
    • Johnathas

      Dezembro 3, 2023

      Olá João! (Infelizmente) É bastante frequente observarmos falhas nessa função em NTSL. Abs!

      Reply
  • Dorival Dias

    Setembro 19, 2024

    Boa tarde John, blz?!

    Quero te agradecer pelo conteúdo de qualidade que coloca aqui no site. Espero em breve fazer seu curso completo para melhorar ainda mas nesse conhecimento.
    Com certeza vc ajuda muita gente a atingir seus objetivos. Agradeço mesmo.

    Gostaria de tirar uma dúvida.
    Não estou conseguindo colocar os valores das order BuyPrice e SellPrice em variáveis. Retornam valores diferentes do que está efetivamente comprado ou vendido. Tem algo que precisa ser feito ara que eles retornem o valor exato que aparece no gráfico.

    Muito obrigado!

    Reply
    • Johnathas

      Outubro 14, 2024

      Olá Dorival!
      As funções BuyPrice e SellPrice retornam o valor do preço médio da posição quando você está comprado ou vendido. O função Price retorna o valor independente de estar comprado ou vendido.
      O preço retornado depende da forma como você configura o cálculo do preço médio na plataforma. Mas a principio deve retornar o que você vê no gráfico.

      Abs!

      Reply

Leave a Comment

CONTENTS