Cada bug que só por Deus

 
Estou criando um robô para operar com vários ativos simultaneamente sendo inicializado no gráfico IBOV para operar com ações da B3, e uma maneira que estou utilizando para identificar se o mercado já abriu pro ativo naquele dia, é verificando se já tem uma candle diário com a data do dia no mesmo. Porém ao fazer isso, eu não consigo iniciar uma negociação, pois o Meta Trader é interrompido logo em seguida sem apresentar erros, porém se comentar a linha 31 (linha da verificação do candle diário) e descomentar a 30 (linha com true no if), eu consigo realizar a negociação normalmente, mas sem verificar a abertura do mercado no ativo.

Caso seja comentada a linha 36 (linha de envio de ordem) com a 31 (linha de verificação do candle diário) descomentada e a 30 (linha com true no if) comentada, consigo verificar a abertura do mercado naquele ativo e o Meta Trader continua rodando normalmente.

Uma maneira bizarra que encontrei para resolver o problema, foi adicionando uma média móvel. 

Caso eu descomente a linha 15 (linha da média móvel), o script funciona sem erros, verificando o candle diário e realizando a negociação.

Surreal!

Estou fazendo backtest com o a data 02-01-2024 no gráfico IBOV. Coloque como ativo de teste CMIG4

#include <Trade.mqh>

CTrde trade;

MqlRates candles[];

string actual_symbol = "CMIG4";

bool set_timer;
bool order_sent;

int OnInit()
  {
   SymbolSelect("CMIG4",true);   
   //int ma = iMA("CMIG4",PERIOD_D1,1,0,MODE_SMA,PRICE_OPEN);
   return(INIT_SUCCEEDED);
  }

void OnTick()
  {
   if(!set_timer)
     {
      EventSetMillisecondTimer(1);   
      set_timer = true;
     }
  }

void OnTimer()
  {
   //if(true)
   if(TimeToString(SeriesInfoInteger("CMIG4",PERIOD_D1,SERIES_LASTBAR_DATE),TIME_DATE) == TimeToString(TimeLocal(),TIME_DATE))
     {
      if(!order_sent)
        {         
         CopyRates("CMIG4",PERIOD_D1,0,1,candles);
         trade.SellLimit(100, "CMIG4", candles[0].open);
         order_sent = true;
        }
     }
  }
  
void OnDeinit(const int reason)
  {   
   EventKillTimer();
   //IndicatorRelease(ma);
  }


Sem a média móvel (encerrado imediatamente ás 10h03 após ser lançada a ordem):

Sem a média móvel


Com a média móvel (encerrado normalmente às 23h59):

Com a média móvel

 

Algumas observações:

1. Por favor, verifique o retorno de SymbolSelect(), porque o que a iMA() está fazendo (incluindo o ativo na janela Observação do Mercado), deveria está sendo feito por SymbolSelect():

   if(!SymbolSelect(actual_symbol, true))
     {
      Print(__FUNCTION__, " - Error SymbolSelect().");
      return(INIT_FAILED);
     }

2. Transfira o comando abaixo de OnTick() para OnInit() mesmo, verificando o seu retorno:

   if(!EventSetMillisecondTimer(1))
     {
      Print(__FUNCTION__, " - Error EventSetMillisecondTimer().");
      return(INIT_FAILED);
     }

3. Os parâmetros do comando SellLimit() estão invertidos... Corrigir:

trade.SellLimit(100, "CMIG4", candles[0].open);

... Para:

trade.SellLimit(100, candles[0].open, actual_symbol);
 
Vinicius Pereira De Oliveira #:

Algumas observações:

1. Por favor, verifique o retorno de SymbolSelect(), porque o que a iMA() está fazendo (incluindo o ativo na janela Observação do Mercado), deveria está sendo feito por SymbolSelect():

2. Transfira o comando abaixo de OnTick() para OnInit() mesmo, verificando o seu retorno:

3. Os parâmetros do comando SellLimit() estão invertidos... Corrigir:

... Para:

Tem programador que Só Por Deus não?

Programar um EA é mega-difícil, ao contrário do que as pessoas possam achar.

Você tem máquina para disparar um evento a cada 1 milissegundo?

Você está checando o retorno da função SymbolSelect()?

Você sequer está checando o retorno do CopyRates()!   E se falhar? Você já sai vendendo??? 

Você está chamando de Bugs aquilo que você sequer conhece da linguagem... Cuidado...

Hoje tenho um EA pessoal meu que tem mais de 5.000 linhas de código para tratar de cada condição adversa do mercado e me dar a segurança, que quando der m*rda, ele saia da operação da melhor maneira possível... Não quero te desencorajar, mas de novo, NÃO é trivial, longe disso...

De novo, cuidado!

;)

 
Flavio Javier Jarabeck #:

Tem programador que Só Por Deus não?

Programar um EA é mega-difícil, ao contrário do que as pessoas possam achar.

Você tem máquina para disparar um evento a cada 1 milissegundo?

Você está checando o retorno da função SymbolSelect()?

Você sequer está checando o retorno do CopyRates()!   E se falhar? Você já sai vendendo??? 

Você está chamando de Bugs aquilo que você sequer conhece da linguagem... Cuidado...

Hoje tenho um EA pessoal meu que tem mais de 5.000 linhas de código para tratar de cada condição adversa do mercado e me dar a segurança, que quando der m*rda, ele saia da operação da melhor maneira possível... Não quero te desencorajar, mas de novo, NÃO é trivial, longe disso...

De novo, cuidado!

;)

Esse não é o script do meu EA, é um script de exemplo do erro apenas. Estou checando o retorno do SymbolSelect() no robô. Obrigado pelas palavras

 
Vinicius Pereira De Oliveira #:
Os parâmetros do comando SellLimit() estão invertidos

Esse não é o script do meu EA, é um script de exemplo do erro apenas, estou checando o retorno do SymbolSelect() no robô. O EventSetMillisecondTimer está no OnTick() para acelerar o backtest. O parâmetros estão invertidos no SellLimit() porque eu mexi no arquivo Trade.mqh e alterei a ordem dos mesmos