English Русский Deutsch
preview
初心者からエキスパートへ:MQL5を使ったアニメーションニュース見出し(III)-インジケーターインサイト

初心者からエキスパートへ:MQL5を使ったアニメーションニュース見出し(III)-インジケーターインサイト

MetaTrader 5 |
105 0
Clemence Benjamin
Clemence Benjamin

内容

  1. はじめに
  2. 概念
  3. 実装
  4. テスト
  5. 結論
  6. 重要な学び
  7. 添付ファイル


はじめに

本日は、新しい「インジケーターインサイトレーン」をご紹介します。これは、これまでのエピソード(IおよびII)で紹介したツールを補完する、ルールベースのチャート上機能です。これまででお気づきかもしれませんが、核心的な目的は明確です。すなわち、MetaTrader 5のターミナル画面を最適化し、必要な取引リソースにコンパクトかつ効率的にアクセスできるよう、チャート上で直接操作可能にすることです。

従来、多くのオシレーターはメインチャートの下に別ウィンドウで表示されるため、作業スペースが分断され、貴重な表示スペースを消費してしまいます。インジケーターを多く使うほどチャートが圧迫され、価格動向を明確に確認する能力が制限されます。

これに対処するために、CCanvasクラスを活用して、チャート上にインジケーターインサイトレーンを統合し、作業効率を改善します。これにより、MQL5のAPIを通じてインジケーターデータを取得して処理し、有益なシグナルをインターフェースを乱すことなく表示できるようになります。視覚的な例も用意しており、複数のインジケーターサブウィンドウがメインチャート表示をどのように圧縮するかを示しています。

チャートスペースを削減する複数のインジケーターウィンドウ

この図は、インジケーターウィンドウがチャートにどのような影響を与えるかを示しています。

次のセクションでは、このアプローチの背後にあるコンセプトを分解して解説し、その後、実装方法に進みます。


概念

今回の計画では、デフォルトで単一のスクロールレーンを導入し、4つの主要なオシレーターからのインサイトを表示する予定です。これらのインジケーターは、トレーダーが意思決定をおこなう上で重要なシグナルを提供します。コンパクトな設計により、チャートの乱雑さを減らし、よりクリアで集中した表示を実現します。もちろん、より詳細な情報を希望するユーザー向けに、各インジケーター専用のレーンにインサイトを展開するオプションも用意しています。

これらのインジケーターを深く理解することは、堅実な取引戦略を支える仕組みを正しく評価するうえで不可欠です。この設定を完了すれば、ニュース見出し、経済指標カレンダー、リアルタイムのインジケーターインサイトをすべて、MetaTrader 5のチャート上の1つのスマートインターフェースに統合して活用できるようになります。

将来のアップデートとして、私は「アナリストインサイトレーン」の追加も検討しています。これは、専門アナリストの公開情報からキュレーションされたインサイトを表示する専用スペースです。APIを通じて情報を取得することで、専門家のコメントや戦略的視点を直接チャート上に反映させ、トレーダーにとって意思決定に直結する強力な表示を実現できます。

ここで、初心者の方にも経験者の方にも参考になるよう、統合する4つのオシレーターそれぞれが取引でどのように一般的に使用されているか、そしてそれらのインサイトを組み合わせることでリアルタイムの意思決定をどのように大幅に向上させられるかを確認してみましょう。

取引におけるRSI、CCI、ストキャスティクス、MACDの理解

相対力指数(RSI: Relative Strength Index)

RSIは、1978年にJ.ウェルズ・ワイルダーによって開発されたモメンタムオシレーターで、価格変動のスピードと変化率を測定します。主に、買われ過ぎや売られ過ぎの状態やトレンド転換の可能性を識別するために使われます。RSIは特にレンジ相場で効果的で、価格がサポートとレジスタンスの間で上下する状況で有効です。

計算方法:

RSIは通常14期間で計算されますが、トレーダーの判断で短期または長期に調整可能です。計算式は次のとおりです。

ここで、RS(Relative Strength、相対力)は指定期間における平均利益を平均損失で割った値です。平均利益と平均損失は、指定期間の価格変動に基づいて算出されます。

重要レベルと解釈  

RSIは0~100の範囲で変動し、50が中立値です。

  • RSIが70を上回る場合は買われ過ぎと見なされ、価格の下落調整が予想されます。
  • RSIが30を下回る場合は売られ過ぎと見なされ、価格の反発が期待されます。
  • RSIが50を上回る場合は強気モメンタム、50を下回る場合は弱気モメンタムを示します。

相対力指数(RSI)

相対力指数(RSI: Relative Strength Index)

RSIに基づく取引戦略  

  • 買われ過ぎ/売られ過ぎのシグナル:RSIが30を上回ると、資産が売られ過ぎ領域から脱した可能性を示し、買いのシグナルとなることがあります。逆にRSIが70を下回ると、資産が買われ過ぎ状態から脱した可能性を示し、売りのシグナルとなることがあります。
  • ダイバージェンス:RSIは価格との乖離(ダイバージェンス)によって、潜在的なトレンド転換を示すことがあります。たとえば、価格が新高値を更新してもRSIが前回の高値を上回らない場合は弱気ダイバージェンス、価格が新安値を更新してもRSIが前回の安値を下回らない場合は強気ダイバージェンスとなります。
  • トレンドの確認:上昇トレンド中はRSIが概ね50以上を維持し、下降トレンド中は50以下を維持する傾向があります。これによりトレンド方向を確認できます。
  • Failure Swing:ワイルダーは「failure swings」を、市場の反転を示す強いサインとして特定しました。たとえば、RSIが76まで上昇した後に70を上抜けることに失敗し、その後72を下回る場合、反転の可能性を示唆します。

実例

RSIが売られ過ぎ領域(30未満)から30を上抜けた場合、買いのチャンスを示唆する可能性があります。特に、移動平均線のクロスオーバーなど、他の強気のシグナルと組み合わさっている場合は有効性が高まります。逆に、RSIが70を下抜けた場合は、資産が買われ過ぎ状態から調整に入る可能性を示し、売りのサインとなることがあります。

商品チャネル指数(CCI: Commodity Channel Index)

CCIは、もともとコモディティ市場におけるサイクルの転換点を特定するために設計されたモメンタムオシレーターですが、現在では株式や為替など幅広い資産クラスで利用されています。この指標は、一定期間における平均価格水準に対して現在の価格水準を測定することで、買われ過ぎや売られ過ぎの状態やトレンドの強さを把握するのに役立ちます。CCIは1980年にドナルド・ランバートによって考案されました。

計算方法:

CCIは一般的に20期間で計算されますが、設定は調整可能です。計算式は次のとおりです。

ここで

Typical Price = (高値 + 安値 + 終値) / 3
SMA = 指定期間のTypical Priceの移動平均
Mean Deviation = Typical PriceとSMAとの差の絶対値の平均

結果の読みやすさを目的に、スケーリング係数として0.015が使用されます。

重要レベルと解釈  

  • CCIはゼロを中心に推移し、上限や下限はありません。
  • +100を超えるレベルは買われ過ぎを示唆し、売りのシグナルとなる可能性があります。
  • -100を下回るレベルは売られ過ぎを示唆し、買いのシグナルとなる可能性があります。
  • 強いトレンド下では、CCIが+200や-200を超えることもあり、極端なモメンタムを示します。

Commodity Channel Index (CCI)

Commodity Channel Index (CCI)

ただし、CCIが-100を下回ったり+100を上回ったりした瞬間が、必ずしもすぐにエントリーの好機を意味するわけではありません。多くの場合、他のインジケーターやプライスアクションの分析による確認が不可欠です。たとえば、前述の例では、CCIが-100を下回った後も価格はさらに数ピップス下落を続け、その後にようやく反転しました。

このような挙動はCCIに限らず、ストキャスティクスなど他のオシレーターでもよく見られます。特に、あらかじめ定義された閾値付近では同様のパターンが起こりやすいのです。クロスオーバーのシグナル自体は有用ですが、それだけに依存するとエントリーが早すぎる場合があります。より信頼性の高いアプローチは、オシレーターのシグナルと他のテクニカルな確認手法を組み合わせて意思決定を強化することです。

CCIに基づく取引戦略  

  • 買われ過ぎ/売られ過ぎのシグナル:CCIが+100を超えた場合、売りの可能性を示唆します。CCIが-100を下回った場合、買いの可能性を示唆します。多くのトレーダーは、CCIが再び+100を下回る、または-100を上回る動きを確認してからエントリーを検討します。
  • トレンド強度の把握:CCIが持続的に+100を上回る場合は強い上昇トレンドを示します。CCIが持続的に-100を下回る場合は強い下降トレンドを示します。これにより、トレーダーはトレンドに長く留まる判断ができます。
  • ダイバージェンス:RSIと同様、CCIにおいても価格が高値を更新する一方でCCIが高値を切り下げる場合など、モメンタムの弱まりを示唆することがあります。これは反転のシグナルとなる可能性があります。
  • クロスオーバー:CCIがゼロラインを上抜ける場合、強気のモメンタムを示唆します。CCIがゼロラインを下抜ける場合、弱気のモメンタムを示唆します。

実例

たとえばCCIが+100を上抜けた場合、強い上昇トレンドのシグナルとなります。ただし、その後CCIが低下し、再び+100を下回ると反転の可能性を示唆します。同様に、CCIが-100を下回った場合は買いの好機となる可能性がありますが、その後CCIが上昇して-100を上抜ける動きが確認できれば、より信頼度の高いシグナルとなります。

ストキャスティクス

ストキャスティクスは、モメンタム系のインジケーターであり、証券の終値を直近の取引レンジと比較することで、市場における転換点の可能性を示すよう設計されています。一般的には14期間で設定され、買われ過ぎや売られ過ぎの状態を見極めるのに特に有効です。価格変化のスピードに注目することで、実際のトレンド転換が起こる前にシグナルを発することを目的としています。

この強力なツールは1950年代にGeorge Lane(英語)によって導入され、その原則は現在もなお、市場モメンタムの変化を早期に察知しようとするトレーダーを導いています。

計算方法:

ストキャスティクスは%K(高速)と%D(低速)の2本のラインで構成されます。%Kラインは次のように計算されます。

ここで

Close = 現在の終値
Lowest Low = 指定期間内の最安値
Highest High = 指定期間内の最高値

%Dは%Kの移動平均(通常は3期間の単純移動平均)であり、%Kの変動を平滑化する役割を果たします。

重要レベルと解釈  

  • ストキャスティクスは0〜100の範囲で推移します。
  • 80以上の数値は買われ過ぎとみなされ、売りの可能性を示唆します。
  • 20以下の数値は売られ過ぎとみなされ、買いの可能性を示唆します。
  • %Dラインはシグナルラインとして機能し、%Kと%Dのクロスオーバーによって取引シグナルが発生します。

ストキャスティクス

ストキャスティクス

ストキャスティクスに基づく取引戦略  

  • 買われ過ぎ/売られ過ぎのシグナル:%Kが20を上抜けた場合、資産が売られ過ぎ状態から抜け出していると考えられ、買いシグナルとなる可能性があります。逆に、%Kが80を下回った場合は、買われ過ぎ状態からの調整を示し、売りシグナルとなる可能性があります。
  • クロスオーバー:強気のシグナルは、%Kが%Dを上抜ける場合に発生します。特に20以下の売られ過ぎ領域でこのクロスが起きると、買いシグナルとなる可能性があります。逆に、弱気のシグナルは、%Kが%Dを下抜ける場合に発生します。特に80以上の買われ過ぎ領域でこのクロスが起きると、売りシグナルとなる可能性があります。
  • ダイバージェンス:ストキャスティクスは、ダイバージェンスによっても反転の可能性を示すことがあります。たとえば、価格が安値を更新しているにもかかわらず%Kが安値を切り上げている場合、下降モメンタムの弱まりを示唆する強気のダイバージェンスと解釈されます。
  • トレンドの確認:上昇トレンドでは、ストキャスティクスは一般的に50を上回って推移することが期待されます。下降トレンドでは、ストキャスティクスは50を下回って推移することが多く、トレンド方向の確認に利用することができます。

実例

%Kが%Dを上抜け、両方が20を下回っている場合、それは強い買いシグナルとなる可能性があります。特に、レジスタンスレベルを上抜けるといった他の強気シグナルと重なる場合、その信頼度はさらに高まります。逆に、%Kが%Dを下抜け、両方が80を上回っている場合、買われ過ぎ状態からの反転を示唆し、売りシグナルとなる可能性があります。

MACD

MACD (Moving Average Convergence/Divergence)は、広く利用されているトレンドフォロー型のモメンタム指標であり、2本の指数平滑移動平均(EMA)の差を分析することで、短期と長期の価格トレンドを比較します。これにより、市場モメンタムの変化やトレンド方向、エントリーやイグジットの可能性を把握することができ、多くのテクニカル取引システムにおいて重要な役割を果たしています。

MACDは1970年代後半にGerald B. Appelによって開発され、今日に至るまで、トレーダーがトレンドの強さや反転の可能性を見極めるうえで最も信頼されるツールのひとつとなっています。

計算方法:

MACDラインは、12期間のEMAから26期間のEMAを引いて算出されます。

このMACDラインの9期間EMAが「シグナルライン」として描かれます。さらに、MACDラインとシグナルラインとの差は「ヒストグラム」として表示され、モメンタムの強弱を視覚的に示します。

重要レベルと解釈  

  • MACDはゼロを中心に推移し、上限や下限はありません。
  • MACDが正の値であれば強気のモメンタムを示し、負の値であれば弱気のモメンタムを示します。
  • MACDラインとシグナルラインのクロスオーバーは取引シグナルを提供します。MACDがシグナルラインを上抜けた場合は強気シグナル、下抜けた場合は弱気シグナルです。
  • また、ゼロラインのクロスも重要です。MACDがゼロを上抜けた場合は上昇トレンドの可能性を、ゼロを下抜けた場合は下降トレンドの可能性を示唆します。

Moving Average Convergence Divergence

MACD(移動平均線収束拡散)

MACDに基づく取引戦略  

  • クロスオーバー:MACDラインがシグナルラインを上抜けると強気モメンタムを示す買いシグナル、下抜けると弱気モメンタムを示す売りシグナルとなります。
  • ゼロラインのクロスオーバー:MACDがゼロを上抜けると上昇トレンドの可能性を、下抜けると下降トレンドの可能性を示し、トレンドの確認に役立ちます。
  • ヒストグラム分析:ヒストグラムの大きさはモメンタムの強さを示します。ヒストグラムが拡大していればモメンタムが強まっていることを示し、縮小していればモメンタムの減速を示し、反転の可能性を示唆します。
  • ダイバージェンス:MACDはダイバージェンスによって反転の可能性を示すこともあります。たとえば、価格が安値を更新しているのにMACDが安値を切り上げている場合、下降モメンタムが弱まっていると考えられ、強気のダイバージェンスとして解釈されます。

実例

MACDラインがシグナルラインを上抜け、ヒストグラムが拡大している場合は、特に重要なレジスタンスラインを上抜けるなど他の強気シグナルを伴えば、買いの可能性を示唆します。逆に、MACDラインがシグナルラインを下抜け、ヒストグラムが縮小している場合は、売りの可能性を示し、反転を示唆することがあります。

インジケーター用途重要レベル主なシグナル最適な適用場面
RSIモメンタムを測定し、買われ過ぎ・売られ過ぎを特定>70(買われ過ぎ)、<30(売られ過ぎ)、50(中間点)30を上抜けた場合(買い)、70を下抜けた場合(売り)、ダイバージェンス、failure swingレンジ相場
CCIサイクル転換とトレンド強度を把握>+100(買われ過ぎ)、<-100(売られ過ぎ)、ゼロライン+100を下抜けた場合(売り)、-100を上抜けた場合(買い)、ダイバージェンス、ゼロラインクロストレンド相場
ストキャスティクスモメンタムを測定し、反転の可能性を特定>80(買われ過ぎ)、<20(売られ過ぎ)%K/%Dクロスオーバー(20未満で%Kが%Dを上抜けると買い、80を超えて下抜けると売り)、ダイバージェンスレンジ・トレンド両方の相場
MACDトレンドフォロー型モメンタム指標ゼロライン、シグナルラインクロスオーバーMACDラインがシグナルラインを上抜けると買い、下抜けると売り、ゼロライン・クロス、ヒストグラム変化トレンド相場
最もよく利用されるインジケーターのいくつかについて、より深い洞察を探ってきました。次のステップでは、これらの概念がどのようにコードで実装されているのかを詳しく見ていきます。



実装

アクティブチャートに表示されているシンボルと時間足の組み込みインジケーターの値は、三段階の「ハンドル → バッファ → 解放」の手順で取得できます。まず、関連するMQL5関数(iRSIやiMACDなど)を呼び出してインジケーターハンドルを作成します。このとき、銘柄や時間足のパラメータは省略し、チャートのコンテキストを使用します。次に、そのハンドルに対してCopyBufferを呼び出すことで、インジケーターの出力バッファから最新値を取得します。最後にIndicatorReleaseを呼び出して、ハンドルおよび関連リソースを解放します。この手順をヘルパー関数内にカプセル化することで、RSI、MACD、ストキャスティクス、CCIなどの標準インジケーターを追加のチャートウィンドウを生成せずに効率的かつオンデマンドで取得できます。

以下では、News Headline EAにインジケーターインサイト機能を統合する手順を示し、MQL5で組み込みインジケーターを扱う実践的な方法を解説します。

EAへのインジケーターインサイトの統合

1. ユーザー入力宣言

InpSeparateLanesInpInsightSpeedを他の入力項目と並べて公開することで、トレーダーが統合インジケーター表示を1本のスクロールレーンにするか、個別に表示するかを選択できます。

input bool   InpSeparateLanes    = false; // combined vs separate insights
input int    InpInsightSpeed     = 3;     // scroll speed for insight text

2. グローバルとキャンバスハンドル

統合表示用と個別表示用の両方のキャンバスをあらかじめ宣言します。各キャンバスのスクロールオフセットがアニメーションを制御します。MQL5では、キャンバスハンドルはタイマーコールバック間で有効である必要があるため、グローバル変数として保持します。チャート幅やリロード時刻などの状態変数と一緒に整理することで、すべてのティック間状態を一箇所で管理できます。

//--- Globals ---------------------------------------------
CCanvas   combinedCanvas;        // holds all four insights in one lane
CCanvas   rsiCanvas, stochCanvas, macdCanvas, cciCanvas;  // separate lanes
int       offCombined, offRSI, offStoch, offMACD, offCCI;

3. インジケーター計算用ヘルパー関数

各ヘルパー関数は「ハンドル → バッファ → 解放」のパターンに従います。これにより、各ティックごとにインジケーターハンドルを1回だけ生成し、最新値を取得した後に即座にシステムリソースを解放できます。また、フォーマット処理を集中させることで、メイン描画ループは簡潔かつ高速に保たれます。さらに、4つのシグナルを統合レーン用に1つの文字列にまとめることで、描画ロジックを簡素化できます。

//+------------------------------------------------------------------+
//| Compute indicator insights                                       |
//+------------------------------------------------------------------+
string ComputeRSIInsight()
{
  int h=iRSI(NULL,PERIOD_CURRENT,14,PRICE_CLOSE);
  if(h==INVALID_HANDLE) return "["+Symbol()+"] RSI err";
  double b[]; CopyBuffer(h,0,1,1,b); IndicatorRelease(h);
  double v=b[0]; string s=DoubleToString(v,1);
  string m=v<30?"Oversold("+s+")":v>70?"Overbought("+s+")":"Neutral("+s+")";
  return "["+Symbol()+"] RSI:"+m;
}

string ComputeStochInsight()
{
  int h=iStochastic(NULL,PERIOD_CURRENT,14,3,3,MODE_SMA,STO_LOWHIGH);
  if(h==INVALID_HANDLE) return "["+Symbol()+"] Stoch err";
  double b[]; CopyBuffer(h,0,1,1,b); IndicatorRelease(h);
  double v=b[0]; string s=DoubleToString(v,1);
  string m=v<20?"Oversold("+s+")":v>80?"Overbought("+s+")":"Neutral("+s+")";
  return "["+Symbol()+"] Stoch:"+m;
}

string ComputeMACDInsight()
{
  int h=iMACD(NULL,PERIOD_CURRENT,12,26,9,PRICE_CLOSE);
  if(h==INVALID_HANDLE) return "["+Symbol()+"] MACD err";
  double m[],g[]; CopyBuffer(h,0,1,1,m); CopyBuffer(h,1,1,1,g); IndicatorRelease(h);
  double d=m[0]-g[0]; string s=DoubleToString(d,2);
  string m2=d>0?"Bull("+s+")":d<0?"Bear("+s+")":"Neu(0)";
  return "["+Symbol()+"] MACD:"+m2;
}

string ComputeCCIInsight()
{
  int h=iCCI(NULL,PERIOD_CURRENT,14,PRICE_TYPICAL);
  if(h==INVALID_HANDLE) return "["+Symbol()+"] CCI err";
  double b[]; CopyBuffer(h,0,1,1,b); IndicatorRelease(h);
  double v=b[0]; string s=DoubleToString(v,1);
  string m=v<-100?"Oversold("+s+")":v>100?"Overbought("+s+")":"Neutral("+s+")";
  return "["+Symbol()+"] CCI:"+m;
}

string ComputeAllInsights()
{
  return ComputeRSIInsight() + "  |  " +
         ComputeStochInsight() + "  |  " +
         ComputeMACDInsight() + "  |  " +
         ComputeCCIInsight();
}

4. OnInitでのキャンバス作成

OnInit内では、新しい表示レーンを設定します。個別レーンモードでは、4つのキャンバスを初期化します。統合レーンモードでは、1つのキャンバスのみを初期化し、固定のラベル「Indicator Insights:」を付加します。初回のUpdateを呼び出すことで、最初のタイマーティックが発生する前でも、トレーダーがコンテキストを確認できるようにします。これは、大規模なEAをロードした際の重要なユーザビリティ上の配慮です。

int OnInit()
{
  // … existing canvases for events & news …

  if(InpSeparateLanes)
  {
    rsiCanvas.CreateBitmapLabel("RsiC",0,0,canvW,lineH);
    stochCanvas.CreateBitmapLabel("StoC",0,0,canvW,lineH);
    macdCanvas.CreateBitmapLabel("MacC",0,0,canvW,lineH);
    cciCanvas.CreateBitmapLabel("CciC",0,0,canvW,lineH);
    // set transparency…
  }
  else
  {
    combinedCanvas.CreateBitmapLabel("AllC",0,0,canvW,lineH);
    combinedCanvas.TransparentLevelSet(120);
    // static label at x=5: “Indicator Insights:”
    combinedCanvas.FontSizeSet(-120);
    combinedCanvas.TextOut(5, (lineH-combinedCanvas.TextHeight("Indicator Insights:"))/2,
                           "Indicator Insights:", XRGB(200,200,255), ALIGN_LEFT);
    combinedCanvas.Update(true);
  }

  // … remainder of OnInit …
}

5. OnTimerでのスクロール処理

ここがEAの心臓部です。各タイマーティックごとに、キャンバスの位置を再設定し、データを再読み込みし、チャートのサイズ変更にも対応したうえで、各レーン(イベント、ニュース、インジケーターいずれも)の計算と描画サイクルを実行します。すべての更新呼び出しを最後にまとめて行うことで、ちらつきを最小限に抑え、複数レイヤー間のスクロールを完全に同期させることができます。オフセット処理をラップするヘルパー関数を使うことで、コードをDRY(Don't Repeat Yourself、繰り返しを避ける)に保っています。

//+------------------------------------------------------------------+
//| OnTimer: redraw                                                  |
//+------------------------------------------------------------------+
void OnTimer()
{
  // reposition canvases
  SetCanvas("EvC",InpPositionTop,InpTopOffset);
  SetCanvas("NwC",InpPositionTop,InpTopOffset+3*lineH);

  if(InpSeparateLanes)
  {
    SetCanvas("RsiC",InpPositionTop,InpTopOffset+4*lineH);
    SetCanvas("StoC",InpPositionTop,InpTopOffset+5*lineH);
    SetCanvas("MacC",InpPositionTop,InpTopOffset+6*lineH);
    SetCanvas("CciC",InpPositionTop,InpTopOffset+7*lineH);
  }
  else
  {
    SetCanvas("AllC",InpPositionTop,InpTopOffset+4*lineH);
  }

  // refresh data
  ReloadEvents();
  FetchAlphaVantageNews();

  // resize if needed
  int wNew=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
  if(wNew!=canvW)
  {
    canvW=wNew;
    ObjectSetInteger(0,"EvC",OBJPROP_WIDTH,canvW);
    ObjectSetInteger(0,"NwC",OBJPROP_WIDTH,canvW);
    if(InpSeparateLanes)
    {
      ObjectSetInteger(0,"RsiC",OBJPROP_WIDTH,canvW);
      ObjectSetInteger(0,"StoC",OBJPROP_WIDTH,canvW);
      ObjectSetInteger(0,"MacC",OBJPROP_WIDTH,canvW);
      ObjectSetInteger(0,"CciC",OBJPROP_WIDTH,canvW);
    }
    else
    {
      ObjectSetInteger(0,"AllC",OBJPROP_WIDTH,canvW);
    }
  }

  // draw events
  DrawAll();

  // draw news
  newsCanvas.Erase(ARGB(170,0,0,0));
  string nt = totalNews>0?newsHeadlines[0]:placeholder;
  newsCanvas.TextOut(offNews,(lineH-newsCanvas.TextHeight(nt))/2,
                     nt,XRGB(255,255,255),ALIGN_LEFT);
  offNews-=InpNewsSpeed;
  if(offNews+newsCanvas.TextWidth(nt)<-20) offNews=canvW;

  // draw insights
  if(InpSeparateLanes)
  {
    string t;
    t=ComputeRSIInsight();
    rsiCanvas.Erase(ARGB(120,0,0,0));
    rsiCanvas.TextOut(offRSI,(lineH-rsiCanvas.TextHeight(t))/2,
                      t,XRGB(180,220,255),ALIGN_LEFT);
    offRSI-=InpInsightSpeed;
    if(offRSI+rsiCanvas.TextWidth(t)<-20) offRSI=canvW;

    t=ComputeStochInsight();
    stochCanvas.Erase(ARGB(120,0,0,0));
    stochCanvas.TextOut(offStoch,(lineH-stochCanvas.TextHeight(t))/2,
                        t,XRGB(180,220,255),ALIGN_LEFT);
    offStoch-=InpInsightSpeed;
    if(offStoch+stochCanvas.TextWidth(t)<-20) offStoch=canvW;

    t=ComputeMACDInsight();
    macdCanvas.Erase(ARGB(120,0,0,0));
    macdCanvas.TextOut(offMACD,(lineH-macdCanvas.TextHeight(t))/2,
                       t,XRGB(180,220,255),ALIGN_LEFT);
    offMACD-=InpInsightSpeed;
    if(offMACD+macdCanvas.TextWidth(t)<-20) offMACD=canvW;

    t=ComputeCCIInsight();
    cciCanvas.Erase(ARGB(120,0,0,0));
    cciCanvas.TextOut(offCCI,(lineH-cciCanvas.TextHeight(t))/2,
                      t,XRGB(180,220,255),ALIGN_LEFT);
    offCCI-=InpInsightSpeed;
    if(offCCI+cciCanvas.TextWidth(t)<-20) offCCI=canvW;
  }
  else
  {
    combinedCanvas.Erase(ARGB(120,0,0,0));
    string txt=ComputeAllInsights();
    combinedCanvas.TextOut(offCombined,(lineH-combinedCanvas.TextHeight(txt))/2,
                           txt,XRGB(180,220,255),ALIGN_LEFT);
    offCombined-=InpInsightSpeed;
    if(offCombined+combinedCanvas.TextWidth(txt)<100) offCombined=canvW;
  }

  // batch update
  eventsCanvas.Update(true);
  newsCanvas.  Update(true);
  if(InpSeparateLanes)
  {
    rsiCanvas.  Update(true);
    stochCanvas.Update(true);
    macdCanvas. Update(true);
    cciCanvas.  Update(true);
  }
  else
  {
    combinedCanvas.Update(true);
  }
}

6. OnDeinitでのクリーンアップ

適切なクリーンアップを行うことで、孤立したビットマップや残存するタイマーを防ぐことができます。OnInitで作成したCreateBitmapLabelは、OnDeinitでDestroyおよびObjectDeleteによって対応させます。また、タイマーも停止させ、不要なコールバックが残らないようにします。さらに、イベントインスタンスなどの動的オブジェクトを明示的に削除することで、堅牢なクリーンアップフェーズが完了します。

//+------------------------------------------------------------------+
//| OnDeinit: cleanup                                                |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  EventKillTimer();
  eventsCanvas.Destroy(); ObjectDelete(0,"EvC");
  newsCanvas.Destroy();   ObjectDelete(0,"NwC");
  if(InpSeparateLanes)
  {
    rsiCanvas.Destroy();  ObjectDelete(0,"RsiC");
    stochCanvas.Destroy();ObjectDelete(0,"StoC");
    macdCanvas.Destroy(); ObjectDelete(0,"MacC");
    cciCanvas.Destroy();  ObjectDelete(0,"CciC");
  }
  else
  {
    combinedCanvas.Destroy();ObjectDelete(0,"AllC");
  }
  for(int i=0;i<ArraySize(highArr);i++) delete highArr[i];
  for(int i=0;i<ArraySize(medArr);i++)   delete medArr[i];
  for(int i=0;i <ArraySize(lowArr);i++)   delete lowArr[i];
  ArrayResize(newsHeadlines,0);
}

 前回の記事の既存コードに新しいコンポーネントを適切に統合することで、リアルタイムのインジケーターインサイト機能を備えたアップグレード版のプログラムが完成しました。次のセクションでは、これら新機能のテスト結果を示した後、開発プロセスから得られた主要な知見と結論をまとめます。


テスト

MetaTrader 5では、ナビゲーターパネルのExpert AdvisorsセクションからEAをチャートにドラッグすることでテストできます。バージョン1.04以降、News Headline EAには統合されたインジケーターインサイト機能が追加されています。下の画像は、EAの入力設定を使って、デフォルトの単一レーン表示と個別レーン表示を切り替える方法を示しています。なお、セキュリティ上の理由から、APIキーは意図的に空欄になっており、使用前に手動で入力する必要があります。

インジケーターインサイトの統合・個別レーン表示のテスト

新機能のテスト

Alpha VantageのAPIキーを追加すると、ニュース見出しと統合されたインジケーターインサイトが同時に表示されるようになります。下図はその例です。

インジケーターインサイトを搭載したNews Headline EA

インジケーターインサイトを搭載したNews Headline EA

ストラテジーテスターを使用してEAをテストしましたが、キャンバスレーンは表示されるものの、データは表示されませんでした。これは、ニュースやインジケーターの値など、必要な情報がリアルタイムで取得される必要があるためであり、テスター環境では完全にはサポートされていないためと思われます。


結論

これまでの内容をまとめると、私たちはアイデアを実際に形にすることに成功しました。経済指標カレンダーのイベント、金融ニュースの見出し、ルールベースのインジケーターインサイトをすべて統合し、コンパクトで視覚的にわかりやすいインターフェース上で提供するオンチャートツールの実現可能性を示しました。

インジケーターインサイトの導入は、トレーダーにとって特に価値があります。複数のインジケーターウィンドウやチャートを切り替えることなく、市場状況の即時の文脈を把握できるため、判断に必要な情報を効率的に提供します。これにより作業効率が向上し、貴重な画面スペースも節約できます。

開発の観点では、MQL5 APIを用いてMetaTrader 5の組み込みインジケーターからデータを取得・操作する方法への理解を深めることができました。さらに、CCanvasクラスの柔軟性を活かすことで、取得したデータを視覚的に整理された形で表示し、ユーザー体験を向上させることができました。本プロジェクトは、MQL5におけるプログラムによるインターフェースカスタマイズの強力さを示すとともに、将来的にはアナリストのインサイトやユーザー定義インジケーターの統合など、さらなる機能拡張の可能性も示唆しています。

以下に、本記事から得られた主要な学びをまとめた要約表を用意しました。また、記事の最後にはフルソースコードも添付しています。コメント欄でご意見やフィードバックを共有していただけると幸いです。皆さんのご意見は非常に貴重です。



重要な学び

学び説明
関心の分離イベント、ニュース、インジケーターインサイト用にキャンバスを分けることで、コードのモジュール化が進み、レイアウトやスタイルの柔軟性が向上します。
CCanvasの使用チャート上でカスタムテキストやグラフィックを滑らかに描画でき、MetaTrader 5標準オブジェクトを超えた独自のインターフェース強化が可能になります。
スクロールアニメーションロジックオフセット変数を管理することで、ニュースフィードやインジケーター要約のような動的表示に最適な水平スクロールテキストを滑らかに作成できます。
DRY原則SetCanvasのようなヘルパー関数を作成することで、コードを簡潔かつ再利用可能に保ち、繰り返しを避けて保守性を高めます。
API統合WebRequestを使用して外部データを取得することで、MetaTrader 5が金融ニュースプロバイダーなどのサードパーティサービスと連携できることを示します。
リアルタイムデータの制約経済イベントや市場ニュースなどのライブデータはリアルタイムでの取得が必要であり、ストラテジーテスター環境では完全に機能しない場合があります。
組み込みインジケーターの使用RSI、MACD、CCIなど標準インジケーターのバッファにアクセス・解釈することで、コード内で自動的にインサイトを生成できます。
コンパクトなUIデザイン複数のデータストリームを1本のスクロールレーンに統合することで、チャートの混雑を減らし、すべての重要情報を一箇所で提供できます。
動的キャンバス配置ユーザーの設定やチャートサイズに応じてキャンバスオブジェクトを再配置することで、レスポンシブで柔軟なレイアウトを実現します。
バージョン管理と機能追跡明確なバージョン番号を維持することで、変更履歴の追跡、進捗の記録、ユーザーや開発者への更新情報の伝達が容易になります。


添付ファイル

ファイルバージョン説明 
News Headline EA.mq51.04経済指標カレンダーのイベントやリアルタイムの市場ニュースヘッドラインを、組み込みのMQL5キャンバスとAlpha Vantage APIを用いてチャート上に直接表示するEA。さらに、各種インジケーターによるテクニカルインサイトも提供します。

裏表紙

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

添付されたファイル |
データサイエンスとML(第45回):FacebookのPROPHETモデルを用いた外国為替時系列予測 データサイエンスとML(第45回):FacebookのPROPHETモデルを用いた外国為替時系列予測
Prophetモデルは、Meta(旧Facebook)によって開発された強力な時系列予測ツールであり、トレンドや季節性、イベント効果(holiday effects)を最小限の手作業で捉えることができます。このモデルは、需要予測やビジネスプランニングにおいて広く活用されてきました。本記事では、ProphetモデルをFXのボラティリティ予測に応用する効果について探り、従来のビジネス用途を超えた利用例を紹介します。
ログレコードをマスターする(第9回):ビルダーパターンの実装とデフォルト設定の追加 ログレコードをマスターする(第9回):ビルダーパターンの実装とデフォルト設定の追加
本記事では、Logifyライブラリの利用をビルダーパターンと自動的なデフォルト設定によって大幅に簡単にする方法をご紹介します。ここでは、専用ビルダーの構造、スマートな補完機能を活用した利用方法、手動で設定をおこなわなくても動作するログ確保方法について解説します。さらに、MetaTrader 5ビルド5100向けの調整についても触れます。
MQL5での取引戦略の自動化(第21回):適応学習率によるニューラルネットワーク取引の強化 MQL5での取引戦略の自動化(第21回):適応学習率によるニューラルネットワーク取引の強化
本記事では、MQL5におけるニューラルネットワーク取引戦略を、適応型学習率を用いて精度を向上させる形で強化します。このメカニズムを設計・実装した後、そのパフォーマンスを検証します。記事の最後には、アルゴリズム取引における最適化の知見もまとめます。
MQL5での取引戦略の自動化(第20回):CCIとAOを使用した多銘柄戦略 MQL5での取引戦略の自動化(第20回):CCIとAOを使用した多銘柄戦略
この記事では、CCI (Commodity Channel Index)とAO (Awesome Oscillator)を用いてトレンド反転を検出する多銘柄取引戦略を作成します。戦略の設計、MQL5での実装、バックテストのプロセスについて解説します。記事の最後には、パフォーマンス改善のためのヒントも紹介します。