Convert data to OHLC (Open, High, Low, Close) in JavaScript?

前端 未结 1 1114
隐瞒了意图╮
隐瞒了意图╮ 2020-12-11 11:22

Similar to create an OHLC data from Date, time, price using C#, how does one take the theory of converting basic trade data to OHLC (or Open, High, Low, Close) and apply it

相关标签:
1条回答
  • 2020-12-11 12:00

    This is a working function for converting the data to OHLC:

    function convertToOHLC(data) {
        data.sort((a, b) => d3.ascending(a.date, b.date));
        var result = [];
        var format = d3.timeFormat("%Y-%m-%d");
        data.forEach(d => d.date = format(new Date(d.date * 1000)));
        var allDates = [...new Set(data.map(d => d.date))];
        allDates.forEach(d => {
            var tempObject = {};
            var filteredData = data.filter(e => e.date === d);
            tempObject.date = d;
            tempObject.open = filteredData[0].price;
            tempObject.close = filteredData[filteredData.length - 1].price;
            tempObject.high = d3.max(filteredData, e => e.price);
            tempObject.low = d3.min(filteredData, e => e.price);
            result.push(tempObject);
        });
        return result;
    };
    

    Here is your updated fiddle: https://jsfiddle.net/mg9v89r2/

    Step by step explanation:

    First, we sort the original data array by the dates:

    data.sort((a, b) => d3.ascending(a.date, b.date));
    

    That's an important step when we deal with open and close later.

    After that, we convert the milliseconds to dates, as strings:

    var format = d3.timeFormat("%Y-%m-%d");
    data.forEach(d => d.date = format(new Date(d.date * 1000)));
    

    Doing this, we can filter all objects belonging to a given day. First, we create an array with all different days in your data:

    var allDates = [...new Set(data.map(d => d.date))];
    

    For each day of that array, we will call a function that will populate an empty array, named results:

    allDates.forEach(d => {
        var tempObject = {};
        var filteredData = data.filter(e => e.date === d);
        tempObject.date = d;
        tempObject.open = filteredData[0].price;
        tempObject.close = filteredData[filteredData.length - 1].price;
        tempObject.high = d3.max(filteredData, e => e.price);
        tempObject.low = d3.min(filteredData, e => e.price);
        result.push(tempObject);
    });
    

    In the above forEach, we create an empty object, and for each day in our allDates array, we filter the data:

    var filteredData = data.filter(e => e.date === d);
    

    And populate an temporary object with it:

    var tempObject = {};
    tempObject.date = d;
    tempObject.open = filteredData[0].price;
    tempObject.close = filteredData[filteredData.length - 1].price;
    tempObject.high = d3.max(filteredData, e => e.price);
    tempObject.low = d3.min(filteredData, e => e.price);
    

    After each iteration, we push that temporary object into results:

    result.push(tempObject);
    

    Finally, we return results.

    That huge data array in your fiddle, surprisingly, has only 2 days of data.

    0 讨论(0)
提交回复
热议问题