EURUSDが上がっているのを見て、
「EURが強いのか、それともUSDが弱いだけなのか」と迷ったことはないでしょうか。
1つの通貨ペアの値動きだけでは、
どちらの通貨が強いのかを判断できません。
この記事では、7つの主要通貨ペアの変化率から、
主要8通貨(USD/EUR/GBP/JPY/AUD/NZD/CAD/CHF)の、
強弱を計算し、チャート上のパネルに一覧表示する、
インジケーターの作り方を解説します。
・1つの通貨ペアだけでは強弱が分からない理由
・7つの主要通貨ペアから8通貨の強弱を計算する考え方
・他の通貨ペアのデータを取得する際の落とし穴(SymbolSelect)
・変化率を計算してパネル表示する実装コード
通貨強弱とは何か・1通貨ペアだけでは分からない理由
まず、「通貨強弱」という考え方を整理します。
1通貨ペアの上下だけでは「どちらが強いか」分からない
EURUSDが上がったとき、
EURが強くなったのか、USDが弱くなったのか、
あるいは両方なのかは、このペアだけでは判断できません。
主要8通貨を7つのペアでカバーする考え方
USD・EUR・GBP・JPY・AUD・NZD・CAD・CHFの8通貨は、
EURUSD・GBPUSD・AUDUSD・NZDUSD・
USDJPY・USDCAD・USDCHFの7つの主要ペアを調べれば、
全通貨の変化率を拾えます。
USDだけは7ペア全てに登場するため平均を取る
・USDは7ペア全てに登場するため、7ペア分の変化率の平均値を使う
・他の7通貨は、今回の組み合わせでは1ペアにしか登場しない
・精度を上げたい場合はクロス通貨ペアを追加する(8節のFAQ参照)
他の通貨ペアのデータを取得する際の落とし穴
ここが、この種のインジケーターを自作するときに最初に詰まりやすい部分です。
iClose()は対象シンボルがMarket Watchに無いと0を返す
・iClose(symbol, …)で、表示中の通貨ペア以外を指定することはできる
・しかしMarket Watchに表示されていないと履歴が読み込まれず0を返す
・0のまま変化率を計算すると、ゼロ除算やあり得ない強弱表示につながる
SymbolSelect(symbol, true)で明示的に追加する
`SymbolSelect()`関数を使い、
必要な7通貨ペアを明示的にMarket Watchへ追加しておくことで、
この問題を避けられます。
OnInit()でまとめて追加しておく設計にする
毎ティック呼び出す必要はないため、
`OnInit()`の中で7ペアをまとめて1回だけ追加する設計にします。
iCloseで変化率を計算し、符号をどう決めるか
次に、実際の変化率の計算方法を確認します。
変化率(%)の計算式
`(現在値 – N本前の値) ÷ N本前の値 × 100`
(Nは`InpLookbackBars`)という、
ごく基本的な変化率の式を使います。
XXXUSD形式とUSDXXX形式で符号の向きが逆になる
EURUSD・GBPUSD等(XXXUSD形式)が上がれば、
左側の通貨(EUR・GBP等)が強くUSDが弱いと判断します。
USDJPY・USDCAD・USDCHF等(USDXXX形式)が上がれば、
逆にUSDが強く右側の通貨が弱いと判断します。
色でプラス・マイナスを判別できるようにする
強くなっている通貨は緑、
弱くなっている通貨は赤で表示し、
数値を読まなくても一目で判断できるようにします。
実際に動くサンプルコード
8通貨の強弱をパネルに一覧表示するインジケーターです。
//+------------------------------------------------------------------+
//| CurrencyStrengthPanel.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window
input int InpLookbackBars = 20; //強弱を計算する期間(本数)
string Symbols7[7] = {"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDJPY","USDCAD","USDCHF"};
string PanelPrefix = "CcyStrength_";
int OnInit()
{
for(int i = 0; i < 7; i++)
SymbolSelect(Symbols7[i], true); //Market Watchに追加(iCloseの0返り対策)
for(int i = 0; i < 8; i++)
{
string name = PanelPrefix + IntegerToString(i);
ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, 20 + i * 18);
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 10);
}
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
for(int i = 0; i < 8; i++)
ObjectDelete(0, PanelPrefix + IntegerToString(i));
}
double PercentChange(string symbol)
{
double past = iClose(symbol, 0, InpLookbackBars);
double now = iClose(symbol, 0, 0);
if(past == 0)
return(0); //履歴未取得時の保険(ゼロ除算防止)
return((now - past) / past * 100.0);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
double chgEURUSD = PercentChange("EURUSD");
double chgGBPUSD = PercentChange("GBPUSD");
double chgAUDUSD = PercentChange("AUDUSD");
double chgNZDUSD = PercentChange("NZDUSD");
double chgUSDJPY = PercentChange("USDJPY");
double chgUSDCAD = PercentChange("USDCAD");
double chgUSDCHF = PercentChange("USDCHF");
double usd = (-chgEURUSD - chgGBPUSD - chgAUDUSD - chgNZDUSD
+ chgUSDJPY + chgUSDCAD + chgUSDCHF) / 7.0;
string names[8] = {"USD","EUR","GBP","AUD","NZD","JPY","CAD","CHF"};
double values[8];
values[0] = usd;
values[1] = chgEURUSD;
values[2] = chgGBPUSD;
values[3] = chgAUDUSD;
values[4] = chgNZDUSD;
values[5] = -chgUSDJPY;
values[6] = -chgUSDCAD;
values[7] = -chgUSDCHF;
for(int i = 0; i < 8; i++)
{
string name = PanelPrefix + IntegerToString(i);
string sign = (values[i] >= 0) ? "+" : "";
string text = StringFormat("%s %s%.2f%%", names[i], sign, values[i]);
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetInteger(0, name, OBJPROP_COLOR, values[i] >= 0 ? clrLimeGreen : clrOrangeRed);
}
return(rates_total);
}
USD以外の7通貨は、
対応する1つの通貨ペアの変化率(の符号を調整した値)が、
そのままパネルの表示値になります。
MetaEditorでのコンパイル・表示手順
- MetaEditorで新規カスタムインジケーター「CurrencyStrengthPanel」を作成し、上のコードを貼り付けてコンパイルする
- 任意の通貨ペアのチャートにドラッグ&ドロップで適用する
- チャート右上に8通貨分のパネルが表示され、緑・赤で強弱が色分けされることを確認する
- `InpLookbackBars`の値を変え、表示される変化率が変わる様子を確認する
よくあるエラーと注意点
実際に使う前に確認しておきたい注意点をまとめます。
表示直後は一部の通貨が0%のままになることがある
・ブローカーによっては他通貨ペアの気配配信が遅れることがある
・SymbolSelectで追加した直後は履歴データの読み込みが済んでいない場合がある
・数秒待ってから再度確認するか、OnTimer等で再計算する設計にすると改善する
InpLookbackBarsを変えると基準期間が変わる
短くすると直近の短期的な強弱に、
長くすると中期的な強弱に、
それぞれ敏感になります。
これはランキングではなく一覧表示である点に注意
本記事のパネルは、
強い順に並び替えたランキングではなく、
固定の順番(USD→EUR→…)で一覧表示するだけの設計です。
よくある質問
通貨強弱パネルについて、よく検索される疑問に回答します。
なぜ7ペアだけで8通貨の強弱が分かるのですか?
8通貨のうちUSDは、
7ペア全てに登場するため平均値を取れますが、
残りの7通貨は1ペアのみの変化率をそのまま使う簡略化です。
精度を上げたい場合は、次のFAQのクロス通貨ペアを追加してください。
クロス通貨ペア(EURJPY等)を追加すれば精度は上がりますか?
上がります。
EURJPY・GBPJPY等を追加し、
各通貨が登場する全ペアの変化率を平均するよう拡張すれば、
USD以外の通貨も複数ペアの裏付けを持つ強弱になります。
このロジックをEAのフィルターに組み込めますか?
できます。
`PercentChange()`関数と8通貨の集計部分を関数化すれば、
「一番強い通貨と一番弱い通貨の組み合わせだけエントリーする」
といったフィルターにも応用できます。
【MQL4】主要8通貨の通貨強弱をパネルで表示するインジケーターの作り方:まとめ
1つの通貨ペアの値動きだけでは、
どちらの通貨が強いのかを判断できません。
7つの主要通貨ペアの変化率を、
SymbolSelectで確実に取得し、
8通貨の強弱としてパネルに一覧表示することで、
通貨ペア選びの判断材料を増やせます。
コメント