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でのコンパイル・表示手順

  1. MetaEditorで新規カスタムインジケーター「CurrencyStrengthPanel」を作成し、上のコードを貼り付けてコンパイルする
  2. 任意の通貨ペアのチャートにドラッグ&ドロップで適用する
  3. チャート右上に8通貨分のパネルが表示され、緑・赤で強弱が色分けされることを確認する
  4. `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通貨の強弱としてパネルに一覧表示することで、

通貨ペア選びの判断材料を増やせます。

関連記事