
Um backtesting adequado deve buscar simular situações práticas do mercado (slippage, custo de operação, etc...)
Olá pessoal,
Tentei fazer uma variável de saída de trade quando uma média curta cruza uma média mais longa. No backtesting algumas vezes dá certo e outras vezes a saída não acontece no local determinado e acontece mais adiante sem qualquer ligação com o cruzamento das médias.
A definição da variável: vSaidaC := ((vMedFiltro[1] > vMedC[1]) and (vMedFiltro < vMedC))
Nesse caso é o cruzamento de cima para baixo. Será que é problema de programação ou de desempenho da plataforma. Também acontece na automação em conta de simulação.
Muito obrigado,
Olá @rugor!
Bom, é difícil de responder sem ver o código.
É certo que o Profit está sempre com um bug novo...mas temos que eliminar primeiro a chance do erro ser no código.
Se puder, poste o código aqui, mesmo que simplificado que já ajuda a depurar o erro.
Abs!
Postado por: @rugorA definição da variável: vSaidaC := ((vMedFiltro[1] > vMedC[1]) and (vMedFiltro < vMedC))
Está tudo certo com essa saída.
Já reparei também que o BT puxa datas do ativo que nem estão mais em vigência naquele período e aí os resultados não batem.
Na minha opinião a melhor maneira de ver uma estratégia em execução é rodando replay msm.
Postado por: @adminÉ certo que o Profit está sempre com um bug novo...
🤣
Coloco o código para verificação de erros:
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // // NOME DA ESTRATÉGIA: SAIDA NO CRUZAMENTO DE MÉDIAS // input iMediaL(160); iMediaC(70); iMediaF(6); iHoraTermino(1700); var /// Variáveis do programa de exclusão dos renkos vazios /// bLocalizouBoxesGap : boolean; iDataUltimoBox,iUltimoBoxDiaAnterior,iBoxDeGAP : integer; /// Variáveis de entrada e saída /// vCompra,vVenda,vSaidaC,vSaidaV : Boolean; /// Variáveis das médias /// vMedL : float; vMedC : float; vDistMed : float; vMedFiltro : float; begin // Código da exclusão de renkos // // 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 //INÍCIO DA ESTRATÉGIA SAIDA NO CRUZAMENTO MEDIAS// // DEFINIÇÃO DAS MÉDIAS// vMedL := HullMOvingAverage(iMediaL); vMedC := HullMovingAverage(iMediaC); vMedFiltro := Media(iMediaF,close); vDistMed := vMedC - vMedL; //PLOTAGEM DAS MÉDIAS// Plot(vMedL); Plot2(vMedC); Plot3(vMedFiltro); ///// DEFINIÇÃO DE ENTRADAS///// begin ///// COMPRA CANDLE DE ALTA /// vCompra := (close > open) and (time < iHoraTermino); ///// VENDA CANDLE DE BAIXA /// vVenda := (close < open) and (time < iHoraTermino); ///// DEFINIÇÃO DE SAÍDAS ///// MÉDIA FILTRO CRUZANDO MEDIA CURTA EM QUALQUER SENTIDO //// vSaidaC := (((vMedFiltro[1] > vMedC[1]) and (vMedFiltro < vMedC)) or ((vMedFiltro[1] < vMedC[1]) and (vMedFiltro > vMedC))) and (time < iHoraTermino); vSaidaV := (((vMedFiltro[1] > vMedC[1]) and (vMedFiltro < vMedC)) or ((vMedFiltro[1] < vMedC[1]) and (vMedFiltro > vMedC))) and (time < iHoraTermino); ///// ENTRADAS///// if vCompra and (buyposition = 0) then buyatmarket; if vVenda and (sellposition = 0) then sellshortatmarket; ///// SAIDAS///// if (buyposition = 1) and vSaidaC then sellshortatmarket; if (sellposition = 1) and vSaidaV then buyatmarket; if (buyposition = 1) and (time > iHoraTermino) then closeposition; if (sellposition = 1) and (time > iHoraTermino) then closeposition; PaintBar(clGreen); end; end; // O Gráfico não é do tipo Renko! // end; end;
Oi @rugor!
Reforço o ponto do @masker. É estranho os vSaidaC e vSaidaV serem exatamente as mesmas condições. É isso mesmo que quer?
Outro ponto que gostaria de indicar é o trecho de código em que você realiza as ENTRADAS. Da forma como você escreveu, esse trecho de código também faz saídas.
Pense comigo: nada impede que vCompra seja verdadeiro e você esteja, na verdade, vendido naquele momento. Nesse caso, sua regra de entrada encerra a posição porque gera uma compra a mercado. O mesmo ocorre para a entrada na venda. Minha sugestão seria começar trocando esse trecho por:
///// ENTRADAS///// if vCompra and not hasPosition then buyatmarket; if vVenda and not hasPosition then sellshortatmarket;
Roda aí e veja se já resolve o problema que está presenciando.
Caso persista, envia novamente o código atualizado e indique um exemplo específico: ativo, tempo gráfico, data e hora, o que deveria ocorrer e o que ocorreu de errado. Assim, fica mais fácil ajudar a depurar o código.
Abs!
@admin, fiz a mudança sugerida e de fato o que acontecia era uma entrada de Venda se comportar como saída de uma anterior compra não identificada. A substituição para 'not hasPosition' resolveu o problema. Valeu! Muito obrigado!
@masker , obrigado por sua ajuda. Nesse caso eu queria a saída em qualquer sentido do cruzamento de uma média com outra. O John resolveu o meu problema: uma ordem de entrada em sentido contrário ao que estava acabava sendo a saída inesperada do trade.