【MQL5】ZigZag的なインジケータを作ってみる③

当ページのリンクには広告が含まれています。
目次

作るもの

前回、平均足を使って ZigZag的な波形を描いてみて、ちょっといまいちだったのですが、平滑平均足なら良いかもと思ったので試してみます。

平滑平均足って、「Heikin-Ashi Smoothed」と「Smoothed Heikin-Ashi」のどっちが正しいのか分からないんですよね。
開発した人がどう呼んでるのか調べるのが良いんでしょうけど、参考にしたサイトには「Heiken Ashi Smoothed」と表記されていたので......この記事では「Heikin-Ashi Smoothed」とします。

参考サイト

実装

やることは前回とほぼ一緒で、平均足の代わりに Heikin-Ashi Smoothed を使用します。
Heikin-Ashi Smoothed は、前述の参考サイトからダウンロードしたものを使用しました。

コード全体を示します。

//+------------------------------------------------------------------+
//|                                                     ZigZaaag.mq5 |
//|                                            Copyright 2024, Hailu |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Hailu"
#property link      "https://www.mql5.com"
#property version   "1.02"
#property indicator_chart_window

#property indicator_buffers 3
#property indicator_plots   1

#property indicator_type1   DRAW_SECTION
#property indicator_color1  clrWhiteSmoke
#property indicator_width1  2

double bufZig[];
double bufOpen[];
double bufClose[];

int hHeiken = 0;
datetime prevDt = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    // 平均足インジケータを作成
    hHeiken = iCustom(NULL, 0, "Heiken Ashi Smoothed");
    if (hHeiken == INVALID_HANDLE)
    {
        PrintFormat("[E] Failed to create Heiken_Ashi indicator. [%d]", GetLastError());
        return INIT_FAILED;
    }

    SetIndexBuffer(0, bufZig, INDICATOR_DATA);
    SetIndexBuffer(1, bufOpen, INDICATOR_CALCULATIONS);
    SetIndexBuffer(2, bufClose, INDICATOR_CALCULATIONS);

    PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);

    prevDt = 0;

    return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
{
    // 平均足を取得
    CopyBuffer(hHeiken, 0, 0, rates_total, bufOpen);
    CopyBuffer(hHeiken, 3, 0, rates_total, bufClose);

    int start = 1;
    if(prev_calculated == 0)
    {
        bufZig[0] = 0;
    }
    else
    {
        // 直前の陽線群または陰線群の開始位置を、処理開始位置とする
        int il = prev_calculated - 1;
        if (bufOpen[il] >= bufClose[il])
        {
            for (int i = il - 1; i >= 0; i--)
            {
                if (bufOpen[i] < bufClose[i])
                {
                    start = i;
                    break;
                }
            }
        }
        else
        {
            for (int i = il - 1; i >= 0; i--)
            {
                if (bufOpen[i] > bufClose[i])
                {
                    start = i;
                    break;
                }
            }
        }
    
        start = MathMax(start, 1);
    }

    for(int i = start; i < rates_total; i++)
    {
        int ip = i - 1;

        // 平均足が陽線から陰線に切替わった
        if ((bufOpen[ip] <= bufClose[ip]) && (bufOpen[i] > bufClose[i]))
        {
            double h = high[ip];
            bufZig[ip] = 0;

            // 陽線群の最高値を検索
            for (int j = i - 2; j >= 0; j--)
            {
                if (bufOpen[j] <= bufClose[j])
                {
                    bufZig[j] = 0;

                    if (high[j] > h)
                    {
                        ip = j;
                        h = high[j];
                    }
                }
                else
                    break;
            }

            bufZig[ip] = h;
        }
        // 平均足が陰線から陽線に切替わった
        else if ((bufOpen[ip] >= bufClose[ip]) && (bufOpen[i] < bufClose[i]))
        {
            double l = low[ip];
            bufZig[ip] = 0;

            // 陰線群の最安値を検索
            for (int j = i - 2; j >= 0; j--)
            {
                if (bufOpen[j] >= bufClose[j])
                {
                    bufZig[j] = 0;

                    if (low[j] < l)
                    {
                        ip = j;
                        l = low[j];
                    }
                }
                else
                    break;
            }

            bufZig[ip] = l;
        }
    }

    return rates_total;
}
//+------------------------------------------------------------------+

これをチャートに乗せてみると、次のようになります。

緑の点線   : ZigZag (Depth=5, Back Step=3)

オレンジの点線: 前回の (平均足を使用して描いた) ZigZag的インジケータ

白の実線   : 今回の ZigZag的インジケータ

それぞれの良いところだけを採用したい...
結局、自分で引くしかないか...(´・ω・`)

ZigZag的インジケータの開発は、一旦ここまでとします。
また何かアイデアを思いついたら試してみます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA



reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

目次