記事「MQL5におけるイベント駆動型アーキテクチャ:エキスパートアドバイザーを本格的なトレードシステムに進化させる方法」についてのディスカッション

 

新しい記事「MQL5におけるイベント駆動型アーキテクチャ:エキスパートアドバイザーを本格的なトレードシステムに進化させる方法」はパブリッシュされました:

MQL5におけるイベント駆動アーキテクチャについて解説し、モノリシックなOnTickモデルから分散処理への移行を取り上げます。定義済みイベントとカスタムイベント、サービス、およびプログラム間のメッセージングについて説明するとともに、アーキテクチャ上でよく見られる典型的な誤りについても考察します。また、実践的な例を通じて、インジケータとEAの連携をどのように構成すれば、負荷を軽減し、可読性を向上させ、保守を容易にできるのかを示します。

MQL5でEAを開発する際、多くの人は最も分かりやすい方法から始めます。すなわち、すべてのロジックをOnTickメソッドの中に配置する方法です。実際、この方法は開発を始めるうえでは簡単です。しかし、このアプローチには見えにくい代償があります。プロジェクトが成長するにつれて、売買ルール、条件チェック、注文処理、データ更新、インターフェース、計算、ログ出力などが、すべて単一のハンドラに集約されていきます。その結果、コードはやがてプログラムとして扱いにくい状態にまで肥大化し、実際には運任せで辛うじて動いているような状態になります。一箇所を変更すると、システムのまったく別の部分に影響が及び始めます。ビジュアルパネルを修正すると、突然トレードシナリオが壊れます。エントリーフィルタを変更すると、バックグラウンドチェックでエラーが発生します。このようなEAはすぐに脆弱なモノリスへと変わり、複雑さは開発者の自信が増す速度よりも速く増大していきます。

MetaTrader 5は単なる価格配信のストリームではありません。その基盤はイベントです。ターミナルは常に、ティック、タイマーシグナル、ユーザー操作、取引状態の変更、板情報更新イベントを受信しています。これらのメッセージは、それぞれ個別に処理されるべきものです。このため、MQL5にはさまざまなハンドラが用意されており、それぞれが独自の責任領域を持っています。OnTickは市場更新を担当します。OnTimerは定期的なタスクやバックグラウンドタスクを担当します。OnChartEventはGUIやユーザー操作への応答を担当します。ロジックがその目的に応じて分散されると、コードは雑然としたものではなくなります。各モジュールが自身の役割を果たし、隣接するモジュールに干渉しない、適切に設計されたシステムのようになります。

MQL5イベント

本記事では、「すべてを OnTick に実装する」モデルから、より成熟したイベントアーキテクチャへ移行する方法について見ていきます。定義済みハンドラとカスタムイベントの役割、さらにチャートに依存しないサービスについても取り上げます。また、実際の開発が始まる前の段階でアーキテクチャを破綻させてしまう典型的な誤りについても詳しく見ていきます。ここでの主な考え方はシンプルです。MQL5を本来の目的に沿って活用すれば、単なる自動売買ロボットだけでなく、本格的なアプリケーションシステムを構築することができます。


作者: MetaQuotes

 
バッファのないインジケータを使ったExpert Advisorでの作業は、おそらく例としては問題ないだろう。
 
//+------------------------------------------------------------------+
//| トレード機能|
//+------------------------------------------------------------------+
void OnTrade()
  {
   Sleep(0);
//---
  }
//+------------------------------------------------------------------+
| トレード・トランザクション機能|
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
   Sleep(0);
//---
  }
何のために?
 
            if(!cTrade.PositionClose(cPosition.Ticket()))
              {
               PrintFormat("Error close Sell position: %d", GetLastError());
               return;
              }
cTradeには エラー時の出力が含まれているようです。
 
fxsaber #:
バッファを使用しないインジケータを使用したExpert Advisorでの作業は、おそらく例としては問題ないでしょう。


例では、シンボルデータの厳密な更新が行われています(MQL_TESTERを使用するのが良いでしょう)。

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


しかし、イベントを通して計算されたシグナルとティックの関連性をチェックしません。これは本当に問題である。


非同期OrderSendによって弱めることはできますが、解決することはできません。したがって、このような例であっても、ChartEvent-eventでは、イベント生成が発生したティックのデータを追加で渡す必要があります。

 
MQL5プログラムの サービスタイプは過小評価されている。
 
素晴らしい例だ。