问题
I'm attempting to use the script in Convert data to OHLC (Open, High, Low, Close) in JavaScript? to convert some chart data to OHLC. The only thing is that my data differs a bit from the original (http://api.bitcoincharts.com/v1/csv/localbtcDKK.csv.gz - showing all bitcoin trades ever done in Denmark), so how would I have to go about modifying the code?
Original data
var data = [{"tid": 283945, "date": 1384934366, "amount": "0.08180000", "price": "501.30"}, {"tid": 283947, "date": 1384934066, "amount": "0.06110000", "price": "490.66"}, ...];
New data
// CSV format: UNIX timestamp, price, amount traded
// http://api.bitcoincharts.com/v1/csv/localbtcDKK.csv.gz
var data = `1366383202,748.680000000000,1.000000000000
1366471506,777.440000000000,2.700000000000
1368121200,685.740000000000,2.187400000000
...`
Since it's CSV I've included jquery-csv for turning the data into an array. Here's my current code (https://jsfiddle.net/askhflajsf/mg9v89r2/5/):
// CSV format: UNIX timestamp, price, amount traded
// http://api.bitcoincharts.com/v1/csv/localbtcDKK.csv.gz
var data = `1366383202,748.680000000000,1.000000000000
1366471506,777.440000000000,2.700000000000
1368121200,685.740000000000,2.187400000000
1375783458,619.500000000000,1.000000000000
...`
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
}
// Parse multi-line CSV string into a 2D array
// https://github.com/evanplaice/jquery-csv
var dataArray = $.csv.toArrays(data);
// jquery-csv's arrays are made up of strings, but we need them to be numbers
// Trim whitespace and then convert to Number
var dataArrayNumbers = dataArray.map(row => row.map(el => Number(el.trim())));
console.log(convertToOHLC(dataArrayNumbers));
回答1:
The most important thing you have to do is adding headers to that data. Like this:
var data = `date,price,amount
1366383202,748.680000000000,1.000000000000
1366471506,777.440000000000,2.700000000000
//etc...
Without the headers, none of those properties will work.
Also, you don't need jQuery here. You can simply use D3:
var parsedArray = d3.csvParse(data)
If, for whatever reason, you cannot change your data to add the headers, you can add then in the code:
var headers = ["date", "price", "amount"];
var parsedArray = d3.csvParse(headers + "\n" + data)
Here is the demo with those changes:
var csv = `date,price,amount
1366383202,748.680000000000,1.000000000000
1366471506,777.440000000000,2.700000000000
1368121200,685.740000000000,2.187400000000
1375783458,619.500000000000,1.000000000000`;
var originalData = d3.csvParse(csv)
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
}
console.log(convertToOHLC(originalData))
<script src="//d3js.org/d3.v4.min.js"></script>
来源:https://stackoverflow.com/questions/46420571/convert-csv-to-ohlc-open-high-low-close-in-javascript