Discussion of article "DIY multi-threaded asynchronous MQL5 WebRequest"

 

New article DIY multi-threaded asynchronous MQL5 WebRequest has been published:

The article describes the library allowing you to increase the efficiency of working with HTTP requests in MQL5. Execution of WebRequest in non-blocking mode is implemented in additional threads that use auxiliary charts and Expert Advisors, exchanging custom events and reading shared resources. The source codes are applied as well.

Implementation of trading algorithms often requires analyzing data from various external sources, including Internet. MQL5 provides the WebRequest function for sending HTTP requests to the "outside world", but, unfortunately, it has one noticeable drawback. The function is synchronous meaning it blocks the EA operation for the entire duration of a request execution. For each EA, MetaTrader 5 allocates a single thread that sequentially executes the existing API function calls in the code, as well as incoming event handlers (such as ticks, depth of market changes in BookEvent, timer, trading operations, chart events, etc.). Only one code fragment is executed at a time, while all remaining "tasks" wait for their turn in queues, till the current fragment returns control to the kernel.

For example, if an EA should process new ticks in real time and periodically check economic news on one or several websites, it is impossible to fulfill both requirements without them interfering with one other. As soon as WebRequest is executed in the code, the EA remains "frozen" on the function call string, while new tick events are skipped. Even with the ability to read skipped ticks using the CopyTicks function, the moment for making a trading decision may be missed. Here is how this situation is illustrated using the UML sequence diagram:

Event handling sequence diagram featuring the blocking code in one thread

Fig.1. Event handling sequence diagram featuring the blocking code in one thread

Author: Stanislav Korotky

 
Nice article, thanks. How about WinINet Asynchronous mode?
 
Mohammad Hossein Sadeghi:
Nice article, thanks. How about WinINet Asynchronous mode?

I don't have plans to implement such a thing, sorry.

 

In the Russian discussion of the article one may find further investigation of the approach and an alternative implementation based on chart objects.

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

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

Stanislav Korotky, 2018.11.14 14:20

I post an alternative way to launch web requests - with the help of graph objects, which use a template with an expert assistant. It can be used from both experts and indicators. Dependencies are the same as in the article. The files of the new implementation:

  • multiwebobjectworker.mqh - header file with common classes;
  • multiwebobjectworker.mq5 is a working expert performing web requests inside graph objects;
  • multiwebindicator.mq5 - unbuffered indicator showing the launch of web requests;

An object is created for each request, an expert assistant is created in it, and at the end of the request, the object is deleted. The exchange of query data and results, as in the article, is done through resources.

Judging by the logs, this mechanism does not provide full-fledged query execution parallelism, since the objects probably share a common event queue. Example log:

2018.11.14 15:11:58.492 multiwebindicator (EURUSD,H1)   129912254742671348: Starting chart object WRS1 129912254742671349
2018.11.14 15:11:58.694 multiwebindicator (EURUSD,H1)   129912254742671348: Starting chart object WRS2 129912254742671350
2018.11.14 15:11:58.819 multiwebindicator (EURUSD,H1)   129912254742671348: Starting chart object WRS3 129912254742671351
2018.11.14 15:11:58.960 multiwebobjectworker (EURUSD,H1)        129912254742671349: OnInit
2018.11.14 15:11:58.960 multiwebobjectworker (EURUSD,H1)        129912254742671349: Reading request \Indicators\multiwebindicator.ex5::WRS_0_129912254742671348
2018.11.14 15:11:58.960 multiwebobjectworker (EURUSD,H1)        129912254742671349: Got 64 bytes in request
2018.11.14 15:11:58.960 multiwebobjectworker (EURUSD,H1)        129912254742671349: GET https://google.com/ User-Agent: n/a 5000 
2018.11.14 15:11:58.975 multiwebobjectworker (EURUSD,H1)        129912254742671350: OnInit
2018.11.14 15:11:58.975 multiwebobjectworker (EURUSD,H1)        129912254742671350: Reading request \Indicators\multiwebindicator.ex5::WRS_1_129912254742671348
2018.11.14 15:11:58.975 multiwebobjectworker (EURUSD,H1)        129912254742671350: Got 60 bytes in request
2018.11.14 15:11:58.975 multiwebobjectworker (EURUSD,H1)        129912254742671350: GET https://ya.ru User-Agent: n/a 5000 
2018.11.14 15:11:59.084 multiwebobjectworker (EURUSD,H1)        129912254742671351: OnInit
2018.11.14 15:11:59.084 multiwebobjectworker (EURUSD,H1)        129912254742671351: Reading request \Indicators\multiwebindicator.ex5::WRS_2_129912254742671348
2018.11.14 15:11:59.084 multiwebobjectworker (EURUSD,H1)        129912254742671351: Got 72 bytes in request
2018.11.14 15:11:59.084 multiwebobjectworker (EURUSD,H1)        129912254742671351: GET https://www.startpage.com/ User-Agent: n/a 5000 
2018.11.14 15:11:59.162 multiwebobjectworker (EURUSD,H1)        129912254742671350: Done in 187ms
2018.11.14 15:11:59.178 multiwebindicator (EURUSD,H1)   129912254742671348: Result code 200
2018.11.14 15:11:59.178 multiwebindicator (EURUSD,H1)   129912254742671348: Reading result \Experts\multiwebobjectworker.ex5::WRS_0_129912254742671350
2018.11.14 15:11:59.178 multiwebindicator (EURUSD,H1)   129912254742671348: Got 16592 bytes in response
2018.11.14 15:11:59.178 multiwebindicator (EURUSD,H1)   GET https://ya.ru
2018.11.14 15:11:59.178 multiwebindicator (EURUSD,H1)   Received 3734 bytes in header, 12775 bytes in document
2018.11.14 15:11:59.256 multiwebobjectworker (EURUSD,H1)        129912254742671350: OnDeinit
2018.11.14 15:11:59.272 multiwebobjectworker (EURUSD,H1)        129912254742671349: Done in 297ms
2018.11.14 15:11:59.334 multiwebindicator (EURUSD,H1)   129912254742671348: Result code 200
2018.11.14 15:11:59.334 multiwebindicator (EURUSD,H1)   129912254742671348: Reading result \Experts\multiwebobjectworker.ex5::WRS_0_129912254742671349
2018.11.14 15:11:59.334 multiwebindicator (EURUSD,H1)   129912254742671348: Got 12688 bytes in response
2018.11.14 15:11:59.334 multiwebindicator (EURUSD,H1)   GET https://google.com/
2018.11.14 15:11:59.334 multiwebindicator (EURUSD,H1)   Received 790 bytes in header, 11813 bytes in document
2018.11.14 15:11:59.350 multiwebobjectworker (EURUSD,H1)        129912254742671349: OnDeinit
2018.11.14 15:11:59.833 multiwebobjectworker (EURUSD,H1)        129912254742671351: Done in 749ms
2018.11.14 15:11:59.833 multiwebindicator (EURUSD,H1)   129912254742671348: Result code 200
2018.11.14 15:11:59.833 multiwebindicator (EURUSD,H1)   129912254742671348: Reading result \Experts\multiwebobjectworker.ex5::WRS_0_129912254742671351
2018.11.14 15:11:59.833 multiwebindicator (EURUSD,H1)   129912254742671348: Got 45212 bytes in response
2018.11.14 15:11:59.833 multiwebindicator (EURUSD,H1)   GET https://www.startpage.com/
2018.11.14 15:11:59.833 multiwebindicator (EURUSD,H1)   Received 822 bytes in header, 44307 bytes in document
2018.11.14 15:11:59.849 multiwebindicator (EURUSD,H1)   > > > Async WebRequest workers finished 3 tasks in 1357ms
2018.11.14 15:11:59.880 multiwebobjectworker (EURUSD,H1)        129912254742671351: OnDeinit

I'm attaching the sources here as well.

Also please check for updated versions of include files from fxsaber, which are used in dependencies - they may contain bugfixes and speedups.

Files:
 
Stanislav Korotky #:


How would this be designed now that there are services in MT5?

 
bot #:

How would this be designed now that there are services in MT5?

It changes nothing as there is no easier way to communicate with an MT5 service.
Reason: