RCIという名前は聞いたことがあっても、

MT4の関数一覧を探しても見つからず、

戸惑った経験はないでしょうか。

実はRCI(順位相関指数)は、

iMAやiRSIのようなMT4の標準関数には存在しません。

自分で計算するしかないインジケーターです。

この記事では、「時間の順位」と「価格の順位」を比べるという

RCIの考え方から、実際に動くMQL4のコード、

そして閾値をまたいだ瞬間だけを矢印で知らせる実装まで解説します。

この記事で分かること
・RCIがRSIと何を比べているか(値動きの大きさ vs 順位)
・MT4に標準関数がないRCIを自分で計算するロジック
・閾値を超えた瞬間だけを矢印表示する設計
・実際に動くインジケーターのコード全体

RCI(順位相関指数)とは何か

まず、RCIが何を計算しているオシレーターなのかを確認します。

時間の順位と価格の順位を比べるという考え方

RCIは、直近n本の値動きについて

「時間が新しい順の順位」と「価格が高い順の順位」という

2種類の順位をつけ、どれだけ一致しているかを数値化したものです。

直近になるほど価格が高くなっていれば、

2つの順位はよく一致し、上昇トレンドと判定されます。

RSIとの違い(値動きの大きさでなく順位を見る)

RSIは値上がり幅・値下がり幅という「大きさ」を使って計算しますが、

RCIは値動きの大きさを無視し、「何番目に高いか」という順位だけを使います。

そのため1本だけ極端に大きく動いた足があっても、

RSIほど過敏に反応しない性質があります。

+80/-80ラインの意味と使い方

RCIは-100から+100の範囲で動きます。

一般的に+80以上は「上昇が行き過ぎた状態」、

-80以下は「下落が行き過ぎた状態」の目安とされています。

ただし強いトレンド中は+80や-80に張り付いたまま動かないことも多く、

水準への到達だけで逆張りすると後述するダマシに遭いやすい点に注意してください。

MT4に標準関数がない理由と自作の方針

RCIをMT4で使うには、なぜ自分で計算する必要があるのかを確認します。

ビルトイン関数がないため配列操作で自作する必要がある

docs.mql4.comの関数一覧には、

iMAやiRSIのような「RCIを直接計算する関数」は存在しません。

そのため過去の価格配列(Close[])を自分で順位付けし、

Spearman順位相関係数の考え方に沿って計算する処理を自作する必要があります。

Spearman順位相関の計算式

一般的なSpearman順位相関係数の公式は次のとおりです。

RCI = (1 - 6×Σd^2 / (n×(n^2-1))) × 100

`n`は計算期間、`d`は各足における

「時間の順位」と「価格の順位」の差です。

差が小さいほど2つの順位が一致しており、RCIは+100に近づきます。

短期・中期・長期(9/26/52)を使い分ける考え方

期間を短くするほどRCIは敏感に反応し、長くするほど大きな流れを示します。

短期(9程度)でタイミングを計り、

中期・長期で大きなトレンドの向きを確認するという

複数期間の併用は、他の多くのオシレーターと同じ考え方です。

補足
・この記事ではまず単一期間での実装を扱います
・複数期間を使う場合は、同じ関数を期間だけ変えて複数回呼び出せば応用できます

RCIの計算ロジックをコードに落とし込む

実際にMQL4で順位相関を計算する関数を作ります。

価格を順位に変換する処理

if(Close[shift - period + 1 + j] > priceI)
   rank++;

価格が高い足の本数を数え、

その数+1を価格の順位にしています。

同じ価格(同値)が複数ある場合は、

簡易的に同順位として扱う実装です。

時間の順位との差を二乗して合計する

double d = timeRank - priceRank;
sumD2 += d * d;

直近の足ほど時間の順位を1に近づけ、

価格の順位との差を二乗して合計しています。

具体的な関数の全体は後述のコード全体で確認してください。

RCI値を-100〜100に正規化する式

最後に、合計した差の二乗和を公式に当てはめ、

-100〜+100の範囲に正規化します。

この範囲に収まることで、+80/-80という共通のしきい値で判断できるようになります。

閾値をまたいだ瞬間だけを矢印表示する設計

RCIの値が計算できたら、矢印表示する設計を作ります。

「状態」でなく「変化」を検知する設計思想

RCIが-80以下の「状態」が続く間ずっと矢印を出すと、

同じ方向の矢印が連続して見づらくなります。

この記事では、前の足では-80以下だったのに、

直近の足で-80を上回った「またいだ瞬間」だけを矢印にします。

SetIndexBuffer/SetIndexStyle(DRAW_ARROW)の設定

SetIndexStyle(0, DRAW_ARROW);
SetIndexArrow(0, 233);

矢印の記号コード233/234は、

既刊のCCI・OsMA矢印インジケーターと同じ組み合わせです。

確定足(shift=1)だけを判定する理由

形成中の0本目は値が変わり続けるため、

判定には必ず確定済みの1本目以降を使います。

未確定の足で判定すると、

同じ足の矢印が出たり消えたりする不具合の原因になります。

実際に動くコード全体

ここまでの要素をまとめたインジケーターの全体です。

//+------------------------------------------------------------------+
//|                                              RciArrowIndicator.mq4 |
//|                     Copyright 2026, FX-EA System Project Creator |
//|                        https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red

extern int    RCI_Period     = 9;
extern double RCI_Oversold   = -80.0;
extern double RCI_Overbought = 80.0;

double UpArrow[];
double DownArrow[];

int init()
  {
   SetIndexBuffer(0, UpArrow);
   SetIndexStyle(0, DRAW_ARROW);
   SetIndexArrow(0, 233);
   SetIndexEmptyValue(0, 0.0);

   SetIndexBuffer(1, DownArrow);
   SetIndexStyle(1, DRAW_ARROW);
   SetIndexArrow(1, 234);
   SetIndexEmptyValue(1, 0.0);
   return(0);
  }

int GetPriceRank(int shift, int period)
  {
   double priceI = Close[shift];
   int rank = 1;
   for(int j = 0; j < period; j++)
     {
      if(Close[shift - period + 1 + j] > priceI)
         rank++;
     }
   return(rank);
  }

double CalcRCI(int period, int baseShift)
  {
   double sumD2 = 0.0;
   for(int i = 0; i < period; i++)
     {
      int targetShift = baseShift + i;
      int priceRank   = GetPriceRank(targetShift, period);
      int timeRank    = i + 1;
      double d = timeRank - priceRank;
      sumD2 += d * d;
     }
   return((1.0 - 6.0 * sumD2 / (period * (period * period - 1.0))) * 100.0);
  }

int start()
  {
   int counted = IndicatorCounted();
   int limit = Bars - counted - 1;
   if(limit > Bars - RCI_Period - 3)
      limit = Bars - RCI_Period - 3;

   for(int shift = limit; shift >= 0; shift--)
     {
      UpArrow[shift]   = 0.0;
      DownArrow[shift] = 0.0;

      double rciNow  = CalcRCI(RCI_Period, shift + 1);
      double rciPrev = CalcRCI(RCI_Period, shift + 2);

      if(rciPrev <= RCI_Oversold && rciNow > RCI_Oversold)
         UpArrow[shift + 1] = Low[shift + 1] - 10 * Point;

      if(rciPrev >= RCI_Overbought && rciNow < RCI_Overbought)
         DownArrow[shift + 1] = High[shift + 1] + 10 * Point;
     }
   return(0);
  }

MetaEditorでのコンパイル・実行手順

実際にMT4へ適用するまでの手順を確認します。

  1. MetaEditorで新規カスタムインジケーター「RciArrowIndicator」を作成し、上のコードを貼り付けてコンパイルする
  2. MT4のナビゲーターからチャートへドラッグ&ドロップで適用する
  3. パラメータ画面でRCI_Period・RCI_Oversold・RCI_Overboughtを確認し、必要に応じて調整する
  4. -80以下から戻った足に青い矢印、+80以上から戻った足に赤い矢印が出ることを確認する

よくあるエラーと注意点

実装・運用でつまずきやすいポイントをまとめます。

配列範囲外エラーが出て計算が止まる

注意
・チャートの読み込み本数(Bars)が期間より少ないと配列範囲外エラーになります
・start()内のlimit計算で必ず余裕を持たせてください

レンジ相場で+80/-80に張り付いて矢印が出ない誤解

強いトレンドの局面でRCIが閾値に張り付いたまま動かないと、

「またいだ瞬間」が発生せず矢印も出ません。

これは不具合ではなく、設計どおりの挙動です。

MQL4とMQL5の違い

このコードはMQL4(init/start形式)を前提にしています。

MQL5ではOnInit/OnCalculate形式に書き換える必要があり、

配列アクセスもClose[]のような時系列配列ではなく、

CopyClose()で取得した配列を使う形に変わります。

よくある質問

RCIインジケーターの自作について、よく検索される疑問に回答します。

RCIは必ず3本(短期・中期・長期)表示しないといけませんか?

いいえ、必須ではありません。

まずは1本の実装で考え方を理解し、

必要であればRCI_Periodを変えて拡張できます。

同じ価格が並んだ場合(同値)はどう扱われますか?

このコードでは、同じ価格の足も

簡易的に同順位として数える実装にしています。

厳密なタイ処理までは行っていない点を開示しておきます。

RCIを使えば勝率は上がりますか?

断定はできません。

RCIは順位の一致度を示す指標であり、

他のオシレーターと同様にダマシも発生します。

損切り設定と組み合わせて使うことをおすすめします。

【MQL4】RCI(順位相関指数)を自作して買われすぎ・売られすぎを矢印表示するインジケーターの作り方:まとめ

RCIはMT4の標準関数にはありませんが、

Spearman順位相関の考え方に沿えば、

自分で計算して矢印表示までコード化できます。

状態ではなく「またいだ瞬間」だけを検知する設計にすることで、

矢印の出すぎをある程度抑えられます。

関連記事