我有一组类似的滴答数据:
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,对于以前没有明确要求我深表歉意。谢谢您的宝贵时间!
答案 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;
};
但是,它非常慢,因此如果有人想加快速度,请在下面评论。谢谢!