Discussing the article: "Event-Driven Architecture in MQL5: How to Turn an Expert Advisor into a Full-Fledged Trading System"

 

Check out the new article: Event-Driven Architecture in MQL5: How to Turn an Expert Advisor into a Full-Fledged Trading System.

The article is dedicated to the event-driven architecture in MQL5 and describes the transition from the monolithic OnTick model to distributed processing. We will consider predefined and custom events, services and messaging between programs, as well as common architectural errors. A practical example demonstrates how to organize interactions between indicators and an EA to reduce load, improve readability, and simplify maintenance.

When developing an EA in MQL5, many people start with the most obvious solution: they put all the logic into the OnTick method. It really is easier to get started this way. But this approach has a hidden cost. As the project grows, trading rules, condition checking, order processing, data updating, interface, calculations, and logging are all combined into a single handler. As a result, the code grows to a state where it is no longer programmable and in fact is held together by sheer luck. Any change in one place begins to affect completely different parts of the system. You fix the visual panel – and suddenly the trading scenario breaks. You change the entry filter - an error appears in the background check. Such an EA quickly turns into a fragile monolith, where complexity grows faster than the developer's confidence.

MetaTrader 5 is more than just a stream of quotes. It is based on events. The terminal constantly receives ticks, timer signals, user actions, trading status changes, and market depth events. These messages should be handled separately. To achieve this, MQL5 features different handlers, each with its own area of responsibility. OnTick is responsible for market updates. OnTimer — for periodic and background tasks. OnChartEvent — for the reaction to the GUI and user actions. When logic is distributed according to its purpose, the code ceases to be cluttered. It starts to resemble a well-structured engineering system, where each module does its job and does not interfere with its neighbors.

MQL5 events

In this article we will look at how to move from the model of all in OnTick towards a more mature event architecture. Let's look at the roles of predefined handlers and custom events, as well as services that are not tied to a chart. Let's take a closer look at typical errors that break the architecture even before actual work begins. The main idea here is simple: when MQL5 is used for its intended purpose, it allows us to build not only trading robots, but also full-fledged application systems.


Author: MetaQuotes

 
Working in an Expert Advisor with indicators without buffers is probably fine for an example.
 
//+------------------------------------------------------------------+
//| Trade function|
//+------------------------------------------------------------------+
void OnTrade()
  {
   Sleep(0);
//---
  }
//+------------------------------------------------------------------+
//| TradeTransaction function|
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
   Sleep(0);
//---
  }
For what?
 
            if(!cTrade.PositionClose(cPosition.Ticket()))
              {
               PrintFormat("Error close Sell position: %d", GetLastError());
               return;
              }
It seems like cTrade contains output in case of an error.
 
fxsaber #:
Working in an Expert Advisor with indicators without buffers is probably fine for an example.


In the example, strict updating of symbol data is done (it would be good to use MQL_TESTER).

void OnTick()
  {
//---
   if(BuySignal)
     {
      cSymbol.Refresh();
      cSymbol.RefreshRates();


But it does not check the relevance of the signal and tick calculated through the events. And this is a real problem.


It can be weakened through asynchronous OrderSend, but not solved. Therefore, even in such an example, in ChartEvent-event we need to additionally pass the data of the tick on which the event generation occurred.

 
Great, the Service type of MQL5 programs is so underrated.
 
Great example, thank you.