Um backtesting adequado deve buscar simular situações práticas do mercado (slippage, custo de operação, etc...)
Olá! Embora tenha assistido os vídeos para evitar execução em gap em renko, bem como impor horário limite para a programação, na hora de colocar no código se torna bem mais difícil. Seria possível implementar essas duas situações no código abaixo? Lembrando que o código foi feito de forma totalmente amadora, por minha pessoa, coletando dados na internet. Forte abraço aos amigos!
/COMPRA E VENDA MAX MIN DIA //
begin
If (time > 0915) e (time < 1700) and (BuyPosition = 0) and (SellPosition = 0) then
begin
Se (Fechamento > Fechamento[1]) e (Fechamento[1] = (LowD(0)[1]) )
Then BuyAtMarket;
end;
Se(isBought = true) então
Se (Fechamento < Fechamento[1]) e (highest(High,2) > highest(high,2)[1])then
SellToCoverAtMarket;
If (time > 1700) then sellToCoverAtMarket;
begin
If (time > 0915) e (time < 1700) and (BuyPosition = 0) and (SellPosition = 0) then
begin
Se (Fechamento < Fechamento[1]) e (Fechamento[1] = (HIGHD(0)[1])) then
SellShortAtMarket;
end;
Se(issold = true) então
Se (Fechamento > Fechamento[1]) e (lowest(low,2) < lowest(low,2)[1])then
BuyToCoverAtMarket;
If (time > 1700) then BuyToCoverAtMarket;
end;
end;
end;
end;
Oi Leandro!
Respondendo objetivamente a sua pergunta, o código seria conforme abaixo.
Mas não sei se código está fazendo exatamente o que deseja.
Se quiser uma ajuda, responda de forma objetiva em que tipo de gráfico vai operar (quantos R's), qual é o sinal de abertura de posição e de encerramento, e quais são as restrições de horários que deseja.
Abs!
var bLocalizouBoxesGap : boolean; iDataUltimoBox, iUltimoBoxDiaAnterior, iBoxDeGAP: integer; begin // Código é aplicável apenas à gráficos do tipo Renko if GraphicInterval = itRenko then begin // Identificação de Box relacionados a GAP if Date <> iDataUltimoBox then begin iUltimoBoxDiaAnterior := CurrentBar - 1; iBoxDeGAP := CurrentBar; bLocalizouBoxesGap := false; end; iDataUltimoBox := Date; if Not bLocalizouBoxesGap then if BarDurationF = 0 then begin iBoxDeGAP := CurrentBar; PaintBar(clRed); end else begin //Aqui foi identificado o primeiro box que não é de GAP bLocalizouBoxesGAP := true; end; //Aqui executa a estratégia em boxes que não são devido à //gap de abertura if bLocalizouBoxesGAP then begin If (time > 0915) e (time < 1700) and (BuyPosition = 0) and (SellPosition = 0) then begin Se (Fechamento > Fechamento[1]) e (Fechamento[1] = (LowD(0)[1]) ) Then BuyAtMarket; end; Se(isBought = true) então Se (Fechamento < Fechamento[1]) e (highest(High,2) > highest(high,2)[1]) then SellToCoverAtMarket; If (time > 1700) then sellToCoverAtMarket; If (time > 0915) e (time < 1700) and (BuyPosition = 0) and (SellPosition = 0) then begin Se (Fechamento < Fechamento[1]) e (Fechamento[1] = (HIGHD(0)[1])) then SellShortAtMarket; end; Se(issold = true) então Se (Fechamento > Fechamento[1]) e (lowest(low,2) < lowest(low,2)[1])then BuyToCoverAtMarket; If (time > 1700) then BuyToCoverAtMarket; end; end; end; end; end // O Gráfico não é do tipo Renko! else if LastBarOnChart then PlotText("Aplicável apenas a Renko",clWhite,-1,10); end
@admin embora o backtest do profit nao seja dos mais confiáveis, ele teve uma curva de capital ascendente em 18R. Então esse seria o "R" a ser utilizado.
O sinal de abertura de posição é a ocorrência de um preço de fechamento de reversão (PFR) logo após uma maxima ou minima do dia.
O sinal de saída seria um preço de fechamento de reversão (PFR) contra o movimento de compra ou venda feito.
@admin restrições de horario seriam abertura e fechamento de pregão. Pensei em 09:15 e 16:45, por exemplo. Estas restrições foram uma tentativa do código nao passar "comprado" ou "vendido" de um dia para o outro, o que em daytrade seria péssimo.
@admin nesta imagem é um exemplo do erro, pois o fechamento foi no gap do dia posterior a entrada.
@admin aqui tambem seria um erro, pois passou 2 dias comprado.
@leandro-master No caso de robô em Renko no Profit, o encerramento de posição via código é mais complicado porque as ordens só são executados após o fechamento. O que pode não ocorrer no dia. Pela interface gráfica do Módulo de Automação é possível adicionar encerramento de posição por horário. Eu não sei se funciona, mas acho que vale a pena configurar lá para ver se as posições são encerradas pelo horário corretamente.
@leandro-master Evolui um pouco no seu código (evolui no sentido que alterei...rsrsrs...não que tenha ficado melhor...kkkk)
Olha aí, rodei para DOLFUT 18R e funcionou tranquilo....Pontos a se observar:
Enfim, como eu não vejo possibilidade de resolver via código a questão do encerramento de daytrade, eu sugiro exportar a planilha de trades e analisar no excel o resultado removendo os trades que foram carregados para dias seguintes.
Grande abs!
var bLocalizouBoxesGap : boolean; iDataUltimoBox, iUltimoBoxDiaAnterior, iBoxDeGAP: integer; bConfigurouGestaoRisco: boolean; fPrecoStop: float; iStopOffsetEmTicks: integer; begin // Código é aplicável apenas à gráficos do tipo Renko if GraphicInterval = itRenko then begin iStopOffsetEmTicks := GraphicOffset - 1; // Identificação de Box relacionados a GAP if Date <> iDataUltimoBox then begin iUltimoBoxDiaAnterior := CurrentBar - 1; iBoxDeGAP := CurrentBar; bLocalizouBoxesGap := false; end; iDataUltimoBox := Date; if Not bLocalizouBoxesGap then if BarDurationF = 0 then begin iBoxDeGAP := CurrentBar; //PaintBar(clRed); end else begin //Aqui foi identificado o primeiro box que não é de GAP bLocalizouBoxesGAP := true; end; //Aqui executa a estratégia em boxes que não são devido à //gap de abertura if bLocalizouBoxesGAP then begin If (Time <= 1600) and Not hasPosition then begin // Compra no PFR após box reverter o preço mínimo do dia If (Close[1] < Close[2]) and (Close > Close[1]) and ((Close[1] - LowD(0)) < 2*iStopOffsetEmTicks*MinPriceIncrement) then begin BuyAtMarket; bConfigurouGestaoRisco := false; end; // Venda no PFR após box reverter o preço máximo do dia If (Close[1] > Close[2]) and (Close < Close[1]) //and (High[1] = HighD(0)) then and ((HighD(0) - Close[1]) < 2*iStopOffsetEmTicks*MinPriceIncrement) then begin SellShortAtMarket; bConfigurouGestaoRisco := false; end; end; // Se estiver comprado, encerra posição no primeiro // box que fecha contra posição If isBought then begin if Not bConfigurouGestaoRisco then begin fPrecoStop := buyPosition - iStopOffsetEmTicks*MinPriceIncrement; bConfigurouGestaoRisco := true; end; SellToCoverStop(fPrecoStop, fPrecoStop - 3*iStopOffsetEmTicks*MinPriceIncrement); if isBought and (Close[1] > Close) then ClosePosition; end; // Se estiver vendido, encerra posição no primeiro // box que fecha contra posição If isSold then begin if Not bConfigurouGestaoRisco then begin fPrecoStop := sellPrice + iStopOffsetEmTicks*MinPriceIncrement; bConfigurouGestaoRisco := true; end; BuyToCoverStop(fPrecoStop, fPrecoStop + 3*iStopOffsetEmTicks*MinPriceIncrement); if isSold and (Close[1] < Close) then ClosePosition; end; //Se houver fechamento de box após este horário, a // estratégia conseguiria encerrar posição de daytrade If (Time >= 1645) then ClosePosition; if Not HasPosition and bConfigurouGestaoRisco then bConfigurouGestaoRisco := false; end; Plot(HighD(0)); Plot2(LowD(0)); SetPlotColor(1,clRed); SetPlotColor(2,clGreen); end // O Gráfico não é do tipo Renko! else if LastBarOnChart then PlotText("Aplicável apenas a Renko",clWhite,-1,10); end
@admin pois é. Ja tinham me alertado pra essas variaveis do renko. Por isso que os backtest's em renko tem muitos aspectos a serem avaliados, nao da pra ir se enganando com o primeiro resultado que aparece, ainda mais no profit.
@admin rapaz, que isso hein. Eu te entreguei um fusca e vc esta me devolvendo uma ferrari!!! Gratidão imensa pelo seu trabalho. Muito obrigado, de coração!!!
Que isso, precisando estamos aí!
Abs e boa programação!
Oi, não estou conseguindo fazer funcionar breakeven e tralling stop nessa estratégia abaixo. Poderia ver onde estou errando... pinta o candle sinalizando, mas não executa
//teste 10/11 executando corretamente, exceto ação tick a tick -aguaradando ação na abertura da barra seguinte
Const //não está executando traillingStop e breackenven.
// Configurações
HoraUltimaEntrada = 1640;
HoraFechamento = 1740;
LoteTotal = 3;
LoteParcial = 1;
LoteNivel61 = 1;
LoteNivel50 = 1;
LoteNivel38 = 1;
StopEmTicks = 6;
StopOffSetEmTicks = 10;
TraillingStopOffSet = 20;
BreakevenEmticks = 10;
AlvoBE = 1.38;
input
max(5366);
min(5262);
var
breakevenAtivado: Boolean;
AlvoC61,SinalC6,SinalC5,SinalC4:Boolean;
Breakeven,difmaxmin, Linha3, Linha4, Linha5, Linha6,Linha7,Linha8,Linha9: float;
barra,amp,Alvo1, StopOffSet,Alvo2,Alvo3,StopC:Float;
b: inteiro;
inicio
difmaxmin:= max-min;
Linha3 := (min+difmaxmin*20.20/100);
Linha4 := (min+difmaxmin*38.20/100);
Linha5 := (min+difmaxmin*50.00/100);
Linha6 := (min+difmaxmin*61.80/100);
Linha7 := (min+difmaxmin*80.00/100);
Linha8 := (min+difmaxmin*138.20/100);
Linha9 := (min+difmaxmin*161.80/100);
SetPlotColor(1,clRed);
SetPlotColor(2,clRed);
SetPlotStyle(3,psDashDot);
SetPlotWidth(3,2);
SetPlotColor(4,clBlue);
SetPlotColor(5,clBlue);
SetPlotColor(6,clBlue);
SetPlotStyle(7,psDashDot);
SetPlotWidth(7,2);
SetPlotColor(8,clBlue);
SetPlotColor(9,clBlue);
Plot(max);
Plot2(min);
Plot3(min+difmaxmin*20.20/100);
Plot4(min+difmaxmin*38.20/100);
Plot5(min+difmaxmin*50.00/100);
Plot6(min+difmaxmin*61.80/100);
Plot7(min+difmaxmin*80.00/100);
Plot8(min+difmaxmin*138.20/100);
Plot9(min+difmaxmin*161.80/100);
Se (GraphicInterval=date[1]) então noPlot(1);
Se (date<>date[1]) então NoPlot(1);
Se (date<>date[1]) então NoPlot(2);
Se (date<>date[1]) então NoPlot(3);
Se (date<>date[1]) então NoPlot(4);
Se (date<>date[1]) então NoPlot(5);
Se (date<>date[1]) então NoPlot(6);
Se (date<>date[1]) então NoPlot(7);
Se (date<>date[1]) então NoPlot(8);
Se (date<>date[1]) então NoPlot(9);
//fim; // se colocar não fica como estrat de execução
b:=BuyPosition;
//LoteTotal= LoteNivel61+LoteNivel50+LoteNivel38;
SinalC6:= (BuyPosition=0) e (minima>min) e (open<max)ou (BuyPosition=0) e (minima>min) e (low<max)
ou isbought e (minima>min) e (open<max)ou isbought e (minima>min) e (low<max);
Se SinalC6 então
inicio
PaintBar(clGreen);
Se (Time < HoraUltimaEntrada) entao
inicio
barra:=CurrentBar;
//se b>=0 então //se colocado dar limite exposição ativado e não faz entradas
StopC:=min-2;
// breakevenAtivado:= maxima>linha7;
barra:=CurrentBar;
Alvo1:=linha6;
barra:=CurrentBar;
Alvo2:=linha7;
barra:=CurrentBar;
Alvo3:=Linha8;
barra:=CurrentBar;
Se (b=0)ou(b<1) então
BuyLimit(Linha6,Loteparcial*lote);//LoteNivel61*lote);
barra:=CurrentBar;
Se (b=0)ou(b>=1) e (b<2) então
BuyLimit(Linha5,LoteParcial*lote);//LoteNivel50*lote);
barra:=CurrentBar;
Se (b=0)ou (b>=1) então
BuyLimit(Linha4,LoteParcial*lote);//LoteNivel38*lote);
barra:=CurrentBar;
Fim;
Fim;
{Buscar saída - No alvo/stop}
Se (IsBought) entao
inicio
barra:=CurrentBar;
Se b<=LoteTotal então SellToCoverLimit(Alvo3,LoteNivel61*lote);
barra:=CurrentBar;
b:=BuyPosition;
barra:=CurrentBar;
Se b >= (LoteTotal-LoteParcial) então SellToCoverLimit(Alvo2,LoteNivel50*lote);
barra:=CurrentBar;
b := BuyPosition;
barra:=CurrentBar;
Se b >= (LoteTotal-LoteParcial) então SellToCoverLimit(Alvo1,LoteNivel38*lote);
barra:=CurrentBar;
b:=BuyPosition;
SellToCoverstop(min-2,min-2,b*lote);
// Breakeven // não executando
fim;
{ b:=BuyPosition;
Se ((close - TraillingStopOffSet*MinPriceIncrement)>=StopC) e breakevenAtivado então
StopC:= Close - TraillingStopOffSet*MinPriceIncrement;
Se (Close >=(BuyPrice + BreakevenEmticks*MinPriceIncrement)) e (Not breakevenAtivado) então
inicio
StopC:= BuyPrice;
breakevenAtivado:= true;
fim;
StopOffSet:= StopC - StopOffSetEmTicks*MinPriceIncrement;
SellToCoverStop(StopC,StopOffSet);
Se Isbought então SellToCoverLimit(Alvo3,LoteNivel61*lote); }
{ Se (IsBought) então
inicio
amp:= max-BuyPrice;
Breakeven:= BuyPrice + (amp*1.38);
Se Close>max então
inicio
Se StopC <> BuyPrice então PaintBar(clAmarelo);
StopC:=Buyprice;
fim;
//SellToCoverLimit(amp*1.38);
// SellToCoverStop(StopC,StopC);
fim; }
{Fechar Posiçoes no Final do Dia}
Se (Time >= HoraFechamento) entao ClosePosition;
Fim;
Fim;
Postado por: @admin@leandro-master Evolui um pouco no seu código (evolui no sentido que alterei...rsrsrs...não que tenha ficado melhor...kkkk)
Olha aí, rodei para DOLFUT 18R e funcionou tranquilo....Pontos a se observar:
- Problema de encerramento de posição daytrade em gráficos de Renko. Isto é uma limitação do modelo de Backtesting. Pois as ações só são tomadas no encerramento do box. No caso do Renko, você pode ficar o dia inteiro em um mesmo box, dependendo do R. A Nelogica deveria desenvolver uma forma de encerrar a posição em box renko...não consigo ver uma forma de fazer isso via código da estratégia;
- Coloquei uma gestão de risco na forma de um stop fixo, mas recomendo você evoluir o código para um stop móvel (versão contínua) baseado no tamanho do box. Exemplo, crie um stop móvel 1 box atrás do fechamento atual. Assim, você deixa a sua estratégia mais próxima do mundo real.
- Tive que alterar a sua lógica de sinais de compra e venda para capturar melhor os PFR que mencionou. Coloquei que se a reversão ocorrer a uma distância de 2 boxes do preço mínimo do dia, então gera os sinais.
- Os alvos não estão fixos e estão conforme o PFR do movimento atual.
Enfim, como eu não vejo possibilidade de resolver via código a questão do encerramento de daytrade, eu sugiro exportar a planilha de trades e analisar no excel o resultado removendo os trades que foram carregados para dias seguintes.
Grande abs!
var bLocalizouBoxesGap : boolean; iDataUltimoBox, iUltimoBoxDiaAnterior, iBoxDeGAP: integer; bConfigurouGestaoRisco: boolean; fPrecoStop: float; iStopOffsetEmTicks: integer; begin // Código é aplicável apenas à gráficos do tipo Renko if GraphicInterval = itRenko then begin iStopOffsetEmTicks := GraphicOffset - 1; // Identificação de Box relacionados a GAP if Date <> iDataUltimoBox then begin iUltimoBoxDiaAnterior := CurrentBar - 1; iBoxDeGAP := CurrentBar; bLocalizouBoxesGap := false; end; iDataUltimoBox := Date; if Not bLocalizouBoxesGap then if BarDurationF = 0 then begin iBoxDeGAP := CurrentBar; //PaintBar(clRed); end else begin //Aqui foi identificado o primeiro box que não é de GAP bLocalizouBoxesGAP := true; end; //Aqui executa a estratégia em boxes que não são devido à //gap de abertura if bLocalizouBoxesGAP then begin If (Time <= 1600) and Not hasPosition then begin // Compra no PFR após box reverter o preço mínimo do dia If (Close[1] < Close[2]) and (Close > Close[1]) and ((Close[1] - LowD(0)) < 2*iStopOffsetEmTicks*MinPriceIncrement) then begin BuyAtMarket; bConfigurouGestaoRisco := false; end; // Venda no PFR após box reverter o preço máximo do dia If (Close[1] > Close[2]) and (Close < Close[1]) //and (High[1] = HighD(0)) then and ((HighD(0) - Close[1]) < 2*iStopOffsetEmTicks*MinPriceIncrement) then begin SellShortAtMarket; bConfigurouGestaoRisco := false; end; end; // Se estiver comprado, encerra posição no primeiro // box que fecha contra posição If isBought then begin if Not bConfigurouGestaoRisco then begin fPrecoStop := buyPosition - iStopOffsetEmTicks*MinPriceIncrement; bConfigurouGestaoRisco := true; end; SellToCoverStop(fPrecoStop, fPrecoStop - 3*iStopOffsetEmTicks*MinPriceIncrement); if isBought and (Close[1] > Close) then ClosePosition; end; // Se estiver vendido, encerra posição no primeiro // box que fecha contra posição If isSold then begin if Not bConfigurouGestaoRisco then begin fPrecoStop := sellPrice + iStopOffsetEmTicks*MinPriceIncrement; bConfigurouGestaoRisco := true; end; BuyToCoverStop(fPrecoStop, fPrecoStop + 3*iStopOffsetEmTicks*MinPriceIncrement); if isSold and (Close[1] < Close) then ClosePosition; end; //Se houver fechamento de box após este horário, a // estratégia conseguiria encerrar posição de daytrade If (Time >= 1645) then ClosePosition; if Not HasPosition and bConfigurouGestaoRisco then bConfigurouGestaoRisco := false; end; Plot(HighD(0)); Plot2(LowD(0)); SetPlotColor(1,clRed); SetPlotColor(2,clGreen); end // O Gráfico não é do tipo Renko! else if LastBarOnChart then PlotText("Aplicável apenas a Renko",clWhite,-1,10); end
Estou fazendo uma automação parte do meu codigo usei como esqueleto esse código entre outras coisas que peguei no forum, mas estou com dificuldade de alterar a parte do stop. Teria como eplicar como faço para usar 3 ou box contra como stop?