English
preview
プライスアクション分析ツールキットの開発(第49回):トレンド系、モメンタム系、ボラティリティ系インジケーターを1つのMQL5システムに統合する

プライスアクション分析ツールキットの開発(第49回):トレンド系、モメンタム系、ボラティリティ系インジケーターを1つのMQL5システムに統合する

MetaTrader 5 |
15 1
Christian Benjamin
Christian Benjamin

内容


はじめに

トレーダーの分析プロセスでは、テクニカル指標はトレンドの把握、モメンタムの測定、エントリー/エグジット候補の特定において中心的な役割を果たします。しかし、MetaTrader 5で複数のインジケーターを1つのチャートに適用する場合、通常は[インディケータ]メニューを何度も開き、各ツールを探して1つずつ手動で追加する必要があります。2〜3個であれば問題ありませんが、本格的なマルチインジケーター分析となるとすぐに煩雑になります。特に初心者は、インジケーターがどのサブフォルダにあるかを覚える必要があります。そして、同じ操作を何度も繰り返すので時間も無駄になります。インジケーターを追加するたびに作業が中断され、市場解釈への集中が妨げられてしまいます。

下図は、MetaTrader 5で各種インジケーターを探してアクセスする手順を示しています。

本記事では、こうした面倒な手動作業を自動化し、効率化するMQL5のエキスパートアドバイザー(EA)を紹介します。このEAは以下を実現します。

  • 主要インジケーターをチャート上に自動的に一覧表示する
  • 重要テクニカル指標をトレンド系、モメンタム系、ボラティリティ系に分類して統合表示する
  • インジケーター値をリアルタイムで解釈し、買い、売り、中立の総合バイアスを生成する
  • 矢印表示とカラーコードにより、市場センチメントを即座に視覚化する

ダッシュボードは常時更新され、複数のインジケーターウィンドウを開いたりテンプレートを切り替えたりする必要はありません。従来のようにサブウィンドウへ個別に表示する方法とは異なり、必要な分析要素を1つのインタラクティブなインターフェースに統合します。トレンド系のみ、モメンタム系のみ、ボラティリティ系のみといったプロファイル切り替えも可能ですし、すべて同時に表示することもできます。[Hide All]および[Show All]ボタンにより、ワンクリックでチャートを整理し、必要に応じて即座にフル表示へ戻すことができます。その結果、チャート自体がテクニカル分析のコントロールセンターになります。インジケーターフォルダを開き直したり、複雑な設定を再構築したりすることなく、生のインジケーターデータから実践的な判断へ数秒で移行することができます。以降のセクションでは、使用する各インジケーターの詳細、総合シグナルのロジック、そしてチャート上で実際に動作させるためのMQL5実装について、開発者視点で解説します。



インジケーターの理解

信頼性の高い市場環境の判断をおこなうためには、トレーダーは通常、複数のテクニカル指標に依存します。各インジケーターはそれぞれ異なる視点を提供します。あるものは現在のトレンドを明確にし、あるものは価格変動のスピードや強さを測定し、また別のものはボラティリティを定量化します。これら異なる視点を組み合わせることで、単一のツールに依存するよりも、より立体的で信頼性の高い市場分析が可能になります。Multi Indicator Handlerシステムでは、この多様な入力をトレンド系、モメンタム系、ボラティリティ系の3つの主要グループに整理しています。

トレンド系インジケーター

トレンド系インジケーターは、方向性分析の基盤となる要素です。市場が上昇傾向にあるのか、下降傾向にあるのか、あるいはレンジ相場なのかを明らかにし、多くの取引判断における前提条件を提供します。このシステムでは、EMA 50を中期トレンドを素早く検出するための反応性の高い移動平均として使用します。一方、EMA 200は長期的なバイアスフィルタとして機能します。価格がEMA 200の上に位置していれば強気環境、下に位置していれば弱気環境と判断します。

これらの移動平均を補完するのが「ADX 14」です。ADXはトレンドの方向ではなく強度を測定するインジケーターです。ADXが上昇し、特に一般的に注目される水準である25を上回る場合、市場が強いトレンド状態にあることを示唆します。

モメンタム系インジケーター

モメンタム系インジケーターは、トレンド系とは対照的に、価格変動の方向、スピード、勢いに焦点を当てます。このシステムでは、期間14と28の2種類のRSIを使用し、異なる時間軸における買われ過ぎと売られ過ぎの状態を検出します。MACD (12,26,9)は、2本のEMAの関係性から導かれるクロスオーバーベースのモメンタム分析を提供します。さらに、Stochastic Oscillator (5,3)は、現在価格を直近レンジ内の位置関係で測定し、転換点に対して非常に敏感に反応します。Momentum 14は価格の加速を絶対値で表現し、100を上回る場合は上昇圧力、100を下回る場合は下降圧力を示唆します。

CCI 20は統計的な平均からの乖離を検出し、相場の過熱や反転ポイントを示すことが多い指標です。Williams %R 14はストキャスティクスに類似した高速なオシレーターで、異なるスケールで買われ過ぎと売られ過ぎを示します。これらのモメンタム系ツールを組み合わせることで、現在のトレンドが継続しやすいのか、それとも反転の可能性が高いのかを判断できます。

ボラティリティ系インジケーター

最後のグループであるボラティリティ系インジケーターは、市場がどの程度変動しているかに焦点を当てます。ATR 14は設定期間における平均的な値幅を測定し、数値が上昇している場合は値動きのレンジが拡大し、市場活動が活発化していることを示します。Bollinger Bands (20,2)は、移動平均を中心に標準偏差ベースの上下バンドを描画します。価格が通常のレンジを超えて拡張する局面を視覚的に捉えることができ、こうした動きは反転やボラティリティ急拡大に先行することがよくあります。ボラティリティ系インジケーターは方向性そのものを直接予測するものではありませんが、リスク管理や最適なエントリータイミングの判断に不可欠なコンテキストを提供します。

このように分析上の役割ごとにインジケーターをグループ化することで、Multi Indicator Handlerには2つの大きな利点があります。第一に、トレーダーはその時点で解決したい問いに応じて、トレンド系、モメンタム系、ボラティリティ系のいずれかにフォーカスするプロファイルへ即座に切り替えることができます。第二に、総合バイアス算出時に重み付けを適用できる点です。トレンド系インジケーターが最も大きな影響力を持ち、モメンタム系が補助的役割を果たし、ボラティリティ系は最も小さいウェイトとなります。これは、方向性判断における実務上の重要度を反映しつつ、市場全体のダイナミクスも取り入れた設計思想です。

次の「戦略の概要」セクションでは、これらのインジケーターグループをシステムの投票ロジックと結び付けます。各インジケーターのシグナルがどのように統合され、最終的に買い、売り、中立という単一の推奨へ変換されるのか、そしてインタラクティブなダッシュボード設計によってその情報がどのように即座に意思決定へ活用できるのかを、開発者視点で解説します。



戦略の概要

インジケーターをトレンド系、モメンタム系、ボラティリティ系の各グループに整理した後のステップは、それぞれの個別シグナルを統合し、単一の売買シグナルへと変換することです。Multi Indicator Handlerでは、構造化された投票方式を採用しています。各インジケーターは事前定義された条件に基づき、「買い」「売り」「中立」のいずれかのバイアスを生成します。たとえば、EMAの傾きが上向きであれば「買い」票を追加し、RSIが30未満から反転すれば「買い」票を追加し、ストキャスティクスが買われ過ぎ圏に到達すれば「売り」票を追加するといった具合です。各投票には、インジケーターの属するグループに応じて重みが割り当てられます。トレンド系インジケーターは市場方向の基盤となるため、最も大きな影響力を持ちます。モメンタム系インジケーターは中程度の影響力を持ち、ボラティリティ系インジケーターは方向性を直接決定づけるのではなく補助的な文脈情報を提供する役割として、より小さな重みが与えられます。

システムはOnTimerイベントを使用してリアルタイムにシグナルを更新します。この方式はOnTickのみに依存する場合と比較して、特に低ボラティリティ環境においてより安定かつ制御しやすい更新を実現します。各更新サイクルでは、各インジケーターのバッファ(多くの場合は直近バーのみ)を読み取り、その役割に応じたシンプルなロジックで解釈します。各グループの加重シグナルを集計すると、EAは総合バイアスを算出し、買い、売り、中立のいずれか単一の方向性を示します。この結果はチャート上にカラーコード付きテキストで強調表示され、複数のサブウィンドウを確認することなく、市場センチメントを一目で把握できます。

Multi Indicator Handlerの重要な設計要素の1つが、プロファイル切り替え機能です。トレーダーは以下の4つのモードを切り替えることができます。[ALL]ではすべてのインジケーターを表示します。TRENDMOMENTUMVOLではそれぞれトレンド系、オシレーターおよびモメンタム系、ボラティリティ系インジケーターのみを表示します。この機能により、その時点で必要な分析タイプにフォーカスできます。たとえば、エントリー前にはMomentumプロファイルで勢いを確認し、ポジション保有中はTrendプロファイルで基調トレンドの維持を確認するといった使い分けが可能です。

さらに、ワークスペース制御機能として[Hide All]と[Show All]の2つのボタンを実装しています。[Hide All]をクリックすると、2つのコントロールボタンを除くすべてのインジケーターオブジェクトが即座に非表示となり、プライスアクションのみを確認できる状態になります。[Show All]をクリックすると、アクティブなプロファイルに応じてダッシュボードが再構築され、手動で再設定することなく完全な分析環境が復元されます。この動的なチャート制御は、ボラティリティが高い局面での視認性を向上させ、価格重視の判断とマルチインジケーター確認との間を迅速に切り替えることを可能にします。

この戦略ロジックは意図的にモジュール化されています。各インジケーターの解釈は独立して実装されているため、新しいツールの追加、シグナル条件の調整、重み付けの変更をおこなっても、ダッシュボード全体の機能を破壊することはありません。グループ投票方式により、単一の異常値が全体のバイアスを支配することを防ぎ、重み付けスキームもリスク許容度や取引スタイルに応じて柔軟に最適化できます。つまり、Multi Indicator Handlerは、実運用環境においてスピードと柔軟性を維持しながら、統合された市場センチメントを明確に提示する設計になっています。

次のセクション「MQL5での実装」では、この投票ロジック、プロファイル制御、チャートベースのインターフェースがどのようにコード化されているのかを解説します。設計思想から具体的な関数実装、イベント処理、オブジェクト生成まで、実装レベルで詳しく見ていきます。



MQL5での実装

Multi Indicator Handler EAは、MetaTrader 5上のチャートにおいて、分析エンジンとビジュアルインターフェースの両方の役割を担います。複数のテクニカル指標からデータを取得および解釈し、その結果をインタラクティブなダッシュボードとしてチャート上に直接表示します。このEAの設計上の大きな特長は、データ取得、シグナル解釈、グラフィカル表示という3つの役割を明確に分離している点です。

プログラムヘッダと入力パラメータ

ファイルの冒頭には、作者情報、バージョン番号、著作権表示、MQL5プロファイルへのリンクを含むヘッダが記述されます。その下に配置されるのが#propertyディレクティブです。これはコンパイル設定やメタデータを定義するもので、後にMetaTraderナビゲーター上に表示されます。続いて、2つの重要なinput変数を定義します。InpTFは内部計算に使用する時間足を指定します。デフォルトはPERIOD_CURRENTですが、たとえば1時間足チャートを表示しながら日足ロジックでインジケーターを計算する、といった多時間軸分析も可能です。InpUpdateMsは更新間隔をミリ秒単位で指定します。これにより、市場のティック頻度に依存せず、一定のリズムでダッシュボードを更新できます。

#property version   "1.0"
#property strict
input ENUM_TIMEFRAMES InpTF = PERIOD_CURRENT;
input int InpUpdateMs = 600;

#define SIG_NEUTRAL 0
#define SIG_BUY     1
#define SIG_SELL   -1

分析シグナルをプログラム上で扱うために、SIG_BUY、SIG_SELL、SIG_NEUTRALという定数を定義します。これらの整数値は、後に各インジケーターからの投票を合算・加重する際に使用されます。

列挙型によるプロファイル管理

ダッシュボードの4つの表示モードを定義するために、ProfileTypeと呼ばれる列挙型を定義します。値はALL、TREND、MOMENTUM、VOL です。これにより、実行中にモードを直感的に切り替えることができます。現在表示中のモードは、currentProfileで管理します。

enum ProfileType { PROFILE_ALL, PROFILE_TREND, PROFILE_MOMENTUM, PROFILE_VOL };
ProfileType currentProfile = PROFILE_ALL;

struct IndicatorSlot {
   string id;
   string name;
   int    handle;
   int    group;      // 0=Trend,1=Momentum,2=Volatility
   string btnName;
   string lblName;
};

生の整数値を直接使用するのではなく、列挙型を用いることでコードの可読性と自己文書性が向上します。コード中にPROFILE_TRENDと書かれていれば、開発者は即座に「トレンド系のみ表示している」と理解できます。

IndicatorSlotデータ構造体

すべてのインジケーターはIndicatorSlot構造体によって表現されます。この構造体は、5つの主要プロパティを1つにまとめています。

  • id:内部識別子
  •  name:「EMA 50」のような分かりやすい名前
  • handle:iCustomや標準関数で取得したハンドル
  • group:所属グループ(Trend、Momentum、Volatility
  • btnNamelblName:それぞれ対応するボタンオブジェクト名と表示ラベル名

これらを1つの構造体にまとめることで、上位レベルのコードは大幅に保守および拡張しやすくなります。各プロパティごとに別々の配列を用意する必要はなく、1つのスロットがそのインジケーターに関連するすべての情報を保持します。

値とシグナルを管理するグローバル配列

構造体に加えて、3つの動的配列が各インジケーターの状態を管理します。

  • values[]:各インジケーターのバッファから取得した最新の数値を保持します。
  • signal[]:その値を解釈した結果のシグナルを保持し、+1を買い、-1を売り、0を中立として表現します。
  • histValues[50][10]:最大50個のインジケーターについて直近10本分の値を保存する簡易履歴配列であり、各ラベルの横に表示されるスパークライン風のミニトレンド描画に利用されます。

IndicatorSlot slots[];
double values[];
int signals[];
double histValues[50][10];

この設計により、各スロットには複数の関連データセットが紐付けられ、それぞれを独立して更新しても他の要素に影響を与えません。

ユーティリティ関数

EAの最初のヘルパー関数であるObjExists ()は、安全対策として機能します。チャートオブジェクトを作成または削除する前に、そのオブジェクトが既に存在するかを確認します。これをおこなわない場合、既存オブジェクトを再作成しようとして表示の乱れが発生したり、意図せずスタイルが上書きされたりする可能性があります。

bool ObjExists(const string name) {
    return(ObjectFind(0,name)!=-1);
}

2つ目のヘルパー関数であるAddSlot ()は、インジケーター追加時に必要となる配列のリサイズおよび初期化処理を一括して担当します。デフォルトのシグナル状態を「中立」に設定し、スパークライン履歴をクリアし、ボタンおよびラベル用の一貫したオブジェクト名を割り当てます。

インジケーターハンドル生成の一元化

CreateIndicators ()関数は、EAに組み込むインジケーターを定義する中核部分です。

void CreateIndicators() {
   ArrayResize(slots,0);
   ArrayResize(values,0);
   ArrayResize(signals,0);

   // Trend
   AddSlot("EMA50","EMA 50", iMA(Symbol(),InpTF,50,0,MODE_EMA,PRICE_CLOSE),0);
   AddSlot("EMA200","EMA 200", iMA(Symbol(),InpTF,200,0,MODE_EMA,PRICE_CLOSE),0);
   AddSlot("ADX14","ADX 14", iADX(Symbol(),InpTF,14),0);

   // Momentum
   AddSlot("RSI14","RSI 14", iRSI(Symbol(),InpTF,14,PRICE_CLOSE),1);
   ...
   // Volatility
   AddSlot("ATR14","ATR 14", iATR(Symbol(),InpTF,14),2);
   AddSlot("BB20","Boll 20,2", iBands(Symbol(),InpTF,20,0,2.0,PRICE_CLOSE),2);
}

この関数は、まずすべての配列をクリアし、その後、各インジケーターごとにAddSlot ()を呼び出します。iMA、iADX、iRSI、iMACDなどのMQL5組み込み関数はインジケーターハンドルを生成します。ハンドルは数値IDであり、EAとMetaTrader内部の計算バッファを接続する役割を持ちます。

void AddSlot(string id,string name,int handle,int group) {
   int n=ArraySize(slots);
   ArrayResize(slots,n+1);
   ArrayResize(values,n+1);
   ArrayResize(signals,n+1);
   slots[n].id=id;
   slots[n].name=name;
   slots[n].handle=handle;
   slots[n].group=group;
   slots[n].btnName="btn_"+id;
   slots[n].lblName="lbl_"+id;
   signals[n]=SIG_NEUTRAL;
   values[n]=0.0;
   for(int j=0;j<10;j++) histValues[n][j]=0.0;
}

インジケーターは分析上の役割に応じて数値でグループ化されます。Trend = 0、Momentum = 1、Volatility = 2です。このグループ番号は、後にフィルタリング(プロファイル表示)やシグナル集計時の重み付けにおいて重要な役割を果たします。

チャートパネルの作成

BuildPanel ()関数は、ダッシュボードの描画全体を管理します。アクティブなプロファイルに含まれる各スロットに対して以下を作成します。

  • インジケーター名を表示するボタン
  • 値とシグナルバイアスを表示するラベル
  • 直近方向を示すミニチャートとしてのスパークライン

オブジェクトは、開始Yオフセットと一定の間隔を使って縦方向に配置されます。リストの最後には「Overall」バイアス用のラベルが描かれ、右上にはプロファイル切替用のprofileBtnが作成されます。

void BuildPanel(ProfileType filter) {
   int y=38, spacing=26;

   for(int i=0; i<ArraySize(slots); i++) {
      if(filter==PROFILE_ALL || slots[i].group==(int)filter) {
         ObjectCreate(0,slots[i].btnName,OBJ_BUTTON,0,0,0);
         ObjectSetString(0,slots[i].btnName,OBJPROP_TEXT,slots[i].name);

         ObjectCreate(0,slots[i].lblName,OBJ_LABEL,0,0,0);
         ObjectSetString(0,slots[i].lblName,OBJPROP_TEXT,"Val: -- Sig: NEUTRAL");

         string spName="spark_"+slots[i].id;
         ObjectCreate(0,spName,OBJ_TREND,0,0,0);

         y += spacing;
      }
   }
}

OBJ_BUTTONやOBJ_LABELといったチャートオブジェクトを使うことで、複数のインジケータウィンドウに依存せず、クリックに応答するインタラクティブなインターフェースを作成できます。また、スタイルの調整も容易で、視認性の高いダッシュボードを構築できます。

ダッシュボードの再構築

プロファイルモードを変更した場合やShow Allボタンが押された場合は、ShowDashboard()が実行されます。まず、[Hide]および[Show]ボタン以外のすべてのオブジェクトを削除します。次に、これら2つのコントロールボタンが存在するか確認し、存在しなければ再作成します。コントロールが確保された後、BuildPanel ()を呼び出して、選択されたプロファイル用のインジケーターUIを再描画します。

void ShowDashboard(ProfileType filter) {
   int total=ObjectsTotal(0,0,-1);
   for(int i=total-1;i>=0;i--) {
      string name=ObjectName(0,i);
      if(name!="btn_hide" && name!="btn_show")
         ObjectDelete(0,name);
   }
   // Ensure control buttons exist
   if(!ObjExists("btn_hide")) { /* create btn_hide */ }
   if(!ObjExists("btn_show")) { /* create btn_show */ }

   BuildPanel(filter);
}

この設計パターンにより、セッション途中でコアコントロールを失うリスクを回避しつつ、ダッシュボードの再構築を常にクリーンに保つことができます。

インジケーターごとのシグナル解釈

InterpretIndicator ()関数は、各インジケーターの数値データに意味を持たせ、売買シグナルへ変換する役割を担います。各インジケーターのハンドルを使い、CopyBuffer ()で最新の値を取得します。その後、インジケーター種類ごとに論理ルールを適用します。

  • EMA:直近2本のバー間の傾きで売買を判定する
  • ADX:25を超える値は強いトレンドの存在を示唆する
  • RSI:70以上で下降中は売り、30以下で上昇中は買いを示す
  • MACD:メインラインが0以上なら買い、0未満なら売りと判定する
  • ストキャスティクス、モメンタム、CCI、ウィリアムズ%R:それぞれ固有の閾値ルールに従って判定する
  • ATRとボリンジャーバンド:方向性の判定には直接使用せず、ボラティリティ情報としてのみ扱う

void InterpretIndicator(int i) {
   double buf[];
   signals[i]=SIG_NEUTRAL;

   if(slots[i].id=="EMA50"||slots[i].id=="EMA200") {
      if(CopyBuffer(slots[i].handle,0,0,2,buf)>=2) {
         double slope=buf[0]-buf[1];
         if(slope>0) signals[i]=SIG_BUY;
         else if(slope<0) signals[i]=SIG_SELL;
      }
   }
   ...
}

各インジケーターのシグナルが+1、-1、0として設定されます。

スロット更新とスパークライン描画

各タイマーサイクルで、UpdateSlotはインジケーターのシグナルを再計算し、履歴値をシフト、ラベルのテキストと色を更新し、DrawSparkline()を呼び出します。

void UpdateSlot(int i) {
   InterpretIndicator(i);
   for(int j=9;j>0;j--) histValues[i][j]=histValues[i][j-1];
   histValues[i][0]=values[i];

   string sigText=(signals[i]==SIG_BUY?"BUY":signals[i]==SIG_SELL?"SELL":"NEUTRAL");
   ObjectSetString(0,slots[i].lblName,OBJPROP_TEXT,
                   StringFormat("Val: %.5g  Sig: %s",values[i],sigText));

   DrawSparkline(i);
}

DrawSparkline ()は、最新値と最も古い値を時間軸上にマッピングして簡易OBJ_TRENDラインを描画します。最小限の表示ですが、直感的に方向性の把握が可能です。

総合バイアスの計算

ComputeOverall ()は、全スロットをループし、各シグナルにグループ重み(Trend × 3、Momentum × 2、Volatility × 1)を掛けて合計します。この合計の符号が総合バイアスを決定します。正なら買い、負なら売り、ゼロなら中立です。

int ComputeOverall() {
   int vote=0;
   for(int i=0;i<ArraySize(slots);i++) {
      int w=(slots[i].group==0?3:(slots[i].group==1?2:1));
      vote+=signals[i]*w;
   }
   if(vote>0) return SIG_BUY;
   if(vote<0) return SIG_SELL;
   return SIG_NEUTRAL;
}

DrawOverallSignal ()は「Overall 」ラベルのテキストを更新し、シグナルに応じて緑・赤・灰色を適用します。

プロファイル切替とコントロール

NextProfile ()は、プロファイルモードを順番に切り替え、切り替えごとにShowDashboard ()を呼び出します。HideEverythingExceptButtons ()は、[Hide]および[Show]ボタン以外をすべて削除し、クリックひとつで価格だけに集中できる状態を作ります。

ライフサイクルイベントとタイマー更新

OnInit ()では、インジケーターを作成し、初期ダッシュボードを構築、さらにミリ秒単位のタイマーを開始してOnTimer ()で定期更新をおこないます。

int OnInit() {
   CreateIndicators();
   ShowDashboard(currentProfile);
   EventSetMillisecondTimer((uint)MathMax(200,(int)InpUpdateMs));
   return INIT_SUCCEEDED;
}

OnDeinit ()では、タイマーを停止し、すべてのチャートオブジェクトを削除してEA削除後の環境をクリーンに保ちます。

OnTimer:更新ループ

関数は、タイマーが作動するたびに実行されます。アクティブプロファイルに属するすべてのインジケーターを更新し、総合バイアスを再計算、そして表示を必要に応じてリフレッシュします。

void OnTimer() {
   for(int i=0;i<ArraySize(slots);i++)
      if(currentProfile==PROFILE_ALL || slots[i].group==(int)currentProfile)
         UpdateSlot(i);

   int ov=ComputeOverall();
   DrawOverallSignal(ov);
}

タイマーをベースにしているため、市場からのティックがなくても定期的に更新され、常に一貫したレスポンスを保てます。

ユーザー操作への対応

OnChartEvent ()関数は、クリックなどのチャートイベントを監視します。プロファイルボタンがクリックされるとNextProfile()が呼ばれ、[Hide All]がクリックされるとHideEverythingExceptButtons()が実行されます。Show Allを押すとShowDashboard(currentProfile)でダッシュボードが再構築されます。

void OnChartEvent(..., const string &sparam) {
   if(sparam=="profileBtn") NextProfile();
   if(sparam=="btn_hide")   HideEverythingExceptButtons();
   if(sparam=="btn_show")   ShowDashboard(currentProfile);
}

OnTick:将来の拡張用

現状では空ですが、将来的にはOnTick()を拡張して、計算済みの総合バイアスに基づいた自動売買処理を追加することも可能です。たとえば、総合バイアス買いに変わったらポジションを建て、中立売りに変わったらクローズするといった運用です。

タスクを「作成」「解釈」「UI構築」「更新」に分離することで、EAはコードが明確で適応性が高く、効率的な構造になっています。インジケーターの追加、重み付けの変更、レイアウトの再設計も、基本ロジックを書き換えることなく容易におこなえます。



テストと結果

MetaTrader 5でMulti Indicator Handlerをコンパイルして任意のチャートにアタッチすると、インターフェースは瞬時に表示され、チャートに自然に統合されます。左上には[Hide All]と[Show All]とラベル付けされた小さなコントロールボタンがあり、ダッシュボードの表示管理に素早くアクセスできます。一方、右上には[Profile: ALL]と表示されたプロファイル選択ボタンがあり、異なるインジケーターグループに切り替えて分析に集中できます。これらのコントロールのすぐ下には、整然と縦に並んだダッシュボードが表示され、設定されたすべてのインジケーターがリストアップされます。各インジケーターは名前、リアルタイムの数値、解釈されたシグナルを表示し、買い、売り、中立のどのバイアスが優勢かを明確に確認できます。

視覚的挙動

各インジケーターは、選択された時間足とInpUpdateMsで設定されたタイマー間隔に応じて自動更新されます。色の変化は即座に反映され、緑は買いバイアス、赤は売りバイアス、灰色は中立を示します。また、各インジケーターの右側には小さなスパークラインが表示され、直近の値動きの上昇・下降を視覚的に確認できます。時間の経過とともに、モメンタム系インジケーターは赤と緑の間で動き、動きの遅いトレンド系インジケーターは安定した表示を保ち、実際の市場の安定性を反映します。

OnTimer ()内での更新プロセスの例は次の通りです。

for(int i=0;i<ArraySize(slots);i++) {
   if(currentProfile==PROFILE_ALL || slots[i].group==(int)currentProfile)
         UpdateSlot(i);
}

市場が常に動いている状態でも、このループにより表示は滑らかに保たれ、EAはオブジェクトをフリーズさせたりちらつかせたりすることなく効率的に更新を処理しています。

プロファイル切り替えの動作

[Profile]ボタンをクリックすると、ALL、TREND、MOMENTUM、VOLのモードが順に循環します。ダッシュボードは即座に再構築され、そのカテゴリに関連するインジケーターのみが表示されます。分析視点を切り替える際に特に有効で、たとえばトレンドを確認したい場合はTRENDを選択して移動平均やADXのみを表示し、エントリータイミングを確認したい場合はMOMENTUMを選択してRSI、MACD、ストキャスティクスを確認できます。

内部ロジックはシンプルです。

void NextProfile() {
   int tmp=(int)currentProfile;
   tmp++;
   if(tmp>3) tmp=0;
   currentProfile=(ProfileType)tmp;
   ShowDashboard(currentProfile);
}

この関数により、ワンクリックで全プロファイルを滑らかに循環させることができます。

非表示と表示のコントロール

[Hide All]ボタンをクリックすると、ダッシュボードが消え、2つのコントロールボタンだけが表示されます。これにより、価格の生情報を確認したり手動でトレンドラインを描いたりする際にチャートをすっきりさせることができます。[Show All]を押すと、以前と同じ場所に同じ色でダッシュボードが瞬時に復元されます。

void HideEverythingExceptButtons() {
   int total=ObjectsTotal(0,0,-1);
   for(int i=total-1;i>=0;i--) {
      string name=ObjectName(0,i);
      if(name!="btn_hide" && name!="btn_show")
         ObjectDelete(0,name);
   }
}

この仕組みは、プロファイル切替やチャート更新後でも一貫して動作し、オブジェクト管理ロジックの堅牢性を証明しています。

総合シグナルの動的表示

ダッシュボード下部のOverallラベルは、常に市場全体の総合バイアスを反映します。個々のインジケーターの色が変化すると、このラベルも赤や緑に変わり、トレーダーに多数のシグナルを簡潔に提示します。ここで用いられる重み付けスキーム(Trend × 3、Momentum × 2、Volatility × 1)により、短期オシレーターが一時的に異なる意見を出しても、強いトレンドが総合バイアスを支配する現実的な結果が得られます。実際には、このEAの出力は経験豊富なトレーダーの直感とよく一致します。たとえば、両方のEMAが上向きでADXが高い場合、RSIが揺れていてもOverallラベルは緑になります。

シグナル計算はComputeOverall()内で簡単に表現できます。

int w=(slots[i].group==0?3:(slots[i].group==1?2:1));
vote += signals[i]*w;

様々な銘柄や時間足でテストしたところ、この重み付けにより、過敏すぎず安定した信頼性のある総合シグナルが得られます。

パフォーマンスと応答性

タイマーベースの更新構造により、ティックの到着速度に関わらずEAは滑らかに動作します。300ミリ秒など高速更新でもCPU使用率は軽く、現在のプロファイルで表示されているインジケーターのみを処理するため、すべてのインジケーターを同時に更新する必要がありません。この選択的更新は、メインループ内でも確認できます。

if(currentProfile==PROFILE_ALL || slots[i].group==(int)currentProfile)
         UpdateSlot(i);

実際の使用では、Multi Indicator Handlerは作業効率を大幅に改善します。ダッシュボードが統合されているため、複数のチャートテンプレートを切り替える必要がなく、移動平均用テンプレートとオシレーター用テンプレートを別々に用意する必要もなく、1つのチャートでコンテキストを含むすべてのシグナルを確認できます。

エントリーの検討時には、MomentumからTrendに切り替えることで条件が戦略に沿っているか即座に確認できます。ライブ観察中には[Hide All]で画面をすっきりさせ、手動描画や価格確認に集中し、その後[Show All]で分析画面を瞬時に復元することが可能です。


結論

Multi Indicator Handler EAの開発は、MetaTrader 5で複数のインジケーターを効率的に管理するという、シンプルでありながら長年の課題から始まりました。従来のワークフローでは、各インジケーターをサブフォルダから手動でチャートに追加し、複数のチャートテンプレートを切り替え、別々のインジケータウィンドウを確認する必要がありました。この作業はエラーが起きやすく、時間がかかり、市場が急速に動く状況では精神的な負担も大きいものでした。  

このEAでは、選択したすべてのインジケーターを1つのインタラクティブなダッシュボードに統合することで、これらの課題に体系的に対応しました。その結果、単にインジケーターの生データを表示するだけでなく、そのデータを買い、売り、中立の実行可能なシグナルに解釈し、論理的な重み付けシステムで集計し、トレーダーが自在に操作できる視覚的に整ったレイアウトで提示するツールが完成しました。

最終的な考察

テクニカル分析は裁量取引や半自動取引の中核をなす手法です。分析プロセスがいかに効率的で分かりやすく、一貫性があるかによって、意思決定のスピードと精度は大きく向上します。Multi Indicator Handlerは、生のインジケーター出力とトレーダー向けの視覚的提示の橋渡しをおこなうことで、MetaTrader 5内で統合的なチャート分析コントロールセンターを提供します。ライブ取引の補助として使用することも、カスタマイズ可能なダッシュボードを構築するためのMQL5コーディングテンプレートとして活用することも可能です。その明確な設計、論理的なシグナル重み付け、ユーザー中心の操作性の組み合わせは、学ぶ価値があり、模倣し、発展させる価値のあるモデルと言えます。

MQL5開発者にとっては、設計を丁寧に構造化し、インターフェースの細部に注意を払うことで、実際の市場環境でも信頼性高く動作する堅牢なツールを生み出せることの例となります。トレーダーにとっては、複数の市場シグナルを単一の明確な方向性に統合する複雑な作業を技術によって簡素化できることを示しています。本記事で紹介した「はじめに」からインジケーターの理解、戦略の概要、実装、結果、そしてこの結論までの流れを追うことで、EAを自身のチャートですぐに動かすことができるだけでなく、その内部動作を正確に理解し、独自の戦略やワークフローに合わせて改造する道が開かれます。

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/20168

添付されたファイル |
最後のコメント | ディスカッションに移動 (1)
syed hanan
syed hanan | 7 11月 2025 において 16:55
実に実用的なソリューションだ。インジケーターのセットアップを自動化することで、多くの時間を節約し、実際の取引判断に集中することができます。
MQL5における二変量コピュラ(第2回):MQL5でのアルキメデスコピュラの実装 MQL5における二変量コピュラ(第2回):MQL5でのアルキメデスコピュラの実装
連載第2回では、二変量アルキメデスコピュラの特性と、それらをMQL5で実装する方法について解説します。また、コピュラを活用したシンプルなペアトレード戦略の開発についても取り上げます。
取引戦略の開発:バタフライオシレーター法 取引戦略の開発:バタフライオシレーター法
魅力的な数学概念であるバタフライ曲線を、実践的な取引ツールへと応用する方法を紹介します。バタフライオシレーターを構築し、それを基盤とした基本的な取引戦略を開発します。この戦略は、オシレーター特有の周期的シグナルと移動平均による従来型のトレンド確認を効果的に組み合わせることで、潜在的な市場エントリーポイントを特定するための体系的なアプローチを実現します。
MQL5における市場ポジショニング戦略の体系(第2回): Nvidia向けマルチパターンのビット単位学習 MQL5における市場ポジショニング戦略の体系(第2回): Nvidia向けマルチパターンのビット単位学習
管理可能なテスト期間において、特定の資産を特定の取引方向で検証する市場ポジショニングに関する新連載を継続します。前回の記事では、Nvidia Corp (NVDA)の株を対象に、RSIとDeMarkerオシレーターの組み合わせから5つのシグナルパターンを検証しました。本記事では残りの5パターンを取り上げ、さらに複数パターンの組み合わせにも踏み込みます。これには、10パターンすべての自由な組み合わせや、特定のペアのみを組み合わせる特殊パターンも含まれます。
オンチャートUIを使用したリスクベースの取引執行EA(第1回):ユーザーインターフェースの設計 オンチャートUIを使用したリスクベースの取引執行EA(第1回):ユーザーインターフェースの設計
MQL5でリスクベース取引執行エキスパートアドバイザー(EA)用の、クリーンでプロフェッショナルなオンチャートコントロールパネルを構築する方法を解説します。このステップバイステップガイドでは、トレーダーが取引パラメータを入力し、ロットサイズを計算し、自動発注に備えることができる機能的なGUIの設計方法を説明します。