iRVIは、RVI(Relative Vigor Index)の値を、

MQL4で直接取得できる組み込み関数です。

既刊のiAO・iAC・iForceは、いずれも移動平均の差や出来高を使って「勢い」

を測る指標でしたが、RVIは終値が始値からどれだけ強く離れたかを、

その日の値幅(高値-安値)に対する比率として捉える、別系統の考え方の指標です。

この記事では、iRVIの5つの引数を整理したうえで、

既刊の勢い系指標との計算対象の違いを明らかにし、

メイン線とシグナル線のクロスを矢印で知らせる、

実際に動くインジケーターの作り方を解説します。

この記事で分かること
・iRVIの5つの引数と戻り値の意味(mode引数の使い方)
・既刊iAO/iAC/iForceとの計算対象の違い
・MQL4とMQL5で引数構成・戻り値の種類が違う点
・実際に動くメイン線/シグナル線クロス矢印のコード

設計思想: RVIは「値幅に対する終値の位置」を測る指標

まず、RVIが既刊の勢い系指標と何が違うのかを整理します。

既刊iAO/iAC/iForceとの計算対象の違い

既刊のiAO(Awesome Oscillator)・

iAC(Accelerator/Decelerator)は、

中間値をもとにした2本の移動平均の差や、

その変化率を見る指標でした。

iForceは、価格変化に出来高を掛け合わせて勢いを測る指標でした。

RVIはこれらと違い、1本のローソク足が「始値から終値までどれだけ強く動いたか」

を、同じ足の値幅(高値-安値)で割った比率として捉えます。

指標 計算対象 示すもの
iAO(既刊) 中間値の2本のSMAの差 いまの勢いの大きさ
iAC(既刊) AOの変化率 勢いの変化(加速・減速)
iForce(既刊) 価格変化×出来高 出来高を含めた勢い
iRVI(本記事) (終値-始値)÷(高値-安値)の重み付き平均 値幅に対する終値の強さ

値幅で正規化することの意味

RVIが(終値-始値)をそのまま使わず、値幅(高値-安値)で割っているのは、

ボラティリティが高い時も低い時も、同じ基準で「終値の強さ」を比較できるようにするためです。

RVIの基本的な考え方
・終値が始値から大きく離れていても、値幅自体が広ければ『普通』の動き
・値幅が狭いのに終値が始値から大きく離れていれば『強い』動き
・RVIはこの比率を直近数本の重み付き平均で滑らかにした指標
・考案者はJohn Ehlersとして広く知られている
・具体的な重み付け計算式は公式リファレンスには記載がない

計算式の細部を自分で再現する必要はなく、

MQL4では`iRVI()`を呼ぶだけで、

この値が直接返ってきます。

iRVI関数の引数と戻り値

公式リファレンス(MQL4 Reference: iRVI)の内容を整理します。

5つの引数の意味

double iRVI(
   string symbol,     // 通貨ペア名(NULLで現在のチャート)
   int    timeframe,  // 時間足(0で現在の時間足)
   int    period,     // 計算用の平均化期間
   int    mode,       // ラインインデックス(MODE_MAIN または MODE_SIGNAL)
   int    shift        // 何本前のバーの値を取得するか
);

iAO・iACにはなかった`period`(平均化期間)と、

`mode`(どちらの線を取るか)が追加されている点が特徴です。

mode引数: MODE_MAINとMODE_SIGNAL

RVIはメイン線とシグナル線の2本を持つ指標で、

`mode`引数にどちらを取得するかを指定します。

定数 値 意味
MODE_MAIN 0 RVIのメイン線
MODE_SIGNAL 1 メイン線をさらに滑らかにしたシグナル線

この2値は、iMACDやiStochasticと共通の「ラインインデックス」

という定数体系に属しています。

MQL5版との違い: 戻り値が直接の値かハンドルか

MQL4のiRVIは、値をdoubleで直接返します。

一方、MQL5のiRVI(MQL5 Reference: iRVI)は、

値ではなくインジケーターのハンドル(int)を返します。

MQL5移行時の注意
・symbol+period+ma_periodの3引数だけで、mode引数が無い
・ハンドルを返すだけで、値はCopyBuffer()で別途取得する
・バッファ0がメイン線、バッファ1がシグナル線に固定
・MQL4のmodeはCopyBufferのバッファ番号に置き換わる

既刊のMQL4→MQL5移行チェックリストと同じ、

テクニカル指標のハンドル方式化という変化点が、

ここにも当てはまります。

サンプルインジケーター: メイン線・シグナル線のゴールデンクロス/デッドクロス

メイン線とシグナル線を2本のラインとして描画し、MACDと同じ発想で、

クロスした瞬間だけ矢印で知らせます。

メイン線・シグナル線の値を取得する

double main     = iRVI(NULL, 0, RviPeriod, MODE_MAIN,   i);
double signal   = iRVI(NULL, 0, RviPeriod, MODE_SIGNAL, i);
double mainPrev = iRVI(NULL, 0, RviPeriod, MODE_MAIN,   i + 1);
double sigPrev  = iRVI(NULL, 0, RviPeriod, MODE_SIGNAL, i + 1);

同じ`period`を指定したうえで、

`mode`だけを切り替えて2回呼び出す形になります。

ゴールデンクロス/デッドクロスの判定

前のバーではメイン線がシグナル線より下にあり、今のバーで上に抜けていればゴールデンクロス、

逆であればデッドクロスと判定します。

実際に動くコード全体

実際にMetaEditorでコンパイルできる、

RVIのメイン線・シグナル線とクロス矢印を表示するインジケーターです。

//+------------------------------------------------------------------+
//|                                                  RVICrossArrow.mq4 |
//|                     Copyright 2026, FX-EA System Project Creator |
//|                        https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link      "https://creator.fx-ea-system-project.com/"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 DodgerBlue
#property indicator_color2 Orange
#property indicator_color3 Lime
#property indicator_width3 2
#property indicator_color4 Red
#property indicator_width4 2

input int RviPeriod = 10;//RVIの平均化期間

double MainLine[];
double SignalLine[];
double GoldenCrossArrow[];
double DeadCrossArrow[];

int OnInit()
  {
   SetIndexBuffer(0, MainLine);
   SetIndexStyle(0, DRAW_LINE);

   SetIndexBuffer(1, SignalLine);
   SetIndexStyle(1, DRAW_LINE);

   SetIndexBuffer(2, GoldenCrossArrow);
   SetIndexStyle(2, DRAW_ARROW);
   SetIndexArrow(2, 233);
   SetIndexEmptyValue(2, EMPTY_VALUE);

   SetIndexBuffer(3, DeadCrossArrow);
   SetIndexStyle(3, DRAW_ARROW);
   SetIndexArrow(3, 234);
   SetIndexEmptyValue(3, EMPTY_VALUE);

   IndicatorShortName("RVI Cross Arrow(" + IntegerToString(RviPeriod) + ")");
   return(INIT_SUCCEEDED);
  }

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[])
  {
   int needed = RviPeriod + 10; // RVI内部の重み付き平均が遡る分の余裕
   if(rates_total < needed)
      return(0);

   int limit = (prev_calculated == 0) ? rates_total - needed : rates_total - prev_calculated + 1;

   for(int i = limit; i >= 0; i--)
     {
      double main     = iRVI(NULL, 0, RviPeriod, MODE_MAIN,   i);
      double signal   = iRVI(NULL, 0, RviPeriod, MODE_SIGNAL, i);
      double mainPrev = iRVI(NULL, 0, RviPeriod, MODE_MAIN,   i + 1);
      double sigPrev  = iRVI(NULL, 0, RviPeriod, MODE_SIGNAL, i + 1);

      MainLine[i]   = main;
      SignalLine[i] = signal;

      GoldenCrossArrow[i] = EMPTY_VALUE;
      DeadCrossArrow[i]   = EMPTY_VALUE;

      bool crossedUp   = (mainPrev <= sigPrev && main > signal);
      bool crossedDown = (mainPrev >= sigPrev && main < signal);

      if(crossedUp)
         GoldenCrossArrow[i] = main;
      if(crossedDown)
         DeadCrossArrow[i] = main;
     }

   return(rates_total);
  }

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

実際にMT4で動かすまでの手順です。

  1. MetaEditorで新規インジケーター「RVICrossArrow」を作成し、上のコードを貼り付けてコンパイルする
  2. エラー・警告が0件であることを確認する
  3. サブウィンドウに青(メイン線)とオレンジ(シグナル線)の2本のラインが表示されることを確認する
  4. メイン線がシグナル線を上に抜けたバーに緑の矢印、下に抜けたバーに赤の矢印が出ることを確認する
  5. 既刊iMACDのクロス矢印インジケーターと並べて表示し、クロスのタイミングがどれくらいずれるか見比べる

よくあるエラーと注意点

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

mode引数に数値をそのまま書いてしまう

`MODE_MAIN`・`MODE_SIGNAL`は定数名ですが、

数値(0・1)を直接書いても動作は同じです。

ただし可読性のため、数値のまま書かず定数名を使うことをおすすめします。

RVIをMACDと同じ感覚で扱ってしまう

メイン線とシグナル線のクロスという見た目はMACDと似ていますが、

RVIは値幅に対する終値の位置、MACDは2本の移動平均の差という、

全く別の計算対象です。

似た形のシグナルでも、意味を混同しないようにしてください。

needed本数が足りない状態で呼び出す

RVIはメイン線・シグナル線それぞれが内部で重み付き平均を行うため、

`period`で指定した本数よりやや多めの履歴が必要です。

ヒストリーが少ない通貨ペアでは、

rates_totalが足りているかの確認を省略しないでください。

既刊テクニカル指標記事との使い分け

似た「2本線クロス」型の記事が複数あるため、使い分けを整理します。

記事 計算対象 用途
本記事(iRVI) 値幅に対する終値の位置 ボラティリティ非依存の勢い判定
iMACD記事(既刊) 2本の移動平均の差 トレンドの方向転換
iStochastic記事(既刊) 直近高安に対する終値の位置 買われすぎ・売られすぎ
iForce記事(既刊) 価格変化×出来高 出来高を含めた勢い

よくある質問

iRVIについて、よくある疑問に回答します。

RVIとストキャスティクス、何が違いますか?

ストキャスティクスは一定期間の高値・安値に対する「現在の終値の位置」

を見ますが、RVIは1本ごとの「始値から終値への動き」を値幅で正規化する点が異なります。

着目する値動きの単位が、期間全体か1本ごとかという違いです。

このインジケーターをEAのフィルターに使えますか?

使えます。

本記事のクロス判定部分を関数化すれば、

「メイン線がシグナル線を上に抜けたらエントリーを許可する」

といった環境認識フィルターに組み込めます。

periodの値はどれくらいにすればよいですか?

公式リファレンスに推奨値の記載はなく、既刊のMACD・ストキャスティクス記事と同様、

通貨ペアや時間足によって最適値が変わるため、まずは標準値(10)で試し、

過去チャートで矢印の頻度を確認しながら調整してください。

【MQL4】iRVI(Relative Vigor Index)で終値の『勢い』を値幅で正規化して測るインジケーターの作り方:まとめ

iRVIは、既刊のiAO/iAC/iForceとは違い、

終値が始値からどれだけ強く離れたかを、

値幅(高値-安値)で正規化した別系統の勢い指標です。

mode引数でメイン線(MODE_MAIN)と、

シグナル線(MODE_SIGNAL)を切り替え、

2本のクロスを矢印で知らせるインジケーターとして実装しました。

MQL5では戻り値がハンドルに変わり、

mode引数が廃止されてCopyBufferのバッファ番号で区別する点に注意してください。

関連記事