首页 > 解决方案 > Highstock MACD 研究使用 sma 而不是 ema

问题描述

我正在使用 macd 图表研究,默认情况下它使用 sma。macd 应该使用 12 天和 26 天 ema 之间的差异来计算。我需要设置哪些参数才能使用 ema 而不是 sma?谢谢你。

标签: highcharts

解决方案


很遗憾,我不能同意你的说法。当然,macdindicator 继承了一些原型函数和默认参数sma,但是该getValues函数(负责计算值)被新函数覆盖,其中值以您上面描述的方式计算。这是该函数代码中最重要的部分:

               getValues: function (series, params) {
                    var j = 0,
                        MACD = [],
                        xMACD = [],
                        yMACD = [],
                        signalLine = [],
                        shortEMA,
                        longEMA,
                        i;

                    if (series.xData.length < params.longPeriod) {
                        return false;
                    }

                    // Calculating the short and long EMA used when calculating the MACD
                    shortEMA = EMA.prototype.getValues(series,
                        {
                            period: params.shortPeriod
                        }
                    );

                    longEMA = EMA.prototype.getValues(series,
                        {
                            period: params.longPeriod
                        }
                    );

                    shortEMA = shortEMA.values;
                    longEMA = longEMA.values;


                    // Subtract each Y value from the EMA's and create the new dataset
                    // (MACD)
                    for (i = 1; i <= shortEMA.length; i++) {
                        if (
                            defined(longEMA[i - 1]) &&
                            defined(longEMA[i - 1][1]) &&
                            defined(shortEMA[i + params.shortPeriod + 1]) &&
                            defined(shortEMA[i + params.shortPeriod + 1][0])
                            ) {
                            MACD.push([
                                shortEMA[i + params.shortPeriod + 1][0],
                                0,
                                null,
                                shortEMA[i + params.shortPeriod + 1][1] -
                                    longEMA[i - 1][1]
                            ]);
                        }
                    }

                    // Set the Y and X data of the MACD. This is used in calculating the
                    // signal line.
                    for (i = 0; i < MACD.length; i++) {
                        xMACD.push(MACD[i][0]);
                        yMACD.push([0, null, MACD[i][3]]);
                    }

                    // Setting the signalline (Signal Line: X-day EMA of MACD line).
                    signalLine = EMA.prototype.getValues(
                        {
                            xData: xMACD,
                            yData: yMACD
                        },
                        {
                            period: params.signalPeriod,
                            index: 2
                        }
                    );

                    signalLine = signalLine.values;

                    // Setting the MACD Histogram. In comparison to the loop with pure
                    // MACD this loop uses MACD x value not xData.
                    for (i = 0; i < MACD.length; i++) {
                        if (MACD[i][0] >= signalLine[0][0]) { // detect the first point

                            MACD[i][2] = signalLine[j][1];
                            yMACD[i] = [0, signalLine[j][1], MACD[i][3]];

                            if (MACD[i][3] === null) {
                                MACD[i][1] = 0;
                                yMACD[i][0] = 0;
                            } else {
                                MACD[i][1] = (MACD[i][3] - signalLine[j][1]);
                                yMACD[i][0] = (MACD[i][3] - signalLine[j][1]);
                            }

                            j++;
                        }
                    }

                    return {
                        values: MACD,
                        xData: xMACD,
                        yData: yMACD
                    };
                }

这是链接,您可以在其中查看macd.src.js指标的完整代码: https ://code.highcharts.com/stock/indicators/macd.src.js

亲切的问候!

[编辑]

在评论对话后,我们注意到 EMA 目前是根据openOHLC 数据集的值而不是close值计算得出的,这绝对是一个错误。我在我们的 GitHub 存储库中报告了新问题:https ://github.com/highcharts/highcharts/issues/8951 ,因此您可以看到修复它的进度,但它应该在即将推出的新 Highstock 版本 (v7) 中修复。

要解决它,您可以简单地覆盖该seriesTypes.macd.prototype.getValues函数,以便它index: 3在计算 short 和 long 时传递 in 参数EMA。这是在初始化任何图表之前应用的代码:

(function(H) {
  var EMA = H.seriesTypes.ema,
    defined = H.defined;

  H.seriesTypes.macd.prototype.getValues = function(series, params) {
    var j = 0,
      MACD = [],
      xMACD = [],
      yMACD = [],
      signalLine = [],
      shortEMA,
      longEMA,
      i;

    if (series.xData.length < params.longPeriod) {
      return false;
    }

    // Calculating the short and long EMA used when calculating the MACD
    shortEMA = EMA.prototype.getValues(series, {
      period: params.shortPeriod,
      index: 3
    });

    longEMA = EMA.prototype.getValues(series, {
      period: params.longPeriod,
      index: 3
    });

    shortEMA = shortEMA.values;
    longEMA = longEMA.values;


    // Subtract each Y value from the EMA's and create the new dataset
    // (MACD)
    for (i = 1; i <= shortEMA.length; i++) {
      if (
        defined(longEMA[i - 1]) &&
        defined(longEMA[i - 1][1]) &&
        defined(shortEMA[i + params.shortPeriod + 1]) &&
        defined(shortEMA[i + params.shortPeriod + 1][0])
      ) {
        MACD.push([
          shortEMA[i + params.shortPeriod + 1][0],
          0,
          null,
          shortEMA[i + params.shortPeriod + 1][1] -
          longEMA[i - 1][1]
        ]);
      }
    }

    // Set the Y and X data of the MACD. This is used in calculating the
    // signal line.
    for (i = 0; i < MACD.length; i++) {
      xMACD.push(MACD[i][0]);
      yMACD.push([0, null, MACD[i][3]]);
    }

    // Setting the signalline (Signal Line: X-day EMA of MACD line).
    signalLine = EMA.prototype.getValues({
      xData: xMACD,
      yData: yMACD
    }, {
      period: params.signalPeriod,
      index: 2
    });

    signalLine = signalLine.values;

    // Setting the MACD Histogram. In comparison to the loop with pure
    // MACD this loop uses MACD x value not xData.
    for (i = 0; i < MACD.length; i++) {
      if (MACD[i][0] >= signalLine[0][0]) { // detect the first point

        MACD[i][2] = signalLine[j][1];
        yMACD[i] = [0, signalLine[j][1], MACD[i][3]];

        if (MACD[i][3] === null) {
          MACD[i][1] = 0;
          yMACD[i][0] = 0;
        } else {
          MACD[i][1] = (MACD[i][3] - signalLine[j][1]);
          yMACD[i][0] = (MACD[i][3] - signalLine[j][1]);
        }

        j++;
      }
    }

    return {
      values: MACD,
      xData: xMACD,
      yData: yMACD
    };
  }
})(Highcharts)

现场示例:http: //jsfiddle.net/aL1bqn2f/


推荐阅读