勾选数据以分钟/小时OHLC Javascript

时间:2018-08-16 17:39:05

标签: javascript node.js trading

我有一组类似的滴答数据:

var data = [{
    "tid": 283945,
    "code": "0001",
    "time": 2018-08-02T04:24:53Z,
    "volume": "12000",
    "price": "501.30",
    "mode": "B"
}, {
    "tid": 283947,
    "code": "0001",
    "date": 2018-08-02T04:24:53Z,
    "amount": "1200000",
    "price": "490.66",
    "mode": "B"
},
...
];

而且我已经编写了创建每日OHLC的代码,如下所示:

function convertToOHLC(data) {
    data.sort((a, b) => d3.ascending(a.time, b.time));
    var result = [];
    data.forEach(d => {
        d.date = new Date(d.time).toISOString().substring(0,10);
    });

    var allDates = [...new Set(data.map(d => d.date))];
    allDates.forEach(d => {
        var tempObject = {};
        var filteredData = data.filter(e => e.date === d);
        var filteredBData = data.filter(e => e.date === d && e.mode === 'B');
        var filteredSData = data.filter(e => e.date === d && e.mode === 'S');
        tempObject.code = filteredData[0].code;
        tempObject.time = new 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);
        tempObject.volume = d3.sum(filteredData, e => e.volume);
        tempObject.bVolume = d3.sum(filteredBData, e => e.volume);
        tempObject.sVolume = d3.sum(filteredSData, e => e.volume);
        result.push(tempObject);
    });
    return result;
};

但是,我住在一个并非每分钟都有交易的国家,因此一分钟可能是空的。但是,记录它们可能仍然很有价值。除此之外,交易时间为9:30-12:30和14:30至17:30。无论有无交易,我如何为交易时间的每一分钟创建OHLC。

请检查previous post,对于以前没有明确要求我深表歉意。谢谢您的宝贵时间!

2 个答案:

答案 0 :(得分:1)

在编写小型应用程序时,效率无关紧要。现在很重要。新的解决方案避免了循环数据太多次。现在就像闪电一样快。

function convertToOHLC(data) {
    var code = data[0].code;
    data.sort((a, b) => d3.ascending(a.time, b.time));
    var result = [];
    data.forEach(d => {
        d.date = new Date(d.time).toISOString().substring(0,10);
    });

    var allDates = [...new Set(data.map(d => d.date))];
    allDates.forEach(d => {
    var minuteCounter = 0;
    var hourCounter = 9;
    var halfTime = new Date(new Date(d).setHours(12,30));
    var halfTimeBegin = new Date(new Date(d).setHours(14,30));
    var fullTime = new Date(new Date(d).setHours(17,00));
    while ( new Date(new Date(d).setHours(hourCounter,minuteCounter)) < fullTime) {
        if (new Date(new Date(d).setHours(hourCounter,minuteCounter)) < halfTime ||
            new Date(new Date(d).setHours(hourCounter,minuteCounter)) >= halfTimeBegin) {
            var currentTime = new Date(new Date(d).setHours(hourCounter,minuteCounter));
            var nextMinute = new Date(new Date(d).setHours(hourCounter,minuteCounter));
            nextMinute.setMinutes(nextMinute.getMinutes() + 1);
            var tempObject = {};
            var filteredData = [];
            var filteredBData = [];
            var filteredSData = [];
            for (var i = 0; i < data.length; i++) {
                if (data[i].time >= currentTime && data[i].time <= nextMinute) {
                    filteredData.push(data[i]);
                    if (data[i].mode === 'B') {
                        filteredBData.push(data[i]);
                    } else if (data[i].mode === 'S') {
                        filteredSData.push(data[i]);
                    }
                } else {
                    break;
                }
            }
            var matchedLength = filteredData.length;
            data = data.splice(matchedLength);
            tempObject.code = code;
            tempObject.time = currentTime;
            tempObject.open = filteredData[0] ? filteredData[0].price : 0;
            tempObject.close = filteredData[filteredData.length - 1] ? filteredData[filteredData.length - 1].price : 0;
            tempObject.high = d3.max(filteredData, e => e.price) || 0;
            tempObject.low = d3.min(filteredData, e => e.price) || 0;
            tempObject.volume = d3.sum(filteredData, e => e.volume) || 0;
            tempObject.bVolume = d3.sum(filteredBData, e => e.volume) || 0;
            tempObject.sVolume = d3.sum(filteredSData, e => e.volume) || 0;
            result.push(tempObject);
        }

        if (minuteCounter == 59) {
            hourCounter += 1;
            minuteCounter = 0;
        } else {
            minuteCounter += 1;
        }
    }

    })
    return result;
};

答案 1 :(得分:0)

我讨厌回答自己的问题。

function convertToOHLC(data) {
    var code = data[0].code;
    data.sort((a, b) => d3.ascending(a.time, b.time));
    var result = [];
    data.forEach(d => {
        d.date = new Date(d.time).toISOString().substring(0,10);
    });

    var allDates = [...new Set(data.map(d => d.date))];
    allDates.forEach(d => {
    var minuteCounter = 0;
    var hourCounter = 9;
    var halfTime = new Date(new Date(d).setHours(12,30)); // Market close for lunch
    var halfTimeBegin = new Date(new Date(d).setHours(14,30)); // Market reopen
    var fullTime = new Date(new Date(d).setHours(17,00)); // Market close for the day
    // Generate every minute for the day and populate them with data
    while ( new Date(new Date(d).setHours(hourCounter,minuteCounter)) < fullTime) {
        if (new Date(new Date(d).setHours(hourCounter,minuteCounter)) < halfTime ||
            new Date(new Date(d).setHours(hourCounter,minuteCounter)) >= halfTimeBegin) {
            var currentTime = new Date(new Date(d).setHours(hourCounter,minuteCounter));
            var nextMinute = new Date(new Date(d).setHours(hourCounter,minuteCounter));
            nextMinute.setMinutes(nextMinute.getMinutes() + 1);
            var tempObject = {};
            var filteredData = data.filter(e => e.time >= currentTime && e.time <= nextMinute);
        filteredData.forEach(f => data.splice(data.findIndex(e => e._id === f._id),1)); // Tries to improve performance by removing unused data
            var filteredBData = data.filter(e => e.time >= currentTime && e.time <= nextMinute && e.mode === 'B');
            var filteredSData = data.filter(e => e.time >= currentTime && e.time <= nextMinute && e.mode === 'S');
            tempObject.code = code;
            tempObject.time = currentTime;
            tempObject.open = filteredData[0] ? filteredData[0].price : 0;
            tempObject.close = filteredData[filteredData.length - 1] ? filteredData[filteredData.length - 1].price : 0;
            tempObject.high = d3.max(filteredData, e => e.price) || 0;
            tempObject.low = d3.min(filteredData, e => e.price) || 0;
            tempObject.volume = d3.sum(filteredData, e => e.volume) || 0;
            tempObject.bVolume = d3.sum(filteredBData, e => e.volume) || 0;
            tempObject.sVolume = d3.sum(filteredSData, e => e.volume) || 0;
            console.log(tempObject);
            result.push(tempObject);
        }

        if (minuteCounter == 59) {
            hourCounter += 1;
            minuteCounter = 0;
        } else {
            minuteCounter += 1;
        }
    }

    });
    return result;
};

但是,它非常慢,因此如果有人想加快速度,请在下面评论。谢谢!

相关问题