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はこの比率を直近数本の重み付き平均で滑らかにした指標
・考案者は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)を返します。
・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で動かすまでの手順です。
- MetaEditorで新規インジケーター「RVICrossArrow」を作成し、上のコードを貼り付けてコンパイルする
- エラー・警告が0件であることを確認する
- サブウィンドウに青(メイン線)とオレンジ(シグナル線)の2本のラインが表示されることを確認する
- メイン線がシグナル線を上に抜けたバーに緑の矢印、下に抜けたバーに赤の矢印が出ることを確認する
- 既刊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のバッファ番号で区別する点に注意してください。
コメント