
プライスアクション分析ツールキットの開発(第23回):Currency Strength Meter
内容
はじめに
自動車レースにいると想像してみてください。各車両はユニークであり、どれが最速か最遅かを単純に推測することはできません。代わりに、ラップタイムを観察し、加速性能を評価し、ブレーキ性能をテストし、各モデルを個別に分析します。各車を徹底的に分析した後で初めて、全体的な性能を比較できます。
通貨も同じように機能します。このEAは、通貨が含まれるすべてのトレーディングペアを検査します。たとえばUSDの場合、USDJPY、EURUSD、GBPUSD、USDCHFなどを対象に分析します。各ペアが異なる時間軸でどれだけ動いたかを測定し、最初にM15、次にH1、最後にH4を使用します。これらの参照期間(ルックバック)は、パラメータLookback_M15、Lookback_H1、Lookback_H4で指定されます。
通貨がペア内で決済通貨である場合、その変化を反転させて正確な通貨の強さを反映させます。関連するすべてのペアでの変化を計算した後、それらの結果を平均化して各通貨の単一の強さ値を算出します。EAはUpdate_Secondsパラメータで指定された秒数ごとにこれらの計算を更新し、ダッシュボードを再描画して現在の通貨の強さを表示します。また、強い通貨、弱い通貨、ニュートラルな通貨をログ出力し、口座のエクイティやドローダウンを示すビジュアルカーブも更新します。
本記事では、各銘柄の複数ペアでのパフォーマンスを分析することで通貨の強さを測定するMQL5ツールを開発します。このアプローチにより、最も強い通貨と最も弱い通貨を確実に特定でき、より自信を持って取引できるようになります。
戦略の理解
このEAの主な役割は、ある通貨が強いのか弱いのかを、その通貨が含まれるすべてのペアを複数の時間軸で確認することで測定することです。各通貨の強さをペアと時間軸ごとに計算するために、次の手順に従います。
関連ペアの選定
8つの主要通貨それぞれについて、その通貨が含まれるすべての通貨ペアを収集します(例:USDの場合、USDJPY、EURUSD、GBPUSD、USDCHFなど)。
パーセンテージ変化の計算
選択した時間軸(例:M15、H1、H4)において、各ペアの指定された参照期間でのパーセンテージ変化を計算します。
符号の正規化
測定対象の通貨がペア内で決済通貨(Quote Currency、後ろの通貨)の場合、そのパーセンテージ変化の符号を反転します。これにより、強い決済通貨は常に正の強さとして表示されます。
ペア間で平均化
すべてのペアにおける(符号付き)パーセンテージ変化を単純平均します。これにより、特定の時間軸における通貨の単一の「強さスコア」が得られます。
上の図は、USDを例にしてこのプロセスを示しています。USDが含まれるすべてのペアでの強さを複数の時間軸で測定することで、USDがどの時間軸で最も強いか、または最も弱いかを特定できます。
コード解説
EAはまず、基本的なプロパティを定義することから始まります。著作権情報、リンク、バージョン、strictコンパイルモードなどのディレクティブは、EAを特定し、MetaTrader環境内で期待される標準に準拠していることを保証するために使用されます。次にSymbolInfo.mqhライブラリをインクルードします。このライブラリは銘柄情報の管理や取得に必要な関数を提供し、複数の通貨ペアを動的に選択・有効化・データ取得するために不可欠です。このインクルードにより、デフォルトで有効になっていない銘柄のデータにもアクセスでき、スクリプトが複数のペアで問題なく動作することを保証します。
#property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/ja/users/lynnchris" #property version "1.0" #property strict #include <Trade\SymbolInfo.mqh>
次に、コードは複数の入力パラメータを定義します。Lookback_M15、Lookback_H1、Lookback_H4は、それぞれの時間軸で通貨の強さを計算する際に参照する過去バーの数を指定します。Update_Secondsパラメータは、ダッシュボードが更新される頻度を決定し、リアルタイムでの応答性と計算効率のバランスを取ります。
さらに、FontSize、BackgroundColor、PanelWidth、PanelHeight、および初期位置のパラメータは、ユーザーがチャート上でダッシュボードの見た目や配置をカスタマイズできるようにします。これにより、異なる画面サイズや個人の好みに合わせて調整可能です。参照期間は、通貨の強さ計算の感度や滑らかさに影響します。期間が短いほど反応は速くなりますがノイズが多くなり、期間が長いほど安定性は高くなりますが反応は遅くなります。
input int Lookback_M15 = 96; input int Lookback_H1 = 48; input int Lookback_H4 = 30; input int Update_Seconds = 30; input int FontSize = 12; input color BackgroundColor = clrBlack; input int PanelWidth = 280; input int PanelHeight = 240; input int InitPanelX = 10; input int InitPanelY = 10;
CurrenciesおよびPairs配列は、主要通貨とそれに関連する通貨ペアをリスト化した静的データ構造です。この構成により、各通貨に関連するペアがまとめられ、強度計算時にペアをループ処理するのが簡単になります。たとえば、Pairs配列は各通貨ごとに4つのペアを含み、それぞれのペアにはその通貨がベース通貨または決済通貨として含まれています。この体系的なグループ化により、計算関数は複数のペアを同時に分析して各通貨の他通貨に対するパフォーマンスを効率的に評価でき、より包括的な強度測定が可能となります。
static const string Currencies[8] = {"USD","EUR","GBP","JPY","CHF","CAD","AUD","NZD"}; static const string Pairs[8][4] = { {"USDJPY","EURUSD","GBPUSD","USDCHF"}, {"EURUSD","EURJPY","EURGBP","EURCHF"}, // ... ......... };
グローバル変数は、異なる時間軸で計算された通貨の強さの値を保持するために宣言されており、二次元配列Strength[8][3]に格納されます。これらのスコアはダッシュボード上の表示やログ記録に使用されます。さらに、LastUpdateなどの変数は、データが最後に更新された時刻を追跡し、不要な再計算を防ぐ役割を果たします。
ユーザー操作を管理するために、変数dragging、dragOffsetX、dragOffsetYが宣言されており、これによりトレーダーはマウス操作でダッシュボードの位置を自由に移動できます。口座のパフォーマンスを可視化するため、times[]とequities[]の配列が宣言され、タイムスタンプ付きの口座エクイティデータを格納します。また、dataCount変数が収集されたデータポイントの数を追跡します。これらは、口座のエクイティやドローダウンの推移を時間軸でプロットするために不可欠です。
double Strength[8][3]; // [currency][timeframe] datetime LastUpdate; int dataCount; double equities[MAX_POINTS]; datetime times[MAX_POINTS]; int PanelX, PanelY; bool dragging; int dragOffsetX, dragOffsetY;
初期化時(OnInit())に、EAはユーザー入力に基づいてダッシュボードの開始位置を設定します。次に、すべての通貨ペアをループ処理し、それぞれに対してSymbolSelect関数を呼び出してデータアクセスを有効化します。このステップは非常に重要で、銘柄が有効になっていないと、iCloseのような後続のデータ取得関数が失敗し、計算ミスやエラーが発生する可能性があります。
その後、LastUpdateのタイムスタンプを初期化し、データカウンターdataCountをリセットします。UpdateStrengths関数を呼び出して初回の通貨の強さ計算をおこない、起動直後からダッシュボードに最新データを表示できるようにします。DrawPanel関数は、ラベル、カラー付きバー、ヘッダを備えたビジュアルダッシュボードを作成し、直感的で視覚的に分かりやすいインターフェースを提供します。
さらに、LogCurrencyStrengths関数を呼び出して、ターミナル上に通貨の状態をテキストで要約して表示します。これにより、トレーダーは通貨の強弱を高レベルで素早く把握できます。最後に、EventSetTimer関数がUpdate_Secondsで指定された間隔で定期更新ルーチンをスケジュールし、手動操作なしでダッシュボードを自動的に更新できるようにします。
int OnInit() { PanelX = InitPanelX; PanelY = InitPanelY; for(int i=0; i<8; i++) for(int j=0; j<4; j++) SymbolSelect(Pairs[i][j], true); LastUpdate = 0; dataCount = 0; UpdateStrengths(); DrawPanel(); LogCurrencyStrengths(1); EventSetTimer(Update_Seconds); return(INIT_SUCCEEDED); }
EAが初期化解除されると(OnDeinit())、クリーンアップ処理がおこなわれます。これには、EventKillTimer関数によるタイマーイベントの削除、ダッシュボードに関連するすべてのグラフィカルオブジェクト(背景、ラベル、バー、ヘッダなど)の削除、エクイティおよびドローダウンのトレンドラインのクリアが含まれます。これらのクリーンアップにより、チャート上に不要なオブジェクトが残ったり、リソースを消費したりすることを防ぎ、EAが削除または再読み込みされた際にチャート環境を整理された状態に保つことができます。
void OnTimer() { if(TimeCurrent() - LastUpdate < Update_Seconds) return; LastUpdate = TimeCurrent(); UpdateStrengths(); DrawPanel(); LogCurrencyStrengths(1); double eq = AccountInfoDouble(ACCOUNT_EQUITY); if(dataCount < MAX_POINTS) { times[dataCount] = TimeCurrent(); equities[dataCount] = eq; dataCount++; } DrawEquityLines(); DrawDrawdownLines(); }
コアの更新ロジックはOnTimer関数に存在し、定期的に実行されます。まず、最後の更新時刻LastUpdateと現在時刻を比較して、十分な時間が経過しているかどうかを確認します。指定された間隔が経過していない場合は、過剰な計算を避けるために処理を早期終了します。更新がトリガーされると、LastUpdateを現在時刻に更新し、UpdateStrengths関数を呼び出して、最新の市場データに基づき通貨の強さスコアを再計算します。
次にDrawPanel関数を呼び出してビジュアルダッシュボードを更新し、ラベル、色、バーを最新の強度値に反映させます。また、LogCurrencyStrengths関数を使って現在の通貨状況をログに出力し、テキスト形式での洞察を提供します。その後、現在の口座エクイティ(AccountInfoDouble(ACCOUNT_EQUITY))を取得し、最大データポイントに達していない場合、タイムスタンプとエクイティ値をそれぞれの配列に追加します。
これらの保存されたデータポイントは、DrawEquityLines()およびDrawDrawdownLines()によりパフォーマンスのトレンドラインを更新するために使用され、口座の成長やリスクを時間軸で視覚的に表現します。このサイクルにより、ダッシュボード全体がリアルタイムの市場状況および口座のパフォーマンスと常に同期された状態を維持します。
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id==CHARTEVENT_OBJECT_CLICK && sparam=="CS_BG") { dragging = true; dragOffsetX = (int)lparam - PanelX; dragOffsetY = (int)dparam - PanelY; } else if(id==CHARTEVENT_MOUSE_MOVE && dragging) { PanelX = (int)lparam - dragOffsetX; PanelY = (int)dparam - dragOffsetY; DrawPanel(); } else if(dragging && id==CHARTEVENT_OBJECT_CLICK) { dragging = false; } }
ユーザー操作はOnChartEvent()で管理されます。ユーザーが背景矩形(CS_BG)をクリックすると、ドラッグモードが有効になり、マウス位置とパネルの現在位置とのオフセットが記録されます。マウスが移動すると(CHARTEVENT_MOUSE_MOVE)、パネルの位置が動的に更新され、トレーダーはダッシュボードを見やすい位置にインタラクティブに移動できます。ユーザーがマウスボタンを放すか、別の場所をクリックすると、ドラッグモードは無効になり、パネルは新しい位置に固定されます。この機能により、異なる作業環境に合わせてダッシュボードをカスタマイズでき、使いやすさが向上します。
double CalculateStrength(int ci, ENUM_TIMEFRAMES tf, int lookback) { double sum = 0; int cnt = 0; for(int j=0; j<4; j++) { string sym = Pairs[ci][j]; if(Bars(sym, tf) < lookback+1) continue; double now = iClose(sym, tf, 0); double prev = iClose(sym, tf, lookback); if(prev == 0) continue; double pct = (now - prev) / prev * 100.0; if(StringFind(sym, Currencies[ci]) > 0) pct = -pct; sum += pct; cnt++; } return (cnt == 0) ? 0 : sum / cnt; }
通貨の強さの計算はUpdateStrengths()およびCalculateStrength()でおこなわれます。UpdateStrengths()は各通貨インデックスを順に処理し、3つの時間軸それぞれに対してCalculateStrength()を呼び出します。
CalculateStrength()は、対象となる各ペアの最新終値(iClose())を取得し、続いて参照期間の過去終値を取得します。計算に十分なバーが存在するかどうかを確認し、不足している場合はエラーを避けるためにそのペアの計算をスキップします。参照期間におけるパーセンテージ変化を計算し、対象通貨がペア内で決済通貨の場合、その変化の符号を反転して、ベース通貨の相対的な強さを正確に測定します。
この符号の反転により、決済通貨が値上がりした場合にベース通貨が弱まることが反映され、計算全体の整合性が保たれます。関数は各通貨に対して4つのペアのパーセンテージ変化を合計し、平均を取ることで代表的な強度スコアを生成し、表示やログ記録のためにStrength配列に格納します。
void DrawPanel() { RemovePanel(); ObjectCreate(0, "CS_BG", OBJ_RECTANGLE_LABEL, 0, 0, 0); ObjectSetInteger(0, "CS_BG", OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, "CS_BG", OBJPROP_XDISTANCE, PanelX); ObjectSetInteger(0, "CS_BG", OBJPROP_YDISTANCE, PanelY); ObjectSetInteger(0, "CS_BG", OBJPROP_XSIZE, PanelWidth); ObjectSetInteger(0, "CS_BG", OBJPROP_YSIZE, PanelHeight); // Add headers, labels, colored bars for each currency }
このデータの視覚的表示はDrawPanel()によっておこなわれます。まず、指定されたダッシュボード領域を覆う矩形を作成し、各時間軸のヘッダを上部に追加して見やすくします。次に、各通貨を順にループ処理し、通貨名のラベル、数値としての強度値(小数点以下2桁でフォーマット)、そして通貨の強弱を視覚的に示すカラー付きバーを作成します。
カラースキームは、強い通貨に緑系、ニュートラルにオレンジ、弱い通貨に赤を使用しており、トレーダーが市場状況を直感的に把握できるようにしています。バーの幅は強度値に比例しており、視覚的な手掛かりとして直感的に理解可能です。これらの体系的で一貫したグラフィカル要素により、ダッシュボードは情報豊かで、一目で状況を把握できる設計となっています。
void RemovePanel() { for(int i=ObjectsTotal(0)-1; i>=0; i--) { string name = ObjectName(0, i); if(StringFind(name, "CS_") == 0 || StringFind(name, "Lbl_") == 0 || StringFind(name, "Bar_") == 0) ObjectDelete(0, name); } }
ダッシュボードの更新や削除が必要な場合、RemovePanel()は、ダッシュボードに関連する特定の名前プレフィックス(「CS_」、「Hdr_」、「Lbl_」、「Val_」、「Bar_」など)を削を持つすべてのオブジェクト除します。この体系的な削除により、チャート上に不要なグラフィックが残らず、常に整理された状態が保たれます。これにより、ダッシュボードはリフレッシュのたびにゼロから再構築でき、残留オブジェクトが蓄積するのを防ぎます。
void DrawEquityLines() { for(int i=1; i< dataCount; i++) { string id = StringFormat("EQ_%d", i); ObjectDelete(0, id); ObjectCreate(0, id, OBJ_TREND, 0, times[i-1], equities[i-1], times[i], equities[i]); ObjectSetInteger(0, id, OBJPROP_COLOR, clrYellow); ObjectSetInteger(0, id, OBJPROP_WIDTH, 2); } }
DrawEquityLines()関数とDrawDrawdownLines()関数は、口座のパフォーマンスの推移を視覚化します。新しいエクイティデータが記録されるたびに、これらの関数は以前のトレンドオブジェクト(「EQ_」および「DD_」)を削除してプロットを整理します。続いて、保存されたデータポイントを結ぶ新しいトレンドオブジェクトを作成し、明確に区別できるように色分けします。エクイティは黄色、ドローダウンは赤です。
トレンドラインは、口座の価値がどのように推移してきたか、最大ドローダウンがどの程度であったかを視覚的に示します。これらの視覚表現は、EAが実際に取引を管理している場合にのみ真に意味を持ちます。なぜなら、口座エクイティの変化は、実行された注文によるものであるためです。
void DrawDrawdownLines() { double peak = -DBL_MAX; for(int i=1; i< dataCount; i++) { peak = MathMax(peak, equities[i-1]); double dd = equities[i-1] - peak; string id = StringFormat("DD_%d", i); ObjectDelete(0, id); ObjectCreate(0, id, OBJ_TREND, 0, times[i-1], dd, times[i], equities[i] - peak); ObjectSetInteger(0, id, OBJPROP_COLOR, clrRed); ObjectSetInteger(0, id, OBJPROP_WIDTH, 2); } }
重要なポイントとして、エクイティやドローダウンのプロット用コードは含まれており、トレンドラインを生成しますが、その有用性はEAが自動取引をおこなうかどうかに大きく依存します。EAが情報提供のみ、または手動取引専用の場合、口座エクイティはトレーダーが手動で取引をおこなうか、入出金をおこなったときにしか変化しません。この場合、エクイティのプロットはリアルタイムの取引パフォーマンスを正確に反映せず、トレンドラインも静的になったり、あまり意味を持たなかったりします。
したがって、これらのプロット機能は、自動取引を積極的におこない口座残高を継続的に調整するEAに統合された場合に最も価値があります。そのような自動取引システムが存在する場合、エクイティプロットは口座の成長、ドローダウン、全体的なパフォーマンスをリアルタイムで視覚的に示し、リスク管理やパフォーマンス評価に非常に有用となります。
void LogCurrencyStrengths(int tfIdx) { string sStrong="", sWeak="", sNeutral=""; for(int i=0; i<8; i++) { double v = Strength[i][tfIdx]; if(v > 0.3) sStrong += Currencies[i] + " "; else if(v < -0.3) sWeak += Currencies[i] + " "; else sNeutral += Currencies[i] + " "; } Print("Strong: ", sStrong, "| Weak: ", sWeak, "| Neutral: ", sNeutral); }
最後に、LogCurrencyStrengths()は、各通貨を事前に定めた閾値(例:+0.3%以上は強い、-0.3%以下は弱い)に基づき、強い、弱い、またはニュートラルに分類してテキスト形式で要約を提供します。各カテゴリの通貨コードを文字列として連結し、ターミナルウィンドウに出力します。このテキストによる概要は、主要通貨全体の市場センチメントを素早く把握するための手段となり、グラフィカル表示を補完して、迅速かつ高レベルの洞察を求めるトレーダーに便利です。
結果
このセクションでは、MetaTrader 5でのEAテストの結果を確認します。
通貨 | M15 | H1 | H4 |
---|---|---|---|
USD | -0.11 | +1.12 | +2.20 |
EUR | -0.23 | -0.38 | -0.38 |
GBP | +0.20 | +0.49 | +0.67 |
JPY | +0.01 | -1.44 | -2.48 |
CHF | +0.32 | -0.25 | -0.33 |
CAD | +0.17 | +0.34 | +0.16 |
AUD | +0.05 | +0.71 | +0.52 |
NZD | +0.10 | +0.76 | +0.13 |
- USDは、短期のM15で一時的な下落があったものの、H1 (+1.12%)およびH4 (+2.20%)で最も強い通貨です。
- JPYとEURは、H1(それぞれ–1.44%、–0.38%)およびH4(–2.48%、–0.38%)で最も弱い通貨となっています。
- GBP、CAD、AUD、NZDはH1/H4でやや強めから中程度の強さを示しており、二次的な「強い通貨」の候補です。
結論
通貨の強さメーターは、複数の時間軸で通貨ペアの変化を把握するのに役立ち、潜在的な市場方向性を明確に示すスナップショットを提供します。ただし、これを見てすぐに取引をおこなうべきという意味ではありません。あくまで最適なエントリーレベルを見つけるための補助として活用し、リスク管理や確認戦略と組み合わせて使用してください。このツールは通貨の強さを測定する出発点であり、分析方法や結果の表示方法をさらに改善する余地があります。今後のプロジェクトでのさらなる発展にご期待ください。
日付 | ツール名 | 詳細 | バージョン | アップデート | 備考 |
---|---|---|---|---|---|
01/10/24 | ChartProjector | 前日のプライスアクションをゴースト効果でオーバーレイするスクリプト | 1.0 | 初回リリース | ツール番号1 |
18/11/24 | Analytical Comment | 前日の情報を表形式で提供し、市場の将来の方向性を予測する | 1.0 | 初回リリース | ツール番号2 |
27/11/24 | Analytics Master | 2時間ごとに市場指標を定期的に更新 | 1.01 | v.2 | ツール番号3 |
02/12/24 | Analytics Forecaster | Telegram統合により、2時間ごとに市場指標を定期的に更新 | 1.1 | v.3 | ツール番号4 |
09/12/24 | Volatility Navigator | ボリンジャーバンド、RSI、ATR指標を使用して市場の状況を分析するEA | 1.0 | 初回リリース | ツール番号5 |
19/12/24 | Mean Reversion Signal Reaper | 平均回帰戦略を用いて市場を分析し、シグナルを提供する | 1.0 | 初回リリース | ツール番号6 |
9/01/25 | Signal Pulse | 多時間軸分析ツール | 1.0 | 初回リリース | ツール番号7 |
17/01/25 | Metrics Board | 分析用のボタン付きパネル | 1.0 | 初回リリース | ツール番号8 |
21/01/25 | External Flow | 外部ライブラリによる分析 | 1.0 | 初回リリース | ツール番号9 |
27/01/25 | VWAP | 出来高加重平均価格 | 1.3 | 初回リリース | ツール番号10 |
02/02/25 | Heikin Ashi | トレンドの平滑化と反転シグナルの識別 | 1.0 | 初回リリース | ツール番号11 |
04/02/25 | FibVWAP | Python分析によるシグナル生成 | 1.0 | 初回リリース | ツール番号12 |
14/02/25 | RSI DIVERGENCE | プライスアクションとRSIのダイバージェンス | 1.0 | 初回リリース | ツール番号13 |
17/02/25 | Parabolic Stop and Reverse (PSAR) | PSAR戦略の自動化 | 1.0 | 初回リリース | ツール番号14 |
20/02/25 | Quarters Drawerスクリプト | チャートにクォーターレベルを描く | 1.0 | 初回リリース | ツール番号15 |
27/02/25 | Intrusion Detector | 価格がクォーターレベルに達したときに検出して警告する | 1.0 | 初回リリース | ツール番号16 |
27/02/25 | TrendLoom Tool | 多時間軸分析パネル | 1.0 | 初回リリース | ツール番号17 |
11/03/25 | Quarters Board | クォーターレベルを有効または無効にするボタン付きのパネル | 1.0 | 初回リリース | ツール番号18 |
26/03/25 | ZigZag Analyzer | ジグザグインジケーターを使ったトレンドラインの描画 | 1.0 | 初回リリース | ツール番号19 |
10/04/25 | Correlation Pathfinder | Pythonライブラリを使用して通貨の相関関係をプロットする | 1.0 | 初回リリース | ツール番号20 |
23/04/25 | Market Structure Flip Detector Tool | 市場構造反転を検出する | 1.0 | 初回リリース | ツール番号21 |
08/05/25 | Correlation Dashboard | 異なるペア間の関係 | 1.0 | 初回リリース | ツール番号22 |
13/05/25 | Currency Strength Meter | 各通貨ペアの強さを測定する | 1.0 | 初回リリース | ツール番号22 |
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/18108
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索