(async () => {

    // Load the dataset
    const data = await fetch(
        'https://demo-live-data.highcharts.com/aapl-ohlcv.json'
    ).then(response => response.json());

    // split the data set into ohlc and volume
    const ohlc = [],
        volume = [],
        dataLength = data.length;

    for (let i = 0; i < dataLength; i += 1) {
        ohlc.push([
            data[i][0], // the date
            data[i][1], // open
            data[i][2], // high
            data[i][3], // low
            data[i][4] // close
        ]);

        volume.push([
            data[i][0], // the date
            data[i][5] // the volume
        ]);
    }

    Highcharts.stockChart('container', {
        navigation: {
            bindings: {
                fibonacci: {
                    steps: [
                        function (e, annotation) {
                            const isNumber = Highcharts.isNumber,
                                options = annotation.options.typeOptions,
                                xAxis =
                                    isNumber(options.xAxis) &&
                                    this.chart.xAxis[options.xAxis],
                                yAxis =
                                    isNumber(options.yAxis) &&
                                    this.chart.yAxis[options.yAxis];
                            if (xAxis && yAxis) {
                                options.points[1].x = xAxis.toValue(
                                    e[xAxis.horiz ? 'chartX' : 'chartY']
                                );
                                annotation.update({
                                    typeOptions: {
                                        points: options.points,
                                        height: yAxis.toValue(
                                            e[yAxis.horiz ? 'chartX' : 'chartY']
                                        ) - (options.points[0].y || 0)
                                    }
                                });
                            }
                        }
                    ]
                }
            }
        },
        yAxis: [{
            labels: {
                align: 'left'
            },
            height: '80%',
            resize: {
                enabled: true
            }
        }, {
            labels: {
                align: 'left'
            },
            top: '80%',
            height: '20%',
            offset: 0
        }],
        tooltip: {
            shape: 'square',
            headerShape: 'callout',
            borderWidth: 0,
            shadow: false,
            positioner: function (width, height, point) {
                const chart = this.chart;
                let position;

                if (point.isHeader) {
                    position = {
                        x: Math.max(
                            // Left side limit
                            chart.plotLeft,
                            Math.min(
                                point.plotX + chart.plotLeft - width / 2,
                                // Right side limit
                                chart.chartWidth - width - chart.marginRight
                            )
                        ),
                        y: point.plotY
                    };
                } else {
                    position = {
                        x: point.series.chart.plotLeft,
                        y: point.series.yAxis.top - chart.plotTop
                    };
                }

                return position;
            }
        },
        series: [{
            type: 'ohlc',
            id: 'aapl-ohlc',
            name: 'AAPL Stock Price',
            data: ohlc
        }, {
            type: 'column',
            id: 'aapl-volume',
            name: 'AAPL Volume',
            data: volume,
            yAxis: 1
        }],
        responsive: {
            rules: [{
                condition: {
                    maxWidth: 800
                },
                chartOptions: {
                    rangeSelector: {
                        inputEnabled: false
                    }
                }
            }]
        }
    });
})();