【问题标题】:Highcharts.js question: is it possible to not draw line beyond MACD indicator histogram?Highcharts.js 问题:是否可以在 MACD 指标直方图之外不画线?
【发布时间】:2018-12-20 17:00:11
【问题描述】:

我使用 Highstock.js 库开发了一个项目。我要求不要在 MACD 指标直方图 (https://prnt.sc/lxjoit) 之外画线。在与 MACD 指标相关的 Highstock.js 文档中,有 macdLine API:https://api.highcharts.com/highstock/series.macd.macdLine,signalLine API:https://api.highcharts.com/highstock/series.macd.signalLine.zones。这些 API 仅允许为除以 y 轴的 MACD 指标部分设置颜色。所以不适合。从文档中不清楚我们是否可以在直方图之外绘制 MACD 指标线。您知道是否可以实施以及如何实施?请指教。

这是 JSFiddle 中的现场演示,显示带有 MACD 指标的图表:http://jsfiddle.net/ogorobets/x3tcpq72/14/

var ohlc = JSON.parse(ohlcStringified),
    volume = JSON.parse(volumeStringified);
var wvapSerieData = [];    
var lastDayDate = new Date("December 6, 2018 00:00:00");
var lastDayDateTs = lastDayDate.getTime();

Highcharts.stockChart('container', {
    chart: {
        borderWidth: 1
    },
    title: {
        text: 'Volume Weighted Average Price (VWAP)'
    },
    legend: {
        enabled: true
    },
    yAxis: [{
        height: '30%'
    }, {
        top: '30%',
        height: '35%',
        offset: 0
    }, {
        top: '65%',
        height: '35%',
        offset: 0
    }],
    series: [{
        type: 'candlestick',
        id: 'candlestick',
        name: 'AAPL',
        data: ohlc,
        tooltip: {
            valueDecimals: 2
        }
    }, {
        type: 'column',
        id: 'volume',
        name: 'Volume',
        data: volume,
        yAxis: 1
    }, 
    {
        type: 'macd',
        color: '#f05f5f',
        linkedTo: 'candlestick',
        showInLegend: true,
        enableMouseTracking: true,
        dataGrouping: {
            enabled: false,
        },
        zones:[
            {
                value: 0,
                color: '#f05f5f',
            },
            {
                color: '#31c26d'
            }
        ],
        yAxis: 2
    }]
});

【问题讨论】:

    标签: highcharts indicator


    【解决方案1】:

    很遗憾,MACD 指标的设计目的不是为了在柱状图之外绘制 MACD 指标线。

    但是,您可以覆盖计算 MACD 值的方法,并删除超出直方图的第一个值。查看我在下面发布的代码和演示。

    添加到H.seriesTypes.macd.prototype.getValues 方法的行:

    // params.signalPeriod - 1 - amount of points beyond the histroram
    MACD.splice(0, params.signalPeriod - 1);
    xMACD.splice(0, params.signalPeriod - 1);
    yMACD.splice(0, params.signalPeriod - 1);
    

    整个包装代码:

    (function(H) {
      H.seriesTypes.macd.prototype.getValues = function(series, params) {
        var j = 0,
            EMA = H.seriesTypes.ema,
          merge = H.merge,
            defined = H.defined,
          correctFloat = H.correctFloat,
          MACD = [],
          xMACD = [],
          yMACD = [],
          signalLine = [],
          shortEMA,
          longEMA,
          i;
    
        if (series.xData.length < params.longPeriod + params.signalPeriod) {
          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] = correctFloat(MACD[i][3] -
                signalLine[j][1]);
              yMACD[i][0] = correctFloat(MACD[i][3] -
                signalLine[j][1]);
            }
    
            j++;
          }
        }
    
        MACD.splice(0, params.signalPeriod - 1);
        xMACD.splice(0, params.signalPeriod - 1);
        yMACD.splice(0, params.signalPeriod - 1);
    
        return {
          values: MACD,
          xData: xMACD,
          yData: yMACD
        };
      }
    })(Highcharts);
    

    演示:
    http://jsfiddle.net/1f2m0yz4/

    文档:
    https://www.highcharts.com/docs/extending-highcharts/extending-highcharts

    【讨论】:

    • 嗨 Wojciech,非常感谢!这真的很聪明:)
    猜你喜欢
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    相关资源
    最近更新 更多