Обсуждение статьи "Библиотека для простого и быстрого создания программ для MetaTrader (Часть X): Совместимость с MQL4 - События открытия позиции и активации отложенных ордеров" - страница 2

 
fxsaber:

ЗЫ Еще хочу иметь возможность запускать Вашу библиотеку в Virtual. Для этого нужно иметь доступ к MT4-style части библы.

Получилось запустить

#define TESTER_CUSTOM // Запуск советника в пользовательском Тестере
#include <fxsaber\Tester\Tester.mqh> // https://www.mql5.com/ru/code/24848

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

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

Т.е. вся событийная модель библиотеки работает и в виртуальном окружении.

 
fxsaber:

В ЛС отправил вариант Вашей библиотеки, которая работает в MT5 через Вами прописанную MT4-style-логику.

Дело в том, что у кроссплатформенных библиотек вероятность работоспособности MQL4-style-части библиотеки гораздо выше, чем MQL5-style. Поэтому при использовании кроссплафторменных библиотек предпочитаю использовать в MT5 их MQL4-style-логику. Так надежней гораздо в MT5 получается.


Думаю, что в MT5 Ваша MQL5-style логика потребует еще долгого выявления багов, а MQL4-style если и будет иметь баги, то минимальное количество и не критические.

В этой библиотеки нет разделения логики на MQL5 и MQL4. Работа идёт с фактическим состоянием и фактическим изменением состояния торгового окружения. Не используются чисто MQL5-OnTradeXXX-функции - всё берётся из состояния торгового окружения. Т.е., это не событийная модель. Поэтому я и говорю - логика одна, реализации чуть отличаются из-за разницы необходимых функций работы с окружением.

У вас, в вашей библиотеке, всё подчинено переносу MQL5-style в MQL4-style, а здесь - в этой библиотеке, скорее наоборот - MQL5-style (как более гибкий) портируется в MQL4. И таким образом, библиотека даёт для MQL4 немного больше, чем есть в стандартных возможностях MQL4 - например, здесь есть подобие PositionID для MQL4, тут есть возможность узнать во время работы (не при просчёте истории) от какого ордера была порождена позиция. Сделок, к сожалению, для MQL4 нет - нет таких данных. Ну или не сильно над этим думал...

Исходя из всего вышесказанного, повторю - тут нет разделения на два стиля - он един для обеих платформ. Поэтому мне не очень понятно ваше желание дважды преобразовать к MQL4 итак уже преобразованное.

 
Artyom Trishkin:

Исходя из всего вышесказанного, повторю - тут нет разделения на два стиля - он един для обеих платформ. Поэтому мне не очень понятно ваше желание дважды преобразовать к MQL4 итак уже преобразованное.

Непонимание лишь в терминологии. Ваша библиотека под MT4 является оберткой, которая написана на MQL4. Это и есть MT4-style. Вот эта часть мне и нужна была. Собственно, сделал.

 
fxsaber:

Непонимание лишь в терминологии. Ваша библиотека под MT4 является оберткой, которая написана на MQL4. Это и есть MT4-style. Вот эта часть мне и нужна была. Собственно, сделал.

Добро
 

Артём привет. Что-то у меня не получается работа с этой библиотекой.Терзаю её в MQL4.

Вчера в тестере в свой советник подключил и даже получал сообщения об открытии или закрытии позиций. А вот сегодня перенёс то что было для тестера в новый советник, уже без кнопок для открытия позиций и пытаюсь получить сообщение об открытии или закрытии, но не получается. И ещё по моим задумкам надо будет получить тикет позиции, цены и время. Этого я не смог получить даже в тестере.

#property strict

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

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

/************************Expert tick function************************/
void OnTick()
{
//--- Инициализация последнего торгового события
   static ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Если работа в тестере
   if(MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer();
      //PressButtonsControl();
     }
//--- Если последнее торговое событие изменилось
   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()
{
//--- Инициализация последнего торгового события
   static ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Если работа в тестере
   if(MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer();
      //PressButtonsControl();
     }
//--- Если последнее торговое событие изменилось
   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("");
}/*******************************************************************/
Файлы:
00.mq4  5 kb
 

А самое непонятное, сейчас поставил свой пробник с кнопками на график... Не приходят сообщения. Вернул его в тестер, всё работает.


ps; С этим разобрался. Надо включить OnChartEvent с пользовательским событием.

 
Alexey Viktorov:
А самое непонятное, сейчас поставил свой пробник с кнопками на график... Не приходят сообщения. Вернул его в тестер, всё работает.
Убери все упоминания таймера из советника - библиотека создаёт для него свой таймер и работает в нём. Всё же делается для простоты и удобства.
 
Artyom Trishkin:
Убери все упоминания таймера из советника - библиотека создаёт для него свой таймер и работает в нём. Всё же делается для простоты и удобства.

Убрал таймер, вставил OnChartEvent в таком виде. Контроль кнопок не нужен наверное, а пользовательское событие думаю создаётся где-то в дебрях библиотеки. Но результата я не добился.

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   //if(MQLInfoInteger(MQL_TESTER))
   //   return;
   //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:

Убрал таймер, вставил OnChartEvent в таком виде. Контроль кнопок не нужен наверное, а пользовательское событие думаю создаётся где-то в дебрях библиотеки. Но результата я не добился.

Позже пример сделаю.
 

Артём, скажи пожалуйста какую роль играет выделенный участок кода

#property strict

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

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

/************************Expert tick function************************/
void OnTick()
{
//--- Инициализация последнего торгового события
   static ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Если работа в тестере
   if(MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer();
     }
//--- Если последнее торговое событие изменилось
   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()
{
//--- Инициализация последнего торгового события
   static ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Если работа в тестере
   if(!MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer();
     }
}/*******************************************************************/

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

Как может выполняться этот код, если таймер не включен?

Но если этот участок кода удалить, то сообщения о событии не печатаются. А с ним всё работает.

И хотелось-бы вместе с сообщением о событии была возможность получить тикет, цены и возможно какие-то ещё свойства позиций и ордеров.

Причина обращения: