Discussão do artigo "Biblioteca para desenvolvimento fácil e rápido de programas para a MetaTrader (parte X)" - página 2

 
fxsaber:

ZY Também quero poder executar sua biblioteca no Virtual. Para isso, preciso ter acesso à parte da biblioteca no estilo MT4.

Consegui executá-la

#define  TESTER_CUSTOM // Executar o Expert Advisor no testador de usuário
#include <fxsaber\Tester\Tester.mqh> // https://www.mql5.com/pt/code/24848

#include <IgorM\TradePanel_C#\TradePanel_C#.mqh> // https://www.mql5.com/pt/code/24829

#include "TestDoEasyPart10.mq5" // https://www.mql5.com/pt/articles/6767

Ou seja, todo o modelo de evento da biblioteca também funciona no ambiente virtual.

 
fxsaber:

Enviei uma variante de sua biblioteca, que funciona no MT5 por meio de sua lógica de estilo MT4.

A questão é que as bibliotecas de plataforma cruzada têm uma probabilidade muito maior de funcionar na parte da biblioteca no estilo MQL4 do que no estilo MQL5. Portanto, ao usar bibliotecas de plataforma cruzada, prefiro usar sua lógica de estilo MQL4 no MT5. Ela é muito mais confiável no MT5.


Acho que, no MT5, sua lógica no estilo MQL5 levará muito tempo para detectar bugs, enquanto o estilo MQL4 terá bugs, mas apenas um número mínimo e não crítico.

Nessa biblioteca, não há divisão da lógica em MQL5 e MQL4. Ela trabalha com o estado real e as mudanças reais no estado do ambiente de negociação. Não são usadas funções puramente MQL5-OnTradeXXX - tudo é retirado do estado do ambiente de negociação. Ou seja, não se trata de um modelo baseado em eventos. É por isso que eu digo: a lógica é a mesma, as implementações são ligeiramente diferentes devido à diferença nas funções necessárias para trabalhar com o ambiente.

Em sua biblioteca, tudo está subordinado à portabilidade do estilo MQL5 para o estilo MQL4, enquanto aqui - nesta biblioteca - é exatamente o oposto - o estilo MQL5 (por ser mais flexível) é portado para MQL4. Assim, a biblioteca fornece um pouco mais para MQL4 do que os recursos padrão MQL4 - por exemplo, tem um PositionID semelhante para MQL4, aqui você pode descobrir durante o trabalho (não ao calcular o histórico) de qual ordem a posição foi gerada. Infelizmente, não há ofertas para MQL4 - não há esses dados. Bem, ou eu não pensei muito sobre isso....

Com base em tudo o que foi dito acima, repito - não há divisão em dois estilos - é a mesma coisa para ambas as plataformas. Portanto, não entendo seu desejo de converter duas vezes para MQL4 o que já foi convertido.

 
Artyom Trishkin:

Com base em tudo o que foi dito acima, repito - não há divisão em dois estilos - é o mesmo para ambas as plataformas. Portanto, não entendo seu desejo de converter duas vezes para MQL4 o que já foi convertido.

O mal-entendido está apenas na terminologia. Sua biblioteca para MT4 é um wrapper, que é escrito em MQL4. Esse é o estilo do MT4. Essa é a parte de que eu precisava. Na verdade, eu já fiz isso.

 
fxsaber:

O mal-entendido está apenas na terminologia. Sua biblioteca MT4 é um wrapper escrito em MQL4. Esse é o estilo MT4. Essa é a parte que eu precisava. Na verdade, eu já fiz isso.

Bom
 

Olá, Artem. Estou tendo problemas para trabalhar com essa biblioteca, pois estou tentando usá-la na MQL4.

Ontem eu a conectei ao meu EA no testador e até recebi mensagens sobre a abertura ou fechamento de posições. Mas hoje transferi o que eu tinha para o testador para um novo EA, sem botões para abrir posições e estou tentando receber uma mensagem sobre abertura ou fechamento de posições, mas não consigo. E, de acordo com minhas idéias, preciso obter um ticket de posição, preço e horário. Não consegui fazer isso nem mesmo no testador.

#property strict

#include <DoEasy\Engine.mqh>
CEngine        engine;

/*******************Expert initialization function*******************/
int OnInit()
{
   EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
}/*******************************************************************/

/************************Expert tick function************************/
void OnTick()
{
//--- Inicialização do último evento de negociação
   static ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Se estiver trabalhando no testador
   if(MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer();
      //PressButtonsControl();
     }
//--- Se o último evento de negociação foi alterado
   if(engine.LastTradeEvent()!=last_event)
     {
      last_event=engine.LastTradeEvent();
      Comment("last_event: ",EnumToString(last_event));
      Print(__FUNCTION__, " last_event: ",EnumToString(last_event));
      engine.ResetLastTradeEvent();
      //Print("last_event: ",EnumToString(last_event));
     }

}/*******************************************************************/

/***************************Timer function***************************/
void OnTimer()
{
//--- Inicialização do último evento de negociação
   static ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Se estiver trabalhando no testador
   if(MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer();
      //PressButtonsControl();
     }
//--- Se o último evento de negociação foi alterado
   if(engine.LastTradeEvent()!=last_event)
     {
      last_event=engine.LastTradeEvent();
      Comment("last_event: ",EnumToString(last_event));
      Print(__FUNCTION__, " last_event: ",EnumToString(last_event));
      engine.ResetLastTradeEvent();
      //Print("last_event: ",EnumToString(last_event));
     }
}/*******************************************************************/

void OnDeinit(const int reason)
{
 EventKillTimer();
 Comment("");
}/*******************************************************************/
Arquivos anexados:
00.mq4  5 kb
 

E o mais desconcertante é que agora coloquei minha sonda com botões no chart..... Nenhuma mensagem é recebida. Coloquei-a de volta no testador e tudo funcionou.


ps; descobri o problema. É necessário ativar o OnChartEvent com um evento personalizado.

 
Alexey Viktorov:
E o mais desconcertante é que agora coloquei minha sonda com botões no chart..... Nenhuma mensagem é recebida. Coloquei-a novamente no testador e tudo funciona.
Remova todas as referências ao cronômetro do EA - a biblioteca cria seu próprio cronômetro para ele e funciona nele. Tudo é feito por simplicidade e conveniência.
 
Artyom Trishkin:
Remova todas as referências ao cronômetro do EA - a biblioteca cria seu próprio cronômetro para ele e trabalha nele. Tudo é feito por simplicidade e conveniência.

Removi o cronômetro e inseri OnChartEvent nesse formulário. O controle do botão provavelmente não é necessário, e o evento do usuário, creio eu, é criado em algum lugar nos confins da biblioteca. Mas não obtive o resultado.

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   //se(MQLInfoInteger(MQL_TESTER))
   // retornar;
   //if(id==CHARTEVENT_OBJECT_CLICK && StringFind(sparam, "BUTT_")>0)
   // {
   // PressButtonEvents(sparam);
   // }
   if(id>=CHARTEVENT_CUSTOM)
     {
      ushort event=ushort(id-CHARTEVENT_CUSTOM);
      Print(DFUN,"id=",id,", event=",EnumToString((ENUM_TRADE_EVENT)event),", lparam=",lparam,", dparam=",DoubleToString(dparam,Digits()),", sparam=",sparam);
     } 
  }
 
Alexey Viktorov:

Removi o cronômetro e inseri OnChartEvent nesse formulário. O controle do botão provavelmente não é necessário, e o evento personalizado, creio eu, foi criado em algum lugar na biblioteca. Mas não obtive o resultado.

Vou criar um exemplo mais tarde.
 

Artem, diga-me qual é a função da seção de código destacada

#property strict

#include <DoEasy\Engine.mqh>
CEngine        engine;

/*******************Expert initialization function*******************/
int OnInit()
{
   //EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
}/*******************************************************************/

/************************Expert tick function************************/
void OnTick()
{
//--- Inicialização do último evento de negociação
   static ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Se estiver trabalhando no testador
   if(MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer();
     }
//--- Se o último evento de negociação foi alterado
   if(engine.LastTradeEvent()!=last_event)
     {
      last_event=engine.LastTradeEvent();
      Comment("last_event: ",EnumToString(last_event));
      Print(__FUNCTION__, " last_event: ",EnumToString(last_event));
      //engine.ResetLastTradeEvent();
      //Print("last_event: ",EnumToString(last_event));
     }

}/*******************************************************************/

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id>=CHARTEVENT_CUSTOM)
     {
      ushort event=ushort(id-CHARTEVENT_CUSTOM);
      Print(DFUN,"id=",id,", event=",EnumToString((ENUM_TRADE_EVENT)event),", lparam=",lparam,", dparam=",DoubleToString(dparam,Digits()),", sparam=",sparam);
     } 
  }

/***************************Timer function***************************/
void OnTimer()
{
//--- Inicialização do último evento de negociação
   static ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Se estiver trabalhando no testador
   if(!MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer();
     }
}/*******************************************************************/

void OnDeinit(const int reason)
{
 //EventKillTimer();
 Comment("");
}/*******************************************************************/

Como esse código pode ser executado se o cronômetro não estiver ativado?

Mas se essa seção de código for excluída, as mensagens de evento não serão impressas. Mas tudo funciona com ela.

E eu gostaria de obter um tíquete, preços e possivelmente algumas outras propriedades de posições e ordens junto com a mensagem do evento.