Códigos de exemplo? Tome Snippets! Ordens e Administração de Trade Estimated reading: 14 minutes 27232 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 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 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 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) 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 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) 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) 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 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 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 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;