Boa Noite,
Estou tentando implementar uma saida parcial no codigo aqui mesmo da comunidade, mas não estou conseguindo, se alguem puder ajudar a idéia e fazer uma parcial e deixar o restante dos lotes sair quando o TraillingStop atintigir o preço.
Codigo da Comunidade
const//Relação risco/ganho de 3:1cStopEmTicks = 30;cBreakevenEmTicks = 10;cTraillingStopTrigger = 20;cTrailingStepEmTicks = 20;cTrailingStopOffset = 10;cStopOffsetEmTicks = 10;cAlvoEmTIcks = 90; inputbGestaoDeRiscoPelaEstrategia(true);bModuloAutomacao(false);iHorarioInicioAberturaPosicao(0905);iHorarioFimAberturaPosicao(1630);iHorarioEncerramentoDaytrade(1645); variCaraCoroa: 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 vendaif Not bPosicionadoand (Time >= iHorarioInicioAberturaPosicao)and (Time <= iHorarioFimAberturaPosicao)thenbegin//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 := trueelse bSinalVenda := true;end; //Gera ordem de compra a mercado quando há um Sinal de COMPRA//e define ordem stoploss e take profitif bSinalCompra then BuyAtMarket; //Gera ordem de venda a mercado quando há um Sinal de VENDA//e define ordem stoploss e take profitif bSinalVenda then SellShortAtMarket; if bGestaoDeRiscoPelaEstrategia thenbegin//Código responsável pela manutenção das ordens de stoploss e take profitif isBought thenbeginif Not bConfigurouRiscoInicial thenbeginfPrecoStop := 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 thenfPrecoStop := fFloorTraillingStop - cTrailingStopOffset*MinPriceIncrement; if (Close >= (BuyPrice + cBreakevenEmTicks*MinPriceIncrement))and (not bBreakevenAtivado) thenbeginbBreakevenAtivado := true;if fPrecoStop < BuyPrice then fPrecoStop := BuyPrice;end; fPrecoStopOffset := fPrecoStop-cStopOffsetEmTicks*MinPriceIncrement; if Not bModuloAutomacao thenbeginSellToCoverStop(fPrecoStop,fPrecoStopOffset);if isBought then SellToCoverLimit(fPrecoAlvo);endelsebeginSellShortStop(fPrecoStop,fPrecoStopOffset);if isBought then SellShortLimit(fPrecoAlvo);end;end; //Código responsável pela manutenção das ordens de stoploss e take profitif isSold thenbeginif Not bConfigurouRiscoInicial thenbeginfPrecoStop := 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 thenfFloorTraillingStop := SellPrice- floor((SellPrice - Close)/(cTrailingStepEmTicks*MinPriceIncrement))*cTrailingStepEmTicks*MinPriceIncrement; if ((fFloorTraillingStop+cTrailingStopOffset*MinPriceIncrement) <= fPrecoStop)and (Close <= SellPrice - cTrailingStepEmTicks*MinPriceIncrement)and bTrailingStopAtivado thenfPrecoStop := fFloorTraillingStop + cTrailingStopOffset*MinPriceIncrement; if (Close <= (SellPrice - cBreakevenEmTicks*MinPriceIncrement))and (not bBreakevenAtivado) thenbeginbBreakevenAtivado := true;if fPrecoStop > SellPrice then fPrecoStop := SellPrice;end; fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement; if Not bModuloAutomacao thenbeginBuyToCoverStop(fPrecoStop,fPrecoStopOffset);if isSold then BuyToCoverLimit(fPrecoAlvo);endelsebeginBuyStop(fPrecoStop,fPrecoStopOffset);if isSold then BuyLimit(fPrecoAlvo);end; end; //Encerra posicaoif (Time >= iHorarioEncerramentoDaytrade)and HasPositionthen ClosePosition; if Not hasPosition and bConfigurouRiscoInicial thenbeginbConfigurouRiscoInicial := false;bBreakevenAtivado := false;bTrailingStopAtivado := false;end; end; // Plot de Stop e Alvo para inspeção visual do códigobPosicionado := hasPosition;if bPosicionado or bPosicionado[1] or bPosicionado[2] thenbeginPlotN(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);endelsebeginNoPlot(1);NoPlot(2);NoPlot(3);end; end;
const//Relação risco/ganho de 3:1cStopEmTicks = 30;cBreakevenEmTicks = 10;cTraillingStopTrigger = 20;cTrailingStepEmTicks = 20;cTrailingStopOffset = 10;cStopOffsetEmTicks = 10;cAlvoEmTIcks = 90;
inputbGestaoDeRiscoPelaEstrategia(true);bModuloAutomacao(false);iHorarioInicioAberturaPosicao(0905);iHorarioFimAberturaPosicao(1630);iHorarioEncerramentoDaytrade(1645);
variCaraCoroa: 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 vendaif Not bPosicionadoand (Time >= iHorarioInicioAberturaPosicao)and (Time <= iHorarioFimAberturaPosicao)thenbegin//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 := trueelse bSinalVenda := true;end;
//Gera ordem de compra a mercado quando há um Sinal de COMPRA//e define ordem stoploss e take profitif bSinalCompra then BuyAtMarket;
//Gera ordem de venda a mercado quando há um Sinal de VENDA//e define ordem stoploss e take profitif bSinalVenda then SellShortAtMarket;
if bGestaoDeRiscoPelaEstrategia thenbegin//Código responsável pela manutenção das ordens de stoploss e take profitif isBought thenbeginif Not bConfigurouRiscoInicial thenbeginfPrecoStop := 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 thenfPrecoStop := fFloorTraillingStop - cTrailingStopOffset*MinPriceIncrement;
if (Close >= (BuyPrice + cBreakevenEmTicks*MinPriceIncrement))and (not bBreakevenAtivado) thenbeginbBreakevenAtivado := true;if fPrecoStop < BuyPrice then fPrecoStop := BuyPrice;end;
fPrecoStopOffset := fPrecoStop-cStopOffsetEmTicks*MinPriceIncrement;
if Not bModuloAutomacao thenbeginSellToCoverStop(fPrecoStop,fPrecoStopOffset);if isBought then SellToCoverLimit(fPrecoAlvo);endelsebeginSellShortStop(fPrecoStop,fPrecoStopOffset);if isBought then SellShortLimit(fPrecoAlvo);end;end;
//Código responsável pela manutenção das ordens de stoploss e take profitif isSold thenbeginif Not bConfigurouRiscoInicial thenbeginfPrecoStop := 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 thenfFloorTraillingStop := SellPrice- floor((SellPrice - Close)/(cTrailingStepEmTicks*MinPriceIncrement))*cTrailingStepEmTicks*MinPriceIncrement;
if ((fFloorTraillingStop+cTrailingStopOffset*MinPriceIncrement) <= fPrecoStop)and (Close <= SellPrice - cTrailingStepEmTicks*MinPriceIncrement)and bTrailingStopAtivado thenfPrecoStop := fFloorTraillingStop + cTrailingStopOffset*MinPriceIncrement;
if (Close <= (SellPrice - cBreakevenEmTicks*MinPriceIncrement))and (not bBreakevenAtivado) thenbeginbBreakevenAtivado := true;if fPrecoStop > SellPrice then fPrecoStop := SellPrice;end;
fPrecoStopOffset := fPrecoStop + cStopOffsetEmTicks*MinPriceIncrement;
if Not bModuloAutomacao thenbeginBuyToCoverStop(fPrecoStop,fPrecoStopOffset);if isSold then BuyToCoverLimit(fPrecoAlvo);endelsebeginBuyStop(fPrecoStop,fPrecoStopOffset);if isSold then BuyLimit(fPrecoAlvo);end;
end;
//Encerra posicaoif (Time >= iHorarioEncerramentoDaytrade)and HasPositionthen ClosePosition;
if Not hasPosition and bConfigurouRiscoInicial thenbeginbConfigurouRiscoInicial := false;bBreakevenAtivado := false;bTrailingStopAtivado := false;end;
// Plot de Stop e Alvo para inspeção visual do códigobPosicionado := hasPosition;if bPosicionado or bPosicionado[1] or bPosicionado[2] thenbeginPlotN(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);endelsebeginNoPlot(1);NoPlot(2);NoPlot(3);end;
Foi postado recentemente neste fórum um código exemplo de saída parcial na qual vc pode adaptar o seu código.
const cTamanhoPosicaoInicial (2); //Define a constante para o tamanho inicial da posição. var bSinalCompra: boolean; bSinalVenda: boolean; fStopCompra, fStopVenda: float; bEstaPosicionado: boolean; fAlvoParcial: float; iTamanhoPosicaoParcial: integer; begin {Busca as Entrada} If Not (IsBought) and (bSinalCompra) then begin fStopCompra := fAlvoParcial := BuyAtMarket(cTamanhoPosicaoInicial); bestaPosicionado := verdadeiro; end; //Verifica ainda não foi aberta uma posição comprada e se o sinal de compra é verdadeiro. Em seguida, define os valores do stop loss e do alvo parcial de lucro, bem como faz uma ordem de compra a mercado para a posição inicial. Por fim, atualiza a variável bestaPosicionado para verdadeiro, indicando que uma posição foi aberta. If Not(IsSold) and ((bSinalVenda) then begin fStopVenda := fAlvoParcial := SellShortAtMarket(cTamanhoPosicaoInicial); bestaPosicionado := verdadeiro; end; //Verifica ainda não foi aberta uma posição vendida e se o sinal de venda é verdadeiro. Atribuí os valores de Stoploss, Alvo e faz a venda, altera a variável bestaPosicionado para verdadeiro, indicando que uma posição foi aberta. {Calcula os valores de saída parcial da compra} if (IsBought) e (bEstaPosicionado) then begin iTamanhoPosicaoParcial := Ceiling(cTamanhoPosicaoInicial / 2); bEstaPosicionado := falso; end; //Se o ativo foi comprado e uma posição foi aberta, calcula o tamanho da posição parcial com base na metade do tamanho da posição inicial. A função Ceiling é usada caso a posição inicial seja um valor impar ex. 3, logo em seguida muda a variável /estaPosicionado para falso, indicando que a posição parcial foi calculada. {Calcula os valores de saída parcial da venda} if (IsSold) e (bEstaPosicionado) then begin iTamanhoPosicaoParcial := Ceiling(cTamanhoPosicaoInicial / 2); bEstaPosicionado := falso; end; //Mesma lógica do bloco anterior para compra. {Busca a saída parcial da compra} If (IsBought) And (Position = cTamanhoPosicaoInicial) then begin SellToCoverLimit(AlvoParcial,tamanhoPosicaoParcial); End; {Busca saída parcial da Venda} If (IsSold) and (Position = neg(iTamanhoPosicaoInicial)) then begin BuyToCoverLimit(fAlvoParcial,iTamanhoPosicaoParcial); end; {Recalcula posicao e ordens de compra} if (IsBought) e (Position < cTamanhoPosicaoInicial) then begin iTamanhoPosicaoParcial := Position; end; //Atribui a variável iTamanhoPosicaoParcial o valor do restante da posicao {Recalcula posição e ordens de venda} //Como a função "Position" retorna um valor negativo é preciso usar a função "neg" if (IsSold) e (Position > neg(iTamanhoPosicaoInicial)) then inicio iTamanhoPosicaoParcial := Position; fim; End;