本記事のテーマ
本記事ではMQL5で書かれたマルチタイムフレームRSIのコードの解説をしていきます。
仕組みを理解することで、RSIだけでなく、ほかのインジケータのマルチタイムフレーム対応版を作れるようになります。
ソースコード
#property copyright "© shanch, 2020"
#property link "shanch2@gmail.com"
#property description "MTFRSI"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_width1 1
#property indicator_style1 STYLE_SOLID
input ENUM_TIMEFRAMES TimeFrame = PERIOD_H1;
input int Period = 14;
input ENUM_APPLIED_PRICE AppliedPrice = PRICE_CLOSE;
int hRsi;
double BufRsi[];
double BufTemp[];
int OnInit()
{
SetIndexBuffer(0, BufRsi, INDICATOR_DATA);
ArraySetAsSeries(BufRsi, true);
ArraySetAsSeries(BufTemp, true);
IndicatorSetInteger(INDICATOR_LEVELS,3);
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,30);
IndicatorSetDouble(INDICATOR_LEVELVALUE,1,50);
IndicatorSetDouble(INDICATOR_LEVELVALUE,2,70);
IndicatorSetDouble(INDICATOR_MINIMUM,0);
IndicatorSetDouble(INDICATOR_MAXIMUM,100);
hRsi = iRSI(NULL, TimeFrame, Period, AppliedPrice);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
IndicatorRelease(hRsi);
}
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[])
{
ArraySetAsSeries(time,true);
int limit = rates_total - prev_calculated;
if(limit == 0) limit= 1;
int shift = 0;
for(int i=0; i<limit; i++)
{
shift=iBarShift(_Symbol,TimeFrame,time[i]);
if(CopyBuffer(hRsi, 0, shift, 1, BufTemp) <= 0)
{
Print("Getting RSI failed! Error",GetLastError());
return(0);
}
else
{
BufRsi[i]=BufTemp[0];
}
}
for(int i=1; i<rates_total; i++)
{
if(iBarShift(NULL, TimeFrame, time[i]) > 0)
{
break;
}
BufRsi[i]=BufRsi[0];
}
return(rates_total);
}
初期化(22行目から39行目)
OnCalculate前半(57行目から77行目)
ポイントは66行目で、iBarShiftを使って、現在の時間が上位足では何本目のバーかを取得し、変数shiftに代入する点です。
68行目では、shiftの値を使って、上位足のRSIを取得し、75行目でその値を現在のチャートに表示させています。
わかりにくいので、現在足が5分足で、上位足が1時間足として、具体的な数字でみてみましょう。
例えば、現在が14:15だとしたら次のようになります。
i | time[i] | shift |
0 | 14:15 | 0 |
1 | 14:10 | 0 |
2 | 14:05 | 0 |
3 | 14:00 | 0 |
4 | 13:55 | 1 |
5 | 13:50 | 1 |
以下省略 | 以下省略 | 以下省略 |
OnCalculate後半(79行目から87行目)
OnCalclateの前半部分でほぼ出来上がっているのですが、このままだと1点問題があります。
最新の上位足のRSI値は確定していないので、下図の赤で囲った部分のようにギザギザになってしまいます。
time[i] | shift | 上位足RSI |
14:15 | 0 | 60 |
14:10 | 0 | 59 |
14:05 | 0 | 61 |
14:00 | 0 | 60 |
13:55 | 1 | 62 |
13:50 | 1 | 62 |
以下省略 | 以下省略 |
そこで、最新の上位足、すなわち、shift=0の時には最新のRSI値(下の表では60)で上書きする必要があります。それを行っているのが85行目になります。
shiftが1以上になったら値を変更する必要がないので、81行目でループを抜けています。
time[i] | shift | 上位足RSI |
14:15 | 0 | 60 |
14:10 | 0 | |
14:05 | 0 | |
14:00 | 0 | |
13:55 | 1 | 62 |
13:50 | 1 | 62 |
以下省略 | 以下省略 |
完成
こちらが5分足チャートに1時間足MTFRSIを表示した様子です。
今回はRSIを使いましたが、同じ感じで他のインジケータもマルチタイムフレーム対応にできますので、皆さんも独自のマルチタイムフレームインジケータを作ってみてください!