Confira os nossos eBooks, Snippets e Fóruns produzidos para cada plataforma!
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.