Discussing the article: "The Repository Pattern in MQL5: Abstracting Trade History Access for Testable EA Logic"

 

Check out the new article: The Repository Pattern in MQL5: Abstracting Trade History Access for Testable EA Logic.

Direct calls to the MQL5 History API inside analytics components create hidden terminal dependencies that make isolated testing structurally impossible. This article constructs an ITradeRepository abstraction layer with CLiveTradeRepository and CMockTradeRepository implementations, enabling the same analytics engine and equity curve panel to operate identically against live account data or a deterministic in-memory dataset. Repository injection eliminates direct API coupling, supports offline validation, and confines data source changes to a single implementation class.

An Expert Advisor (EA) analytics module that directly calls HistorySelect(), HistoryDealGetDouble(), and HistoryDealGetInteger() inside its calculation methods introduces hidden dependencies on the MetaTrader 5 terminal state. For example, a method like CalculateWinRate() appears to be a pure function. In practice, it requires an active broker connection and a loaded account history. It also requires a prior HistorySelect() call with the correct date range. If any of these conditions are missing, the method returns incorrect results without raising a detectable error.

This tight coupling creates severe testing and maintenance limitations. An analytics module written this way cannot be executed in isolation. To unit-test CalculateWinRate(), you need a live terminal and an active connection. You also need an account with matching historical data. Verifying edge cases—such as an empty history—is impractical at scale. It forces the developer to either manually clear terminal data or inject conditional testing logic into production code.

The maintenance overhead compounds as the codebase grows:

  • API Changes: If a broker changes its deal classification scheme, every calculation method reading HistoryDealGetInteger() must be updated manually.
  • Portability Barriers: Porting the EA to a different broker or architecture requires disentangling the analytics code from the data access layer.
  • Code Duplication: New modules must either duplicate the data retrieval pattern or rely on the undocumented assumption that another module already initialized the history state.

Architectural comparison demonstrating

Author: Ushana Kevin Iorkumbul