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通貨の強弱としてパネルに一覧表示することで、通貨ペア選びの判断材料を増やせます。

関連記事