Обсуждение статьи "Многопоточный асинхронный WebRequest на MQL5 своими руками"

 

Опубликована статья Многопоточный асинхронный WebRequest на MQL5 своими руками:

В статье рассмотрена библиотека, позволяющая повысить эффективность работы с HTTP-запросами в MQL5. Выполнение WebRequest в неблокирующем режиме реализовано в дополнительных потоках с использованием вспомогательных графиков и экспертов, обмена пользовательскими событиями и чтения разделяемых ресурсов. Исходные коды прилагаются.

Реализация торговых алгоритмов часто требует анализа информации из различных внешних источников, в частности из Internet. MQL5 предоставляет функцию WebRequest для отправки HTTP-запросов во "внешний мир", но она, к сожалению, обладает одним заметным недостатком. Эта функция является синхронной, а потому блокирует работу эксперта на все время выполнения запроса. Напомним, что для каждого эксперта в MetaTrader 5 выделен один единственный поток, который последовательно выполняет имеющиеся вызовы функций API в коде, а также обработчики поступающих событий (таких как тики, изменения стакана в BookEvent, таймер, торговые транзакции, события графика и т.д.). В каждый момент времени выполняется только один фрагмент кода, а все остальные "задачи" ожидают своего момента в очередях, пока текущий фрагмент не вернет управление ядру.

Например, если эксперт должен обрабатывать новые тики в реальном времени, и в дополнение к этому - периодически проверять экономические новости на одном или нескольких сайтах, то выполнить оба требования без какого-либо ущерба друг другу невозможно. Как только в коде выполняется WebRequest, эксперт остается "застывшим" на строке с вызовом функции, а события о новых тиках пропускаются. Даже с учетом того, что пропущенные тики можно затем прочитать с помощью функции CopyTicks, момент для принятия решения может быть упущен. Вот как данная ситуация иллюстрируется с помощью UML диаграммы последовательности:

Диаграмма последовательности обработки событий с блокирующим кодом в одном потоке

Рис.1 Диаграмма последовательности обработки событий с блокирующим кодом в одном потоке

Автор: Stanislav Korotky

 

Как всегда, сильно! Если библиотеку обобщить, то можно было бы создать готовый инструментарий для простого создания асинхронности любых функций. При этом кроссплатформенный.

Таким методом можно создать OrderSendAsync под MT4, например.

Спасибо за статью!

 
fxsaber:

Как всегда, сильно! Если библиотеку обобщить, то можно было бы создать готовый инструментарий для простого создания асинхронности любых функций. При этом кроссплатформенный.

Таким методом можно создать OrderSendAsync под MT4, например.

Да, я как-то давно начинал делать систему группового управления ордерами для МТ4 с плагинами-командами на сообщениях, но это не было закончено. Не проверял, как работают ресурсы в МТ4, хотя судя по документации должно быть как в МТ5.

 
Stanislav Korotky:

Не проверял, как работают ресурсы в МТ4, хотя судя по документации должно быть как в МТ5.

Да, все, как в MT5. Только в текущем MT4-билде баг, из-за которого обмен невозможен

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2018.09.17 18:38

ResourceReadImage в MT4 с таким багом, что невозможно прочесть ресурс
#property strict

class RESOURCE
{
public:
  const string Name;

  RESOURCE( const string sName = __FILE__ ) : Name("::" + sName )
  {
  }

  ~RESOURCE( void)
  {
    ::ResourceFree(this.Name);
  }

  virtual bool Set( const uint &Data[], const uint Width = 1, const ENUM_COLOR_FORMAT ColorFormat = COLOR_FORMAT_XRGB_NOALPHA ) const
  {
    return(::ResourceCreate(this.Name, Data, Width, (Width == 0) ? ::ArraySize(Data) : ::ArraySize(Data) / Width, 0, 0, Width, ColorFormat));
  }

  int Get( uint &Data[] ) const
  {
    uint Width;
    uint Height;

    return(::ResourceReadImage(this.Name, Data, Width, Height) ? ::ArraySize(Data) : 0);
  }
};

void OnStart()
{
  RESOURCE Resource;
  
  uint DataIn[] = {0};  
  Resource.Set(DataIn);
   
  uint DataOut[];
  Resource.Get(DataOut);
  
  Print(DataOut[0]); // MT5x64 (build 1881) - 0, MT4 (build 1126) - 4278190100 (случайные значения)
}


ResourceSave пишет правильно, а вот ResourceReadImage - один большой баг. Возможно ли исправить? В MT5x32 не проверял...


Возможно, этот метод поможет сделать чтение ресурсов в MT4 правильным. Не проверял.

 

Кстати, можно же обойтись без полноценных чартов - OBJ_CHART. На них скрипты загружаются на ура. А там WebRequest пашет и OrderSend.

Приводил пример, как индикатор сделать торговым без доп. чартов.

Таким образом можно в качестве менеджера использовать iCustom-индикатор, а он будет на каждый WebRequestAsync запускать WebRequest в своем скрипте.

Конструкция должна получиться проще и надежнее, т.к. доп. окон не будет.

 
fxsaber:

Кстати, можно же обойтись без полноценных чартов - OBJ_CHART. На них скрипты загружаются на ура. А там WebRequest пашет и OrderSend.

Приводил пример, как индикатор сделать торговым без доп. чартов.

Таким образом можно в качестве менеджера использовать iCustom-индикатор, а он будет на каждый WebRequestAsync запускать WebRequest в своем скрипте.

Конструкция должна получиться проще и надежнее, т.к. доп. окон не будет.

можно ссылку на сей пример ?

 
Maxim Kuznetsov:

можно ссылку на сей пример ?

Здесь и тут.


ЗЫ Наверное, пользователь удивится, если Маркет-индикатор начнет приторговывать...

 
fxsaber:

Здесь и тут.


ЗЫ Наверное, пользователь удивится, если Маркет-индикатор начнет приторговывать...

блин, тут просто передача эвентов....а я то подумал :-)

 
Maxim Kuznetsov:

блин, тут просто передача эвентов....а я то подумал :-)

Нет там никаких эвентов.

 
fxsaber:

Нет там никаких эвентов.

приказы исполняет скрипт..

а как он получает приказы - это уже дело десятое.

 
Maxim Kuznetsov:

приказы исполняет скрипт..

а как он получает приказы - это уже дело десятое.

Скрипт не получает приказы, он запускается индикатором в любом количестве.

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