サブウィンドウにRSI(ワイルダー方式)を表示されるコードを公開!

RSIを作って表示させるコード

RSI自体はMT5に標準搭載されていますので、標準搭載のRSIを利用すれば良いのですが、サインツールを作る上で、RSIが必要な場合もあります。

例えば、MQL5ではRSIが70以上の時にサインを出すと言うのは簡単なのですが、サインだけはイメージが付きにくのでRSIも同時に見たいものです。

その様な場合は標準のRSIを表示すれば良いのですが、サインツールを立ち上げた際にRSIも表示してくれた方が便利と言えます。

しかし、サインツールを立ち上げる際に標準のRSIを同時に立ち上げる事は出来ません。

その為、サインツールと同時にRSIを立ち上げたい場合はRSIを作る必要があります。

ワイルダー方式のRSIを表示させるコード

RSIを表示



//+------------------------------------------------------------------+
//| ワイルダー方式のRSI(MT5標準に近い挙動)                      |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_label1 "RSI_Wilder"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrOrange
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2

#property indicator_level1 30
#property indicator_level2 70
#property indicator_levelcolor clrSilver
#property indicator_levelstyle STYLE_DOT
#property indicator_levelwidth 1

input int RSIPeriod = 14;

double RSIBuffer[];

int OnInit()
{
    SetIndexBuffer(0, RSIBuffer, INDICATOR_DATA);
    IndicatorSetInteger(INDICATOR_DIGITS, 2);
    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[])
{
    if (rates_total < RSIPeriod + 1)
        return 0;

    int start = prev_calculated;
    if (start < RSIPeriod)
        start = RSIPeriod;

    double avgGain = 0.0, avgLoss = 0.0;

    if (prev_calculated == 0)
    {
        // 最初の平均をSMAで計算
        double gain = 0.0, loss = 0.0;
        for (int i = 1; i <= RSIPeriod; i++)
        {
            double change = close[i] - close[i - 1];
            if (change > 0)
                gain += change;
            else
                loss -= change;
        }

        avgGain = gain / RSIPeriod;
        avgLoss = loss / RSIPeriod;

        double rs = (avgLoss == 0) ? 0 : avgGain / avgLoss;
        RSIBuffer[RSIPeriod] = (avgLoss == 0) ? 100.0 : 100.0 - (100.0 / (1 + rs));

        start = RSIPeriod + 1;
    }
    else
    {
        avgGain = RSIBuffer[prev_calculated - 1]; // 直前のRSI値を再利用(便宜的に)
    }

    // ワイルダーの平滑化計算を開始
    for (int i = start; i < rates_total; i++)
    {
        double change = close[i] - close[i - 1];
        double gain = (change > 0) ? change : 0;
        double loss = (change < 0) ? -change : 0;

        avgGain = (avgGain * (RSIPeriod - 1) + gain) / RSIPeriod;
        avgLoss = (avgLoss * (RSIPeriod - 1) + loss) / RSIPeriod;

        double rs = (avgLoss == 0) ? 0 : avgGain / avgLoss;
        RSIBuffer[i] = (avgLoss == 0) ? 100.0 : 100.0 - (100.0 / (1 + rs));
    }

    return rates_total;
}


RSIコードの注意点

サインが張り付く

RSIのコードはいくつか問題があり、サインツールとRSIを同時に立ち上げようとするとサインがRSI側に張り付きます。

せっかくサインを出すならローソク足の方が良い場合もあります。

この問題を解決するにはサインを出すコードとRSIを出すコードを別々に作り、サインを出すコードを起動した際に、RSIを出すコードを外部ファイルとして読みこませる必要があります。

※うまく出来る方は同時に出来るかもしれません。

今回はRSIを出すコードのみ紹介していますが、後日RSIを外部ファイルとして読み込ませる方法も紹介したいと考えております。