crypto-nodes
Version:
232 lines (151 loc) • 4.91 kB
JavaScript
var md5 = require('md5');
var data_cache = {};
var moment = require('moment');
var request = require('request');
module.exports = function(RED) {
var app = global.app;
function cryptocompare_historic_data_api(sym_from, sym_to, exchange, frequency, callback) {
var url = 'https://min-api.cryptocompare.com/data/histo';
var limit = 0;
switch(frequency) {
default:
case 'latest':
url += 'minute';
limit = 1440;
break;
case 'minute':
limit = 1440;
url += frequency;
break;
case 'hour':
limit = 24;
url += frequency;
break;
case 'day':
limit = 30;
url += frequency;
break;
}
var query = {
fsym: sym_from,
tsym: sym_to,
e: exchange,
aggregate: 1,
limit: limit,
};
request({ url: url, qs: query }, function (error, response, body) {
if(response && response.statusCode && response.statusCode == 200) {
callback(false, body);
} else {
callback(true, error);
}
});
}
function getDataModel(config, frequency) {
var dataModel;
if(config.model_name && app.models[config.model_name]) {
return app.models[config.model_name];
}
switch(frequency) {
default:
case 'latest':
dataModel = app.models.CryptoDataLatest;
break;
case 'minute':
dataModel = app.models.CryptoDataMinute;
break;
case 'hour':
dataModel = app.models.CryptoDataHour;
break;
case 'day':
dataModel = app.models.CryptoDataDay;
break;
}
return dataModel;
}
function cache_update(model, code, data) {
}
function providerDataReader(config) {
RED.nodes.createNode(this,config);
config.node = this;
var node = this;
node.status({fill:"red",shape:"dot", text:"waiting for data"});
node.on('input', function(msg) {
var dataModel = config.setModel || getDataModel(config, config.frequency);
var exchange = msg.req.params.exchange || 'CCCAGG';
// 1. Try finding the data in our database..
console.log('Searching up to :: ' + new moment().add(-1, 'days').unix() + ' for ' + exchange + '/' + msg.req.params.from + '/' + msg.req.params.to);
dataModel.find({symbol: msg.req.params.from + '/' + msg.req.params.to, 'exchange': exchange, ts: {$gt: new moment().add(-1, 'days').unix()} }).then(function(data) {
console.log('Have in database :: ' + data.length || 0);
if(!data || data.length < 1000) {
// console.log(data);
cryptocompare_historic_data_api(msg.req.params.from, msg.req.params.to, exchange, config.frequency, function (e, data) {
if(e) {
// Received error
msg.payload = data;
node.send(msg);
} else {
// Data ok.. Lets fill the gaps and return to sender..
/*
console.log(data);
msg.payload = data;
node.send(msg);
*/
// Need to convert to following format
/*
{"time":1521983880,"close":8527.83,"high":8530.69,"low":8514.89,"open":8515.23,"volumefrom":41.74,"volumeto":355780.46}
TO
{ _id: '7c3ea36013ffe04cd0f0cbc6a5a99710',
__v: 0,
exchange: 'CCCAGG',
max: 8121.86,
min: 8111.4,
provider: 'CryptoCompare',
symbol: 'BTC/USD',
ts: 1522069867,
val: 8111.4
},
*/
var out = [];
var now = moment().unix();
try {
data = JSON.parse(data);
console.log('Received from provider :: ' + data.Data.length);
} catch(e) {
msg.payload = e;
node.send(msg);
return;
}
for(x in data.Data) {
var row_in = data.Data[x];
var row_out = {
_id: md5(row_in.time + '/' + exchange + '/' + msg.req.params.from + '/' + msg.req.params.to),
provider: 'CryptoCompare',
exchange: exchange,
symbol: msg.req.params.from + '/' + msg.req.params.to,
min: row_in.low,
max: row_in.high,
ts: row_in.time,
val: row_in.open // We save the starting point of res only (could save both but kinda pointless)
};
out.push(row_out);
}
dataModel.insertMany(out, { ordered: false }, function(err, docs) {
//console.log(err.message);
//console.log(docs);
});
//console.log(res);
//console.log(out);
msg.payload = out;
node.send(msg);
}
});
} else {
msg.payload = data;
node.send(msg);
}
});
});
}
RED.nodes.registerType("providerDataReader",providerDataReader);
}