Função de um EA deixa de funcionar com a introdução de um segundo EA.

 

Caros srs.,


No que será que estou pecando na função abaixo? Com um EA é tudo ok, mas rodando com dois EA's (mesma conta/ativos diferentes/mesma nuvem) a função deixa de funcionar. Não há mensagens de erros nos logs, tudo ok. O magic number foi setado no OnInit como .SetExpertMagicNumber(); da classe CTrade, e a função é chamada em OnTick. Contextualizando, é uma função que restringe o EA em 2 operações por dia. Primeiramente achei que o motivo da falha fosse que estando dois EA's operando ao mesmo tempo, na mesma conta, poderia ser que estivem compartilhando o histórico de ordens, desconsiderando os respectivos magic numbers. Porém, se assim fosse, ambos EA's já tendo realizado uma única operação cada, então logicamente na sequência os dois estariam impedidos de abrir novas posições, visto que no histórico total já seria possível auferir a existência de 2 operações concluídas no dia (uma de cada robô). Mas não é o que está acontecendo. Os EA's que antes, operando sozinhos, ficavam restritos a 2 operações, agora operam 3 ou 4 vezes, dependendo do dia. Não sou programador, sou um entusiasta, aprendiz e fã de mql5(C++). Se alguém puder me apontar o caminho do erro desde já sou muito grato.


int TradingCounter()
  {
   int tradingsTotal = 0;
   if(HistorySelect(StringToTime(TimeToString(TimeTradeServer(), TIME_DATE)), INT_MAX))
      for(int i = HistoryOrdersTotal() - 1; i >= 0; i--)
        {
         const ulong orderTicket = HistoryOrderGetTicket(i);
         if(HistoryOrderGetString(orderTicket,ORDER_SYMBOL)==ativoFinanc &&
            HistoryOrderGetInteger(orderTicket,ORDER_MAGIC)==EA_magic)
           {
            tradingsTotal = tradingsTotal + 1;
           }
        }
   return(tradingsTotal<=2);
  }
 
Daniel D.:

Caros srs.,


No que será que estou pecando na função abaixo? Com um EA é tudo ok, mas rodando com dois EA's (mesma conta/ativos diferentes/mesma nuvem) a função deixa de funcionar. Não há mensagens de erros nos logs, tudo ok. O magic number foi setado no OnInit como .SetExpertMagicNumber(); da classe CTrade, e a função é chamada em OnTick. Contextualizando, é uma função que restringe o EA em 2 operações por dia. Primeiramente achei que o motivo da falha fosse que estando dois EA's operando ao mesmo tempo, na mesma conta, poderia ser que estivem compartilhando o histórico de ordens, desconsiderando os respectivos magic numbers. Porém, se assim fosse, ambos EA's já tendo realizado uma única operação cada, então logicamente na sequência os dois estariam impedidos de abrir novas posições, visto que no histórico total já seria possível auferir a existência de 2 operações concluídas no dia (uma de cada robô). Mas não é o que está acontecendo. Os EA's que antes, operando sozinhos, ficavam restritos a 2 operações, agora operam 3 ou 4 vezes, dependendo do dia. Não sou programador, sou um entusiasta, aprendiz e fã de mql5(C++). Se alguém puder me apontar o caminho do erro desde já sou muito grato.


por quê você está usando
TimeTradeServer()
?
 
Flavio Jarabeck:
por quê você está usando ?

Caro Flavio, boa noite.

Pensando na tua pergunta, realmente o mais apropriado seria iniciar a leitura do histórico pelo horário de abertura da barra diária e não pelo início do dia, até mesmo pq o TimeTradeServer traz o horário do computador, com uma diferença de 5 horas do que é registrado no histórico. Se eu estiver falando m# pode me corrigir. Realizada abaixo a correção.


int TradingCounter()
  {
   int tradingsTotal = 0;
   datetime fromDate = iTime(financAsset,PERIOD_D1,0);
   datetime toDate   = TimeCurrent();
   if(HistorySelect(fromDate,toDate))
     {
      for(int i = HistoryOrdersTotal() - 1; i >= 0; i--)
        {
         const ulong orderTicket = HistoryOrderGetTicket(i);
         if(HistoryOrderGetString(orderTicket,ORDER_SYMBOL)==financAsset &&
            HistoryOrderGetInteger(orderTicket,ORDER_MAGIC)==EA_magic)
           {
            tradingsTotal = tradingsTotal + 1;
           }
        }
     }
   return(tradingsTotal<=2);
  }
 
Daniel D.:

Caro Flavio, boa noite.

Pensando na tua pergunta, realmente o mais apropriado seria iniciar a leitura do histórico pelo horário de abertura da barra diária e não pelo início do dia, até mesmo pq o TimeTradeServer traz o horário do computador, com uma diferença de 5 horas do que é registrado no histórico. Se eu estiver falando m# pode me corrigir. Realizada abaixo a correção.


TimeTradeServer eh o horario atual do servidor, enquanto o TimeCurrent eh o horario da ultima cotacao presente no observador de mercado. Olhe a ultima linha do seu codigo mais recente <= 2. Pela sua descricao, deveria ser menor que 2 para evitar operar mais que duas vezes ja, entretanto operar uma vez adicional pode acontecer se tiver trades muito corelacionados e ocorrerem durante a atualizacao do historico.
 
Ricardo Rodrigues Lucca:
TimeTradeServer eh o horario atual do servidor, enquanto o TimeCurrent eh o horario da ultima cotacao presente no observador de mercado. Olhe a ultima linha do seu codigo mais recente <= 2. Pela sua descricao, deveria ser menor que 2 para evitar operar mais que duas vezes ja, entretanto operar uma vez adicional pode acontecer se tiver trades muito corelacionados e ocorrerem durante a atualizacao do historico.

Bom dia Ricardo,


Certo, verdade... Obg pelo apontamento.

 

Olá Daniel,

seu código não está errado, mas acho que ler o histórico de ordens não é melhor caminho, por exemplo: cada operação é de fato uma ordem de entrada e uma ordem de saída, assim duas operações envolvem 4 ordens, duas de entrada e duas de saída é por isso que você está testando <=2 ordens...


Sugiro você estudar o código abaixo ele percorre o histórico de deal ( transação ) seleciona as saídas e trabalha com resultados.

Atenção: O código está correto para operações com lote mínimo, para lotes maiores em conta REAL não está correto.

//+------------------------------------------------------------------+
//|                                                 Deal_history.mq5 |
//|                                         Rogério Giannetti Torres |
//|                               mailto:giannetti.rogerio@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Rogério Giannetti Torres"
#property link      "mailto:giannetti.rogerio@gmail.com"
#property version   "1.00"
#define ToNamed(A) #A + " = " + (string)(A) + "   "
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
ulong  ticket, magicNumber;
int    dealsTotal;
double profitTotal;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   dealsTotal = 0;
   profitTotal = 0;
   magicNumber = 123456;
   datetime timeFrom = StringToTime(TimeToString(TimeTradeServer(), TIME_DATE));
   HistorySelect(timeFrom, INT_MAX);
   for(int i = HistoryDealsTotal() - 1; i >= 0 ; i--)
     {
      if((ticket = HistoryDealGetTicket(i)) > 0)
        {
         if(HistoryDealGetString(ticket, DEAL_SYMBOL) == _Symbol
            && HistoryDealGetInteger(ticket, DEAL_MAGIC) == magicNumber
            && HistoryDealGetInteger(ticket, DEAL_ENTRY) != DEAL_ENTRY_IN)
           {
            dealsTotal++;
            profitTotal+=HistoryDealGetDouble(ticket,DEAL_PROFIT);
           }
        }
     }
   Print(ToNamed(timeFrom),ToNamed(dealsTotal),ToNamed(profitTotal));
  }
//+------------------------------------------------------------------+
 
Rogerio Giannetti Torres:

Olá Daniel,

seu código não está errado, mas acho que ler o histórico de ordens não é melhor caminho, por exemplo: cada operação é de fato uma ordem de entrada e uma ordem de saída, assim duas operações envolvem 4 ordens, duas de entrada e duas de saída é por isso que você está testando <=2 ordens...


Sugiro você estudar o código abaixo ele percorre o histórico de deal ( transação ) seleciona as saídas e trabalha com resultados.

Atenção: O código está correto para operações com lote mínimo, para lotes maiores em conta REAL não está correto.

Rogerio, boa tarde. Fico feliz por saber de vc que a lógica do meu código está ao menos coerente. Mas por não ser o melhor caminho, conforme apontou, vou estudar o código que vc me passou até eu dominar esse tema e poder aplicar no meu caso. Sinceros agradecimentos.

Sucesso!

Razão: