Вопрос Highcharts.js: можно ли не рисовать линии за пределами гистограммы индикатора MACD? - PullRequest
0 голосов
/ 20 декабря 2018

Я разрабатываю проект с использованием библиотеки Highstock.js.У меня есть требование не рисовать линии за пределами гистограммы индикатора MACD (https://prnt.sc/lxjoit). В документации Highstock.js, связанной с индикатором MACD, есть macdLine API: https://api.highcharts.com/highstock/series.macd.macdLine, signalLine API: https://api.highcharts.com/highstock/series.macd.signalLine.zones. ТеAPI позволяет устанавливать цвета только для частей индикатора MACD, разделенных на ось Y. Таким образом, он не подходит. Из документации не ясно, можем ли мы рисовать линии индикатора 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
    }]
});

1 Ответ

0 голосов
/ 21 декабря 2018

К сожалению, индикатор 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

...