MQL4では一般的なテクニカル指標の値を簡単に算出できるよう、組み込み関数が用意されております。
たとえば移動平均線であればiMA関数、ボリンジャーバンドであればiBands関数を使用することで、その値を容易に取得可能です。
個人的にRCIは比較的有名なテクニカル指標だと認識しているのですが、残念ながらMetaQuotes社はそう認識していないらしく、MQL4の組み込み関数としてiRCIといった関数は用意されていません。
RCIのように組み込み関数が用意されていないテクニカル指標の値を取得する場合、通常はiCustom関数を使用します。
iCustom関数はMT4内に保存しているインジケーターを指定し、その計算結果を取得することができる関数です。
予めRCIをMT4に保存しておくことで、RCIの結果を取得できます。
しかしプログラム内でiCustom関数を使用することがネガティブに感じる場面もありますので、直接RCIの値を取得できるiRCI関数を作成しました。
iRCI関数
double iRCI(const string symbol, int timeframe, int period, int index)
{
int rank;
double d = 0;
double close_arr[];
ArrayResize(close_arr, period);
for (int i = 0; i < period; i++) {
close_arr[i] = iClose(symbol, timeframe, index + i);
}
ArraySort(close_arr, WHOLE_ARRAY, 0, MODE_DESCEND);
for (int j = 0; j < period; j++) {
rank = ArrayBsearch(close_arr,
iClose(symbol, timeframe, index + j),
WHOLE_ARRAY,
0,
MODE_DESCEND);
d += MathPow(j - rank, 2);
}
return((1 - 6 * d / (period * (period * period - 1))) * 100);
}
第一引数はRCIを取得するチャートの通貨ペア名、第二引数は時間足です。
第三引数がRCIを算出する期間、第四引数がRCIを算出するローソク足の位置(最新のローソク足を0とした値)となっております。
特に変わった処理をしているわけではなく、RCIの定義通りに処理しているだけです。
パラメーターの名称や順序は他の組み込み関数と似た感覚で使用できるよう配慮して作成しましたので、MQL4を少しイジったことのある人であれば、すんなりと受け入れていただける構成かと思います。
iCustom関数の使用がネガティブなケース
ここからは余談です。
今回iCustom関数を使用せず、iRCI関数を用意した経緯について解説します。
iCustom関数の欠点として、呼び出す対象となるインジケーターが同一のMT4内に保存されている必要があります。
このためiCustom関数からRCIを使用したプログラムを配布する際には、インジケーターファイルRCI.ex4も一緒に配布する手間が増えます。
配布するファイルが増えると説明の手間も増えますし、利用者がRCIを正しく保存しなかったために異常な挙動が起きたといったトラブルの発生も考えられます。
上記の問題には解決方法があり、#resourceを使用してコンパイル時にRCI.ex4自体プログラム内に取り込むことがMQL4では可能です。
これによりRCI.ex4が存在しないMT4でもRCIの値を正しく取得して動作可能ですので、利用者へ配布時にRCI.ex4を配布する必要はなくなります。
ただし#resourceを使用する場合、コンパイル時にはRCI.ex4が存在している必要があります。
開発者の方がご自分でコンパイルして配布する分には問題になることはありませんが、そのプログラムがクライアントから依頼を請けて作成しているファイルの場合は問題が発生します。
クライアントにソースコードを納品している場合、クライアント側でほぼ確実にコンパイルが行われます。
このときRCI.ex4が必要となるので、納品時にRCI.ex4も納品する必要があります。
納品するファイルが増えますと、先程と同じく説明の手間が増える・利用者(この場合クライアント)のミスによるトラブル発生の確率が高まるといった問題が発生します。
この問題を避けるためには、関数として作成し、1つのファイルで完結したプログラムとして作成することが望ましかったので今回iRCI関数を作成しました。