Neo traderBot

Neo traderBot

Você sabia?

Um backtesting adequado deve buscar simular situações práticas do mercado (slippage, custo de operação, etc...)

leaf leftleaf right
Notifications
Clear all

[Solucionado] Como armazenar o valor da Minima (Maxima) para a ordem?

9 Posts
3 Usuários
4 Reactions
326 Visualizações
MAHALO
(@mahalo)
Membro ativo
Registrou: 2 anos atrás
Posts: 7
Iniciador do tópico  

Olá.
Agradeço se alguém puder me ajudar no código abaixo...
Quando o candle atende as duas condições para operação, eu quero memorizar a máxima ou a mínima do 1º candle que atendeu as condições para posicionar a ordem de entrada e manter a ordem até ser acionada ou até que novo candle atenda condições contrárias.
Mas a ordem está acompanhando a mudança do candle.

Input
StopLoss(161.8);      //161,8% DO TAMANHO DO CANDLE DE GATILHO
StopGain(161.8);      //161,8% DO TAMANHO DO CANDLE DE GATILHO

HorarioInicial(0905);    
HorarioFinal(1700);
HorEncerrDia(1740);

Var
TamCandle : Real;
BBS, BBI, aEst : Real;
PosC, PosV, PosGain, PosStop : Real;

Inicio

BBS := BollingerBands(1.0, 20, 0)|0|;
plot(bbs);
PLOT2(BBI);
BBI := BollingerBands(1.0, 20, 0)|1|;

aEst := SlowStochastic(150);              //tirei outros parametros  , 3,0);

If time >= HorEncerrDia then ClosePosition;         //encerramento do dia
  
if (time >= horariofinal) or (time <= HorarioInicial) then     //FORA DO HORARIO OPERACIONAL 
       
    begin
        PaintBar(ClAMARELO);
        ClosePosition;                //encerra posiçoes fora do horario
    end
else

if (time < horariofinal) or (time > HorarioInicial) then     //HORARIO OPERACIONAL 

    begin //Abre horario operacional

        //LOGICA OPERACIONAL

// BUSCA ENTRADAS
   if (BuyPosition = 0) e (SellPosition = 0) entao    //Verifica se não existe posição

   //Condição da compra
Inicio   
   inicio
    Se (aEst > 80) and
    (fechamento < BBI) entao          

    PosC := Maxima;                  
      Inicio

    TamCandle := maxima[1] - minima[1];
    PosGain := TamCandle * StopGain;
    PosStop := TamCandle * StopLoss;

    BuyStop(PosC, PosC);
    SellToCoverStop((buyprice - PosStop), (buyprice - PosStop));   //Stop
    SellToCoverLimit(buyprice + PosGain);                          //gain
      fim;
   fim;

   //Condição da venda
   inicio
    Se (aEst < 20) and
    (fechamento > BBS) entao          

PosV := Minima;                        
      Inicio
//    PosV := Minima;
    TamCandle := maxima[1] - minima[1];
    PosGain := TamCandle * StopGain;
    PosStop := TamCandle * StopLoss;

    SellShortStop(PosV, PosV);
    BuyToCoverStop((sellprice + PosStop), (sellprice + PosStop));      //Stop
    BuyToCoverLimit(sellprice - PosGain);                              //gain
      fim;
    

   fim;    
Fim;

 //BUSCA SAIDAS
Inicio
   Se (IsBought) entao
   Inicio
 
    SellToCoverStop((buyprice - PosStop), (buyprice - PosStop));   //Stop
    SellToCoverLimit(buyprice + PosGain);                          //gain     
   
   Fim;
     
   Se (IsSold) entao
   Inicio
    
    BuyToCoverStop((sellprice + PosStop), (sellprice + PosStop));      //Stop
    BuyToCoverLimit(sellprice - PosGain);                              //gain   
  
   Fim;
Fim;   
                          
  Fim;

Fim; 

   
Citar
(@paulo-ferreira)
Membro ativo
Registrou: 2 anos atrás
Posts: 5
 

Eu tambem tenho esse problema, que é armazenar o Candle Sinal para que ele controle os Take e Stop.   sempre que faço robos com essa logica, ele acaba ajustando os alvos e stops a cada novo candle.     Outra dificuldade, que tenho, para fazer um grid de preço médio, é "armazenar o preço da primeira entrada".        Nao vou conseguir te ajudar, mas qdo vc tiver essa resposta, por favor compartilhe pq preciso dela rsrsrsr 

 

Porem, ao avaliar teu codigo eu vi uma logica operacional super interessante mas que não estava rodando de forma capaz de extrair melhores resultados.   Entao, tomei liberdade de ajustar alguns parametros: 

StopLoss(1.618); //161,8% DO TAMANHO DO CANDLE DE GATILHO
StopGain(1.618); //161,8% DO TAMANHO DO CANDLE DE GATILHO
//++++++++++++ estava 168, alterei para 1.618

HorarioInicial(0905);
HorarioFinal(1700);
HorEncerrDia(1740);

Var
TamCandle : Real;
BBS, BBI, aEst : Real;
PosC, PosV, PosGain, PosStop : Real;

Inicio

BBS := BollingerBands(2.0, 20, 0)|0|;
plot(bbs);
PLOT2(BBI);
BBI := BollingerBands(2.0, 20, 0)|1|;
//++++++++++++ favor testar no grafico de 15min, usando banda desvio 2; periodo 60... fica top)

aEst := SlowStochastic(60); //tirei outros parametros , 3,0);
//++++++ no grafico de 5 min, vc pode testar com SlowStochastic 60 ... metralhadora animal e
//++++++ e vai rodar bem tanto com BB desvio 1.0 e desvio 2.0
//++++++ 5 min: bb 1.0, 20; estocastico 150
//++++++ 5 min: bb 2.0, 20; estocastico 60

If time >= HorEncerrDia then ClosePosition; //encerramento do dia

if (time >= horariofinal) or (time <= HorarioInicial) then //FORA DO HORARIO OPERACIONAL

begin
PaintBar(ClAMARELO);
ClosePosition; //encerra posiçoes fora do horario
end
else

if (time < horariofinal) or (time > HorarioInicial) then //HORARIO OPERACIONAL

begin //Abre horario operacional

//LOGICA OPERACIONAL

// BUSCA ENTRADAS
if (BuyPosition = 0) e (SellPosition = 0) entao //Verifica se não existe posição

//Condição da compra
Inicio
inicio
Se (aEst > 80) and (fechamento < BBI) entao

PosC := Maxima;
Inicio

TamCandle := maxima[1] - minima[1];
PosGain := TamCandle * StopGain;
PosStop := TamCandle * StopLoss;
BuyStop(PosC, PosC);
SellToCoverStop((buyprice - PosStop), (buyprice - PosStop)); //Stop
SellToCoverLimit(buyprice + PosGain); //gain
fim;
fim;

//Condição da venda
inicio
Se (aEst < 20) and
(fechamento > BBS) entao

PosV := Minima;
Inicio
// PosV := Minima;
TamCandle := maxima[1] - minima[1];
PosGain := TamCandle * StopGain;
PosStop := TamCandle * StopLoss;

SellShortStop(PosV, PosV);
BuyToCoverStop((sellprice + PosStop), (sellprice + PosStop)); //Stop
BuyToCoverLimit(sellprice - PosGain); //gain
fim;

fim;
Fim;

//BUSCA SAIDAS
Inicio
Se (IsBought) entao
Inicio

SellToCoverStop((buyprice - PosStop), (buyprice - PosStop)); //Stop
SellToCoverLimit(buyprice + PosGain); //gain

Fim;

Se (IsSold) entao
Inicio

BuyToCoverStop((sellprice + PosStop), (sellprice + PosStop)); //Stop
BuyToCoverLimit(sellprice - PosGain); //gain

Fim;
Fim;

Fim;

Fim;


   
MAHALO reacted
ReplyCitar
Credson
(@m4tr1xbr)
Membro Moderator
Registrou: 2 anos atrás
Posts: 45
 

Cria uma variável booleana que será verdadeira apenas quando a condição de compra ou venda acontecer, você irá armazenar os valor de max e min em um bloco separado da entrada.

Exemplo: 

var
  bSinalC:Booleano; //Sinal de Entrada 
  bGuardarValor : Booleano; //Variável que será acionada apenas quando o sinal ocorrer
  Stop, Alvo : Real;

Begin
  {Buscar Sinal}
   bSinalC := (Maxima[1] > Maxima[0]) e (Minima[1] < Minima[0]);
   If  bSinalC thne PaintBar(clVerde);

  {Buscar Entrada}
  If Not(IsBought) and ( bSinalC) then      
    begin             
      BuyAtMarket;
      bGuardarValor := verdadeiro; //Aqui aconteceu a condição então a variável é setada como verdadeiro.
    end;

  {bGuardarValor Valores de Saída} //É aqui que você pega e armazena o valor de max e min. 
  If (IsBought) and (bGuardarValor) then
    begin
      Stop := Minima - (TicksStop * MinPriceIncrement);      
      Alvo := Maxima + GanhoPontos;
      bGuardarValor := falso; //Muda a variável para falso e somente quando a condição se repetir novamente ela voltará a ser verdadeira.  
    end;

  {Buscar Saída}
  SellToCoverLimit(Alvo);
  SellToCoverStop(Stop,Stop-OffsetStop); 

End;

 


   
MAHALO reacted
ReplyCitar
MAHALO
(@mahalo)
Membro ativo
Registrou: 2 anos atrás
Posts: 7
Iniciador do tópico  

@m4tr1xbr obrigado.

Vou tentar usar essa lógica.


   
ReplyCitar
(@paulo-ferreira)
Membro ativo
Registrou: 2 anos atrás
Posts: 5
 

Ainda sem (Travar o candle sinal de entrada, deixando que o take e stop variem candle a candle) eu fiz esses ajustes no seu setup...    (no corpo, tem os resultados de BT)

Input
StopLoss(2); //161,8% DO TAMANHO DO CANDLE DE GATILHO
StopGain(4); //161,8% DO TAMANHO DO CANDLE DE GATILHO
HorarioInicio(0900); //====== HORÁRIO DE INICIO PARA O ENVIO DE ORDENS ======
HorarioFim(1630); //====== HORÁRIO FINAL PARA O ENVIO DE ORDENS E INICIO DO CANCELAMENTO DE ORDENS PENDENTES CASO AINDA NÃO ESTEJA POSICIONADO ======
HorarioFecharPosicoes(1700); //====== HORÁRIO ONDE DEVE SER REALIZADO O FECHAMENTO DAS POSIÇÕES ABERTAS ======

Var
TamCandle : Real;
BBS, BBI, aEst : Real;
PosC, PosV, PosGain, PosStop : Real;
HorarioNegociacao, HorarioZeragem : booleano;
BarraPosicionado, BarraNaoPosicionado : inteiro;

Inicio

BBs := BollingerBands(2, 20, 0)|0|;
BBi := BollingerBands (2, 20, 0)|1|;
//Plot(BBs);
//Plot2(BBi);
aEst := SlowStochastic(60);
Plot3(aEst);
TamCandle := maxima[1] - minima[1];
PosGain := TamCandle * StopGain;
PosStop := TamCandle * StopLoss;

//====== VERIFICA O HORÁRIO DE NEGOCIAÇÃO ======
Se (Time >= HorarioInicio) e (Time <= HorarioFim) então
HorarioNegociacao := verdadeiro
Senao
HorarioNegociacao := falso;

//====== VERIFICA O HORARIO DE ZERAGEM ======
Se (Time >= HorarioFecharPosicoes) então
HorarioZeragem := verdadeiro
Senao
HorarioZeragem := falso;

//====== VERIFICA SE ESTÁ COMPRADO ======
Se IsBought e (CurrentBar <> BarraNaoPosicionado) entao
Inicio
SellToCoverStop((buyprice - PosStop), (buyprice - PosStop));
SellToCoverLimit(buyprice + PosGain);
Fim
Senao
Inicio
//====== VERIFICA SE ESTÁ VENDIDO =====
Se IsSold e (CurrentBar <> BarraNaoPosicionado) entao
Inicio
BuyToCoverStop((sellprice + PosStop), (sellprice + PosStop)); //Stop
BuyToCoverLimit(sellprice - PosGain);
Fim
Senao
Inicio
//====== VERIFICA SE O HORARIO ATUAL PERMITE NOVAS ENTRADAS ======
Se HorarioNegociacao e (CurrentBar <> BarraPosicionado) entao
Inicio
//====== ENTRADAS COMPRAS =====
// --- testes Indice 5Min, com 1 slippage e 0,50 de custo por contrato (5 min)
// --- se eliminar a BB e usar Est40 = 1986trades(Lucro 74.4 / Fator 1,26 / DD tf9.8-tt4.8 / LR 1,18
// --- com uso de BB, melhor deixar Estoc em 020 / 080 = 755trades(lucro 27,2 / Fator 1,24 / DD tf28.8-tt17.1 / LR 1,07

// --- testes Indice 15Min, com 1 slippage e 0,50 de custo por contrato
// --- se eliminar a BB e usar Est40 = 983trades(Lucro 65.1 / Fator 1,27 / DD tf21-tt8 / LR 1,29
// --- ** com uso de BB, melhor deixar Estoc em 020 / 080 = 325trades (lucro 34,6 / Fator 1,39 / DD tf15-tt8.9 / LR 1,33
// --- com uso de BB, melhor deixar Estoc em 020 / 080 = 309trades (lucro 30,6 / Fator 1,30 / DD tf22-tt21.9 / LR 1,76
// --- ** MELHOR OPÇÃO M15 com BB

Se (aEst < 80)
e (fechamento < BBI)
entao BuyStop(Maxima,Maxima)
Senao
//====== ENTRADAS VENDAS =====
Se (aEst > 20)
e (fechamento > BBS)
entao SellShortStop(Maxima,Maxima);
BarraNaoPosicionado := CurrentBar;
Fim
Senao
//====== CANCELA AS ORDENS PENDENTES CASO NÃO ESTEJA COMPRADO E NÃO ESTEJA EM HORÁRIO DE NEGOCIAÇÃO ======
CancelPendingOrders;
Fim;
Fim;
Fim;


   
MAHALO reacted
ReplyCitar
MAHALO
(@mahalo)
Membro ativo
Registrou: 2 anos atrás
Posts: 7
Iniciador do tópico  

@m4tr1xbr , você poderia dar um exemplo de como armazenar o valor da entrada?

Por exemplo, se a condição de entrada for 2 ticks acima da máxima de um determinado candle, eu queria que a ordem ficasse aguardando ser acionada naquele valor esperando o pullback, e não ir mudando de candle em candle.


   
ReplyCitar
MAHALO
(@mahalo)
Membro ativo
Registrou: 2 anos atrás
Posts: 7
Iniciador do tópico  

@paulo-ferreira , obrigado pela ajuda.    Vou testar.


   
ReplyCitar
Credson
(@m4tr1xbr)
Membro Moderator
Registrou: 2 anos atrás
Posts: 45
 

@MAHALO, vou postar um exemplo para você, nesse caso o sinal de entrada é uma Inside Bar, para efeitos didáticos coloquei o nome da variável (Sinal de Compra) como bInsideBar, então sempre que houver um inside bar iremos tentar fazer uma compra na máxima da barra sinal. Nesse caso eu define que se não houver a compra na barra seguinte irei aceitar uma compra até duas barras depois do sinal ocorrer, você também poderia usar o tempo, por exemplo até 5min após o sinal ocorrer, nesse caso é só usar a função Time, lugar de CurrentBar.

Em resumo iremos fazer o seguinte:

  • Definição das constantes e variáveis: No início do código, são definidas algumas constantes e variáveis que serão usadas ao longo do script. As constantes definem a quantidade de ticks para o stop loss, o offset para o stop loss e a quantidade de ticks para o take profit. As variáveis armazenam o sinal de entrada, se devemos guardar o valor de entrada ou não, os preços de stop e alvo, o preço de entrada, a barra atual, o número de barras desde o sinal de entrada e se podemos comprar ou não.

  • Buscar Sinal: Nesta seção, o script verifica se a barra atual é uma inside bar. Se for, ele pinta a barra de verde.

  • Buscar Entrada: Se não houver uma posição aberta e a barra atual for uma inside bar, o script define o preço de entrada como a alta da barra atual, ativa a possibilidade de compra, atualiza a barra atual e coloca uma ordem de compra stop no preço de entrada.

  • Executar Compra: Se a barra atual não for a barra onde o sinal de entrada ocorreu e a possibilidade de compra estiver ativa, o script atualiza o número de barras desde o sinal de entrada. Se ainda não houver uma posição aberta, ele coloca uma ordem de compra stop no preço de entrada. Se houver uma posição aberta ou se passaram duas barras desde o sinal de entrada, ele desativa a possibilidade de compra e reseta a barra onde o sinal ocorreu.

  • Definir Valores de Saída: Se a variável para guardar o valor for verdadeira, o script define o stop como a baixa da barra atual menos o TickStop e o alvo como a alta da barra atual mais o take profit em ticks. Em seguida, ele reseta a variável guardar valor.

  • Buscar Saída: Se houver uma posição aberta, o script coloca uma ordem de venda limitada no alvo e uma ordem de venda stop no stop, com offset. Depois, reseta a variável podeComprar.

// CONSTS =========================================================================================
const
  cTickStop=1;     // Define a quantidade de ticks para o stop loss
  cOffsetStop =2;  // Define o offset para o stop loss
  cTakeProfit=15;   // Define a quantidade de ticks para o take profit (Alvo)

// INPUTS =========================================================================================


// VARIÁVEIS ========================================================================================

var
  bInsideBar    :Boolean; // Sinal de entrada 
  bGuardarValor :Boolean; // Variável que será acionada apenas quando o sinal de entrada ocorrer
  fStop, fAlvo  :float;   // Valores de stop e alvo
  fPrecoEntrada :float;   // Preço de entrada
  iCurrentBar   :integer; // Recebe o valor da barra atual
  iNbarras      :integer; // Número de barras desde o sinal de entrada
  bPodeComprar  :boolean; // Autoriza a compra se a compra não for feita no sinal de entrada ocorrer

Begin
  {Buscar Sinal}
  // Se a barra atual é uma inside bar (máxima e mínima dentro da barra anterior), pintar a barra de verde
  bInsideBar := (Maxima[1] > Maxima[0]) e (Minima[1] < Minima[0]);
  If  bInsideBar then PaintBar(clVerde);

  {Buscar Entrada}
  // Se não houver uma posição aberta e ocorrer um sinal de entrada
  If Not(IsBought) and ( bInsideBar) then      
    begin
      fPrecoEntrada := High;  // Definir o preço de entrada como a máxima da barra atual
      bGuardarValor := true;  // Definir a variável para guardar valor como verdadeira
      bPodeComprar:=true;     // Ativar a possibilidade de comprar
      iCurrentBar:=CurrentBar; // Atualizar a barra atual
      BuyStop(fPrecoEntrada);  // Colocar uma ordem de compra stop no preço de entrada       
    end;

  // Se a barra atual não for a barra em que o sinal ocorreu e a possibilidade de compra estiver ativa
  if (iCurrentBar <> CurrentBar) and bPodeComprar then
    begin
      // Atualizar o número de barras desde o sinal de entrada
      iNbarras:=CurrentBar - iCurrentBar;
      // Se ainda não houver uma posição aberta, colocar uma ordem de compra stop no preço de entrada
      if Not(IsBought) then
        BuyStop(fPrecoEntrada);
      // Se houver uma posição aberta ou se passaram duas barras desde o sinal de entrada
      if (IsBought) or (iNbarras >=2) then 
        begin
          // Desativar a possibilidade de compra
          bPodeComprar:=false;
          // Resetar a barra em que o sinal ocorreu
          iCurrentBar:=-1;
        end;
    end;

  {bGuardarValor Valores de Saída}
  // Se a variável para guardar valor for verdadeira irá fixar os valores para não atualizarem barra a barra
  If (bGuardarValor) then
    begin
      // Definir o stop como a mínima da barra atual menos o TickStop
      fStop := Low  - (cTickStop * MinPriceIncrement);      
      // Definir o alvo como a máxima da barra atual mais o take profit em ticks
      fAlvo := High + (cTakeProfit * MinPriceIncrement);
      // Resetar a variável guardar valor
      bGuardarValor := falso; 
    end;

  {Buscar Saída}
  
  If (IsBought) then
    begin
      // Colocar uma ordem de venda limitada no alvo
      SellToCoverLimit(fAlvo);
      // Colocar uma ordem de venda stop no stop, com offset
      SellToCoverStop(fStop, fStop - cOffsetStop);
      //É preciso resetar a variável PodeComrar sempre que houver um fechamento de posição para evitar erros nos backtesting
      bPodeComprar:=false;
    end;

  
   

End; 

   
MAHALO reacted
ReplyCitar
MAHALO
(@mahalo)
Membro ativo
Registrou: 2 anos atrás
Posts: 7
Iniciador do tópico  

@m4tr1xbr , agradeço muito a ajuda.
Vou estudar o código e sua explicação com cuidado e tentar substituir a condição de entrada pela minha.

👍


   
ReplyCitar