Comparing version 0.2.0 to 0.3.0
@@ -1,7 +0,1 @@ | ||
/* | ||
* index.js | ||
*/ | ||
'use strict'; | ||
exports = module.exports = require('./lib'); |
2214
lib/data.js
@@ -1,1426 +0,998 @@ | ||
/* | ||
* lib/data.js | ||
*/ | ||
var url = require('url'); | ||
var util = require('util'); | ||
'use strict'; | ||
var _ = require('lodash'); | ||
var debug = require('debug')('eoddata:data'); | ||
var moment = require('moment'); | ||
var Promise = require('bluebird'); | ||
var request = require('request'); | ||
var xml2js = require('xml2js'); | ||
var url = require('url'), | ||
util = require('util'); | ||
request = Promise.promisifyAll(request); | ||
xml2js = Promise.promisifyAll(xml2js); | ||
var _ = require('lodash'), | ||
async = require('async'), | ||
moment = require('moment'), | ||
Q = require('q'), | ||
request = require('request'), | ||
xml2js = require('xml2js'); | ||
function Data(config) { | ||
this._config = _getConfig(config); | ||
this._tokenPromise = null; | ||
this._tokenTime = null; | ||
} | ||
var debug = require('debug')('eoddata:data'); | ||
var Data = function (config) { | ||
this._config = _.isPlainObject(config) ? config : {}; | ||
this._taskQueue = async.queue(function (task, next) { | ||
task.run(next); | ||
}); | ||
_.defaults(this._config, { | ||
function _getConfig(config) { | ||
var result = _.clone(config); | ||
if (!_.isPlainObject(result)) { result = {}; } | ||
_.defaults(result, { | ||
endpoint: 'http://ws.eoddata.com/data.asmx/', | ||
timeout: 30000 | ||
requestTimeout: 15000, | ||
tokenCache: true, | ||
tokenExpiryInterval: 30000, | ||
username: null, | ||
password: null | ||
}); | ||
}; | ||
return result; | ||
} | ||
Data.prototype._getToken = function (cb) { | ||
debug('Logging In...'.cyan); | ||
request.post({ | ||
url: url.resolve(this._config.endpoint, 'Login'), | ||
form: { | ||
'Username': this._config.username, | ||
'Password': this._config.password | ||
}, | ||
timeout: this._config.timeout | ||
}, function (err, res, body) { | ||
if (err) { return cb(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return cb(err); } | ||
if (!result.LOGINRESPONSE.$.Token) { | ||
return cb(new Error( | ||
util.format('Failed to login: %s', | ||
result.LOGINRESPONSE.$.Message) | ||
)); | ||
} | ||
var token = result.LOGINRESPONSE.$.Token; | ||
debug(('Login Token: ' + token).yellow); | ||
return cb(null, token); | ||
}); | ||
function _getToken() { | ||
if (this._config.tokenCache && this._tokenPromise) { | ||
if (Date.now() - this._tokenTime >= this._config.tokenExpiryInterval) { | ||
this._tokenPromise = null; | ||
} else { | ||
return cb(new Error( | ||
util.format('Failed to login: status %d', | ||
res.statusCode) | ||
)); | ||
return this._tokenPromise; | ||
} | ||
}); | ||
}; | ||
} | ||
debug('Getting a token...'); | ||
this._tokenTime = Date.now(); | ||
var promise = this._tokenPromise = Promise.bind(this) | ||
.then(function () { | ||
return _request.call(this, 'Login', { | ||
Username: this._config.username, | ||
Password: this._config.password | ||
}); | ||
}) | ||
.then(function (result) { | ||
if (!result.LOGINRESPONSE.$.Token) { | ||
throw new Error( | ||
util.format('Failed to login: %s', | ||
result.LOGINRESPONSE.$.Message) | ||
); | ||
} | ||
var token = result.LOGINRESPONSE.$.Token; | ||
debug(util.format('Login Token: %s', token)); | ||
return token; | ||
}) | ||
.tap(function (token) { | ||
this._tokenTime = Date.now(); | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format('Failed to login: %s', err.message)); | ||
}); | ||
return promise; | ||
} | ||
Data.prototype.getCountryList = function (cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading CountryList...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'CountryList'), | ||
form: { | ||
'Token': token | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
function _request(urlPath, formData) { | ||
return Promise.bind(this) | ||
.then(function () { | ||
return request.postAsync({ | ||
url: url.resolve(this._config.endpoint, urlPath), | ||
form: formData || {}, | ||
timeout: this._config.timeout | ||
}).spread(function (res, body) { | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.COUNTRIES) { | ||
e = new Error(util.format( | ||
'Failed to get CountryList: %s', | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var countries = {}; | ||
if (result.RESPONSE.COUNTRIES[0].CountryBase) { | ||
result.RESPONSE.COUNTRIES[0].CountryBase.forEach(function (country) { | ||
countries[country.$.Code] = country.$.Name; | ||
}); | ||
} | ||
debug(util.format('CountryList: %d', | ||
_.keys(countries).length).yellow); | ||
return _.isFunction(cb) ? cb(null, countries) : dfd.resolve(countries); | ||
}); | ||
return xml2js.parseStringAsync(body); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get CountryList: status %d', | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
throw new Error(util.format('status %d', res.statusCode)); | ||
} | ||
}); | ||
}); | ||
}}); | ||
} | ||
return dfd.promise; | ||
function _requestWithToken(urlPath, formData) { | ||
return Promise.bind(this) | ||
.then(_getToken) | ||
.then(function (token) { | ||
if (formData) { | ||
_.assign(formData, { | ||
Token: token | ||
}); | ||
} | ||
return _request.call(this, urlPath, formData); | ||
}); | ||
} | ||
Data.prototype.getCountryList = function (cb) { | ||
debug('Downloading CountryList...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'CountryList', {}); | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.COUNTRIES) { | ||
throw new Error(util.format( | ||
'Failed to get CountryList: %s', | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var countries = {}; | ||
if (result.RESPONSE.COUNTRIES[0].CountryBase) { | ||
result.RESPONSE.COUNTRIES[0].CountryBase.forEach(function (country) { | ||
countries[country.$.Code] = country.$.Name; | ||
}); | ||
} | ||
debug(util.format('CountryList: %d', | ||
_.keys(countries).length)); | ||
return countries; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get CountryList: %s', | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getDataFormats = function (cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading DataFormats...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'DataFormats'), | ||
form: { | ||
'Token': token | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.DATAFORMATS) { | ||
e = new Error(util.format( | ||
'Failed to get DataFormats: %s', | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var dataFormats = {}; | ||
if (result.RESPONSE.DATAFORMATS[0].DATAFORMAT) { | ||
result.RESPONSE.DATAFORMATS[0].DATAFORMAT.forEach(function (dataFormat) { | ||
dataFormats[dataFormat.$.Code] = dataFormat.$; | ||
}); | ||
} | ||
debug(util.format('DataFormats: %d', _.keys(dataFormats).length).yellow); | ||
return _.isFunction(cb) ? cb(null, dataFormats) : dfd.resolve(dataFormats); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get DataFormats: status %d', | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
debug('Downloading DataFormats...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'DataFormats', {}); | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.DATAFORMATS) { | ||
throw new Error(util.format( | ||
'Failed to get DataFormats: %s', | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var dataFormats = {}; | ||
if (result.RESPONSE.DATAFORMATS[0].DATAFORMAT) { | ||
result.RESPONSE.DATAFORMATS[0].DATAFORMAT.forEach(function (dataFormat) { | ||
dataFormats[dataFormat.$.Code] = dataFormat.$; | ||
}); | ||
} | ||
debug(util.format('DataFormats: %d', _.keys(dataFormats).length)); | ||
return dataFormats; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get DataFormats: %s', | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getExchangeGet = function (exchangeCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading ExchangeGet...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'ExchangeGet'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.EXCHANGE) { | ||
e = new Error(util.format( | ||
'Failed to get ExchangeGet (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var exchange = result.RESPONSE.EXCHANGE[0].$; | ||
debug(util.format('ExchangeGet (%s)', exchangeCode).yellow); | ||
return _.isFunction(cb) ? cb(null, exchange) : dfd.resolve(exchange); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get ExchangeGet (%s): status %d', | ||
exchangeCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading ExchangeGet...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'ExchangeGet', { | ||
Exchange: exchangeCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.EXCHANGE) { | ||
throw new Error(util.format( | ||
'Failed to get ExchangeGet (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var exchange = result.RESPONSE.EXCHANGE[0].$; | ||
debug(util.format('ExchangeGet (%s)', exchangeCode)); | ||
return exchange; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get ExchangeGet (%s): %s', | ||
exchangeCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getExchangeList = function (cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading ExchangeList...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'ExchangeList'), | ||
form: { | ||
'Token': token | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.EXCHANGES) { | ||
e = new Error(util.format( | ||
'Failed to get ExchangeList: %s', | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var exchanges = {}; | ||
if (result.RESPONSE.EXCHANGES[0].EXCHANGE) { | ||
result.RESPONSE.EXCHANGES[0].EXCHANGE.forEach(function (exchange) { | ||
exchanges[exchange.$.Code] = exchange.$; | ||
}); | ||
} | ||
debug(util.format('ExchangeList: %d', | ||
_.keys(exchanges).length).yellow); | ||
return _.isFunction(cb) ? cb(null, exchanges) : dfd.resolve(exchanges); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get ExchangeList: status %d', | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
debug('Downloading ExchangeList...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'ExchangeList', {}); | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.EXCHANGES) { | ||
throw new Error(util.format( | ||
'Failed to get ExchangeList: %s', | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var exchanges = {}; | ||
if (result.RESPONSE.EXCHANGES[0].EXCHANGE) { | ||
result.RESPONSE.EXCHANGES[0].EXCHANGE.forEach(function (exchange) { | ||
exchanges[exchange.$.Code] = exchange.$; | ||
}); | ||
} | ||
debug(util.format('ExchangeList: %d', | ||
_.keys(exchanges).length)); | ||
return exchanges; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get ExchangeList: %s', | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getFundamentalList = function (exchangeCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading FundamentalList...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'FundamentalList'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.FUNDAMENTALS) { | ||
e = new Error(util.format( | ||
'Failed to get FundamentalList (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var fundamentals = {}; | ||
if (result.RESPONSE.FUNDAMENTALS[0].FUNDAMENTAL) { | ||
result.RESPONSE.FUNDAMENTALS[0].FUNDAMENTAL.forEach(function (fundamental) { | ||
fundamentals[fundamental.$.Symbol] = fundamental.$; | ||
}); | ||
} | ||
debug(util.format('FundamentalList (%s): %d', | ||
exchangeCode, | ||
_.keys(fundamentals).length).yellow); | ||
return _.isFunction(cb) ? cb(null, fundamentals) : dfd.resolve(fundamentals); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get FundamentalList (%s): status %d', | ||
exchangeCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading FundamentalList...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'FundamentalList', { | ||
Exchange: exchangeCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.FUNDAMENTALS) { | ||
throw new Error(util.format( | ||
'Failed to get FundamentalList (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var fundamentals = {}; | ||
if (result.RESPONSE.FUNDAMENTALS[0].FUNDAMENTAL) { | ||
result.RESPONSE.FUNDAMENTALS[0].FUNDAMENTAL.forEach(function (fundamental) { | ||
fundamentals[fundamental.$.Symbol] = fundamental.$; | ||
}); | ||
} | ||
debug(util.format('FundamentalList (%s): %d', | ||
exchangeCode, | ||
_.keys(fundamentals).length)); | ||
return fundamentals; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get FundamentalList (%s): %s', | ||
exchangeCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getQuoteGet = function (exchangeCode, symbolCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading QuoteGet...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'QuoteGet'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'Symbol': symbolCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTE) { | ||
e = new Error(util.format( | ||
'Failed to get QuoteGet (%s:%s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quote = result.RESPONSE.QUOTE[0].$; | ||
debug(util.format('QuoteGet (%s:%s)', | ||
exchangeCode, | ||
symbolCode).yellow); | ||
return _.isFunction(cb) ? cb(null, quote) : dfd.resolve(quote); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get QuoteGet (%s:%s): status %d', | ||
exchangeCode, | ||
symbolCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading QuoteGet...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'QuoteGet', { | ||
Exchange: exchangeCode, | ||
Symbol: symbolCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTE) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteGet (%s:%s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quote = result.RESPONSE.QUOTE[0].$; | ||
debug(util.format('QuoteGet (%s:%s)', exchangeCode, symbolCode)); | ||
return quote; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteGet (%s:%s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getQuoteList = function (exchangeCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading QuoteList...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'QuoteList'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES) { | ||
e = new Error(util.format( | ||
'Failed to get QuoteList (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes[quote.$.Symbol] = quote.$; | ||
}); | ||
} | ||
debug(util.format('QuoteList (%s): %d', | ||
exchangeCode, | ||
_.keys(quotes).length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get QuoteList (%s): status %d', | ||
exchangeCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading QuoteList...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'QuoteList', { | ||
Exchange: exchangeCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteList (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes[quote.$.Symbol] = quote.$; | ||
}); | ||
} | ||
debug(util.format('QuoteList (%s): %d', | ||
exchangeCode, | ||
_.keys(quotes).length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteList (%s): %s', | ||
exchangeCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getQuoteList2 = function (exchangeCode, symbolCodes, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
symbolCodes = (_.isArray(symbolCodes) ? symbolCodes : [symbolCodes]); | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading QuoteList2...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'QuoteList2'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'Symbols': symbolCodes.join(',') | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES) { | ||
e = new Error(util.format( | ||
'Failed to get QuoteList2 (%s:%s): %s', | ||
exchangeCode, | ||
symbolCodes.join(','), | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes[quote.$.Symbol] = quote.$; | ||
}); | ||
} | ||
debug(util.format('QuoteList2 (%s:%s): %d', | ||
exchangeCode, | ||
symbolCodes.join(','), | ||
_.keys(quotes).length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get QuoteList2 (%s:%s): status %d', | ||
exchangeCode, | ||
symbolCodes.join(','), | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading QuoteList2...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'QuoteList2', { | ||
Exchange: exchangeCode, | ||
Symbols: symbolCodes.join(',') | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteList2 (%s:%s): %s', | ||
exchangeCode, | ||
symbolCodes.join(','), | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes[quote.$.Symbol] = quote.$; | ||
}); | ||
} | ||
debug(util.format('QuoteList2 (%s:%s): %d', | ||
exchangeCode, | ||
symbolCodes.join(','), | ||
_.keys(quotes).length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteList2 (%s:%s): %s', | ||
exchangeCode, | ||
symbolCodes.join(','), | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getQuoteListByDate = function (exchangeCode, quoteDate, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading QuoteListByDate...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'QuoteListByDate'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'QuoteDate': moment(quoteDate).format('YYYYMMDD') | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES) { | ||
e = new Error(util.format( | ||
'Failed to get QuoteListByDate (%s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes[quote.$.Symbol] = quote.$; | ||
}); | ||
} | ||
debug(util.format('QuoteListByDate (%s, %s): %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
_.keys(quotes).length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get QuoteListByDate (%s, %s): status %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading QuoteListByDate...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'QuoteListByDate', { | ||
Exchange: exchangeCode, | ||
QuoteDate: moment(quoteDate).format('YYYYMMDD') | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteListByDate (%s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes[quote.$.Symbol] = quote.$; | ||
}); | ||
} | ||
debug(util.format('QuoteListByDate (%s, %s): %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
_.keys(quotes).length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteListByDate (%s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getQuoteListByDate2 = function (exchangeCode, quoteDate, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading QuoteListByDate2...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'QuoteListByDate2'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'QuoteDate': moment(quoteDate).format('YYYYMMDD') | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES2) { | ||
e = new Error(util.format( | ||
'Failed to get QuoteListByDate2 (%s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES2[0].QUOTE2) { | ||
result.RESPONSE.QUOTES2[0].QUOTE2.forEach(function (quote) { | ||
quotes[quote.$.s] = quote.$; | ||
}); | ||
} | ||
debug(util.format('QuoteListByDate2 (%s, %s): %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
_.keys(quotes).length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get QuoteListByDate2 (%s, %s): status %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading QuoteListByDate2...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'QuoteListByDate2', { | ||
Exchange: exchangeCode, | ||
QuoteDate: moment(quoteDate).format('YYYYMMDD') | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES2) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteListByDate2 (%s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES2[0].QUOTE2) { | ||
result.RESPONSE.QUOTES2[0].QUOTE2.forEach(function (quote) { | ||
quotes[quote.$.s] = quote.$; | ||
}); | ||
} | ||
debug(util.format('QuoteListByDate2 (%s, %s): %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
_.keys(quotes).length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteListByDate2 (%s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getQuoteListByDatePeriod = function (exchangeCode, quoteDate, period, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading QuoteListByDatePeriod...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'QuoteListByDatePeriod'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'QuoteDate': moment(quoteDate).format('YYYYMMDD'), | ||
'Period': period | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES) { | ||
e = new Error(util.format( | ||
'Failed to get QuoteListByDatePeriod (%s, %s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
if (!_.has(quotes, quote.$.Symbol)) { | ||
quotes[quote.$.Symbol] = []; | ||
} | ||
quotes[quote.$.Symbol].push(quote.$); | ||
}); | ||
} | ||
debug(util.format('QuoteListByDatePeriod (%s, %s, %s): %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
_.keys(quotes).length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get QuoteListByDatePeriod (%s, %s, %s): status %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading QuoteListByDatePeriod...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'QuoteListByDatePeriod', { | ||
Exchange: exchangeCode, | ||
QuoteDate: moment(quoteDate).format('YYYYMMDD'), | ||
Period: period | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteListByDatePeriod (%s, %s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
if (!_.has(quotes, quote.$.Symbol)) { | ||
quotes[quote.$.Symbol] = []; | ||
} | ||
quotes[quote.$.Symbol].push(quote.$); | ||
}); | ||
} | ||
debug(util.format('QuoteListByDatePeriod (%s, %s, %s): %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
_.keys(quotes).length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteListByDatePeriod (%s, %s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getQuoteListByDatePeriod2 = function (exchangeCode, quoteDate, period, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading QuoteListByDatePeriod2...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'QuoteListByDatePeriod2'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'QuoteDate': moment(quoteDate).format('YYYYMMDD'), | ||
'Period': period | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES2) { | ||
e = new Error(util.format( | ||
'Failed to get QuoteListByDatePeriod2 (%s, %s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES2[0].QUOTE2) { | ||
result.RESPONSE.QUOTES2[0].QUOTE2.forEach(function (quote) { | ||
if (!_.has(quotes, quote.$.s)) { | ||
quotes[quote.$.s] = []; | ||
} | ||
quotes[quote.$.s].push(quote.$); | ||
}); | ||
} | ||
debug(util.format('QuoteListByDatePeriod2 (%s, %s, %s): %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
_.keys(quotes).length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get QuoteListByDatePeriod2 (%s, %s, %s): status %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading QuoteListByDatePeriod2...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'QuoteListByDatePeriod2', { | ||
Exchange: exchangeCode, | ||
QuoteDate: moment(quoteDate).format('YYYYMMDD'), | ||
Period: period | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES2) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteListByDatePeriod2 (%s, %s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = {}; | ||
if (result.RESPONSE.QUOTES2[0].QUOTE2) { | ||
result.RESPONSE.QUOTES2[0].QUOTE2.forEach(function (quote) { | ||
if (!_.has(quotes, quote.$.s)) { | ||
quotes[quote.$.s] = []; | ||
} | ||
quotes[quote.$.s].push(quote.$); | ||
}); | ||
} | ||
debug(util.format('QuoteListByDatePeriod2 (%s, %s, %s): %d', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
_.keys(quotes).length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get QuoteListByDatePeriod2 (%s, %s, %s): %s', | ||
exchangeCode, | ||
moment(quoteDate).format('M/D/YYYY'), | ||
period, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getSplitListByExchange = function (exchangeCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading SplitListByExchange...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'SplitListByExchange'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.SPLITS) { | ||
e = new Error(util.format( | ||
'Failed to get SplitListByExchange (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var splits = []; | ||
if (result.RESPONSE.SPLITS[0].SPLIT) { | ||
result.RESPONSE.SPLITS[0].SPLIT.forEach(function (split) { | ||
splits.push(split.$); | ||
}); | ||
} | ||
debug(util.format('SplitListByExchange (%s): %d', | ||
exchangeCode, | ||
_.keys(splits).length).yellow); | ||
return _.isFunction(cb) ? cb(null, splits) : dfd.resolve(splits); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get SplitListByExchange (%s): status %d', | ||
exchangeCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading SplitListByExchange...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'SplitListByExchange', { | ||
Exchange: exchangeCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.SPLITS) { | ||
throw new Error(util.format( | ||
'Failed to get SplitListByExchange (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var splits = []; | ||
if (result.RESPONSE.SPLITS[0].SPLIT) { | ||
result.RESPONSE.SPLITS[0].SPLIT.forEach(function (split) { | ||
splits.push(split.$); | ||
}); | ||
} | ||
debug(util.format('SplitListByExchange (%s): %d', | ||
exchangeCode, | ||
_.keys(splits).length)); | ||
return splits; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get SplitListByExchange (%s): %s', | ||
exchangeCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getSplitListBySymbol = function (exchangeCode, symbolCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading SplitListBySymbol...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'SplitListBySymbol'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'Symbol': symbolCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.SPLITS) { | ||
e = new Error(util.format( | ||
'Failed to get SplitListBySymbol (%s:%s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var splits = []; | ||
if (result.RESPONSE.SPLITS[0].SPLIT) { | ||
result.RESPONSE.SPLITS[0].SPLIT.forEach(function (split) { | ||
splits.push(split.$); | ||
}); | ||
} | ||
debug(util.format('SplitListBySymbol (%s:%s): %d', | ||
exchangeCode, | ||
symbolCode, | ||
_.keys(splits).length).yellow); | ||
return _.isFunction(cb) ? cb(null, splits) : dfd.resolve(splits); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get SplitListBySymbol (%s:%s): status %d', | ||
exchangeCode, | ||
symbolCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
debug('Downloading SplitListBySymbol...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'SplitListBySymbol', { | ||
Exchange: exchangeCode, | ||
Symbol: symbolCode | ||
}); | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.SPLITS) { | ||
if (result.RESPONSE.$.Message === 'No Splits were found') { | ||
return []; | ||
} | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
throw new Error(util.format( | ||
'Failed to get SplitListBySymbol (%s:%s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var splits = []; | ||
if (result.RESPONSE.SPLITS[0].SPLIT) { | ||
result.RESPONSE.SPLITS[0].SPLIT.forEach(function (split) { | ||
splits.push(split.$); | ||
}); | ||
} | ||
debug(util.format('SplitListBySymbol (%s:%s): %d', | ||
exchangeCode, | ||
symbolCode, | ||
_.keys(splits).length)); | ||
return splits; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get SplitListBySymbol (%s:%s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getSymbolChangesByExchange = function (exchangeCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading SymbolChangesByExchange...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'SymbolChangesByExchange'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.SYMBOLCHANGES) { | ||
e = new Error(util.format( | ||
'Failed to get SymbolChangesByExchange (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var symbolChanges = []; | ||
if (result.RESPONSE.SYMBOLCHANGES[0].SYMBOLCHANGE) { | ||
result.RESPONSE.SYMBOLCHANGES[0].SYMBOLCHANGE.forEach(function (symbolChange) { | ||
symbolChanges.push(symbolChange.$); | ||
}); | ||
} | ||
debug(util.format('SymbolChangesByExchange (%s): %d', | ||
exchangeCode, | ||
_.keys(symbolChanges).length).yellow); | ||
return _.isFunction(cb) ? cb(null, symbolChanges) : dfd.resolve(symbolChanges); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get SymbolChangesByExchange (%s): status %d', | ||
exchangeCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading SymbolChangesByExchange...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'SymbolChangesByExchange', { | ||
Exchange: exchangeCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.SYMBOLCHANGES) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolChangesByExchange (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var symbolChanges = []; | ||
if (result.RESPONSE.SYMBOLCHANGES[0].SYMBOLCHANGE) { | ||
result.RESPONSE.SYMBOLCHANGES[0].SYMBOLCHANGE.forEach(function (symbolChange) { | ||
symbolChanges.push(symbolChange.$); | ||
}); | ||
} | ||
debug(util.format('SymbolChangesByExchange (%s): %d', | ||
exchangeCode, | ||
_.keys(symbolChanges).length)); | ||
return symbolChanges; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolChangesByExchange (%s): %s', | ||
exchangeCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getSymbolGet = function (exchangeCode, symbolCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading SymbolGet...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'SymbolGet'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'Symbol': symbolCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.SYMBOL) { | ||
e = new Error(util.format( | ||
'Failed to get SymbolGet (%s:%s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var symbol = result.RESPONSE.SYMBOL[0].$; | ||
debug(util.format('SymbolGet (%s:%s)', exchangeCode, symbolCode).yellow); | ||
return _.isFunction(cb) ? cb(null, symbol) : dfd.resolve(symbol); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get SymbolGet (%s:%s): status %d', | ||
exchangeCode, | ||
symbolCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading SymbolGet...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'SymbolGet', { | ||
Exchange: exchangeCode, | ||
Symbol: symbolCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.SYMBOL) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolGet (%s:%s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var symbol = result.RESPONSE.SYMBOL[0].$; | ||
debug(util.format('SymbolGet (%s:%s)', exchangeCode, symbolCode)); | ||
return symbol; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolGet (%s:%s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getSymbolHistory = function (exchangeCode, symbolCode, startDate, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading SymbolHistory...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'SymbolHistory'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'Symbol': symbolCode, | ||
'StartDate': moment(startDate).format('YYYYMMDD') | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES) { | ||
e = new Error(util.format( | ||
'Failed to get SymbolHistory (%s:%s, %s-): %s', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = []; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes.push(quote.$); | ||
}); | ||
} | ||
debug(util.format('SymbolHistory (%s:%s, %s-): %d', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
quotes.length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get SymbolHistory (%s:%s, %s-): status %d', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading SymbolHistory...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'SymbolHistory', { | ||
Exchange: exchangeCode, | ||
Symbol: symbolCode, | ||
StartDate: moment(startDate).format('YYYYMMDD') | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolHistory (%s:%s, %s-): %s', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = []; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes.push(quote.$); | ||
}); | ||
} | ||
debug(util.format('SymbolHistory (%s:%s, %s-): %d', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
quotes.length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolHistory (%s:%s, %s-): %s', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getSymbolHistoryPeriod = function (exchangeCode, symbolCode, date, period, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading SymbolHistoryPeriod...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'SymbolHistoryPeriod'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'Symbol': symbolCode, | ||
'Date': moment(date).format('YYYYMMDD'), | ||
'Period': period | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES) { | ||
e = new Error(util.format( | ||
'Failed to get SymbolHistoryPeriod (%s:%s, %s, %s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
moment(date).format('M/D/YYYY'), | ||
period, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = []; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes.push(quote.$); | ||
}); | ||
} | ||
debug(util.format('SymbolHistoryPeriod (%s:%s, %s, %s): %d', | ||
exchangeCode, | ||
symbolCode, | ||
moment(date).format('M/D/YYYY'), | ||
period, | ||
quotes.length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get SymbolHistoryPeriod (%s:%s, %s, %s): status %d', | ||
exchangeCode, | ||
symbolCode, | ||
moment(date).format('M/D/YYYY'), | ||
period, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading SymbolHistoryPeriod...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'SymbolHistoryPeriod', { | ||
Exchange: exchangeCode, | ||
Symbol: symbolCode, | ||
Date: moment(date).format('YYYYMMDD'), | ||
Period: period | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolHistoryPeriod (%s:%s, %s, %s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
moment(date).format('M/D/YYYY'), | ||
period, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = []; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes.push(quote.$); | ||
}); | ||
} | ||
debug(util.format('SymbolHistoryPeriod (%s:%s, %s, %s): %d', | ||
exchangeCode, | ||
symbolCode, | ||
moment(date).format('M/D/YYYY'), | ||
period, | ||
quotes.length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolHistoryPeriod (%s:%s, %s, %s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
moment(date).format('M/D/YYYY'), | ||
period, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getSymbolHistoryPeriodByDateRange = function (exchangeCode, symbolCode, startDate, endDate, period, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading SymbolHistoryPeriodByDateRange...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'SymbolHistoryPeriodByDateRange'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode, | ||
'Symbol': symbolCode, | ||
'StartDate': moment(startDate).format('YYYYMMDD'), | ||
'EndDate': moment(endDate).format('YYYYMMDD'), | ||
'Period': period | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES) { | ||
e = new Error(util.format( | ||
'Failed to get SymbolHistoryPeriodByDateRange (%s:%s, %s-%s, %s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
moment(endDate).format('M/D/YYYY'), | ||
period, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = []; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes.push(quote.$); | ||
}); | ||
} | ||
debug(util.format('SymbolHistoryPeriodByDateRange (%s:%s, %s-%s, %s): %d', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
moment(endDate).format('M/D/YYYY'), | ||
period, | ||
quotes.length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get SymbolHistoryPeriodByDateRange (%s:%s, %s-%s, %s): status %d', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
moment(endDate).format('M/D/YYYY'), | ||
period, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading SymbolHistoryPeriodByDateRange...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'SymbolHistoryPeriodByDateRange', { | ||
Exchange: exchangeCode, | ||
Symbol: symbolCode, | ||
StartDate: moment(startDate).format('YYYYMMDD'), | ||
EndDate: moment(endDate).format('YYYYMMDD'), | ||
Period: period | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolHistoryPeriodByDateRange (%s:%s, %s-%s, %s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
moment(endDate).format('M/D/YYYY'), | ||
period, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = []; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes.push(quote.$); | ||
}); | ||
} | ||
debug(util.format('SymbolHistoryPeriodByDateRange (%s:%s, %s-%s, %s): %d', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
moment(endDate).format('M/D/YYYY'), | ||
period, | ||
quotes.length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolHistoryPeriodByDateRange (%s:%s, %s-%s, %s): %s', | ||
exchangeCode, | ||
symbolCode, | ||
moment(startDate).format('M/D/YYYY'), | ||
moment(endDate).format('M/D/YYYY'), | ||
period, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getSymbolList2 = function (exchangeCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading SymbolList2...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'SymbolList2'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.SYMBOLS2) { | ||
e = new Error(util.format( | ||
'Failed to get SymbolList2 (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var symbols = {}; | ||
if (result.RESPONSE.SYMBOLS2[0].SYMBOL2) { | ||
result.RESPONSE.SYMBOLS2[0].SYMBOL2.forEach(function (symbol) { | ||
symbols[symbol.$.c] = symbol.$.n; | ||
}); | ||
} | ||
debug(util.format('SymbolList2 (%s): %d', | ||
exchangeCode, | ||
_.keys(symbols).length).yellow); | ||
return _.isFunction(cb) ? cb(null, symbols) : dfd.resolve(symbols); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get SymbolList2 (%s): status %d', | ||
exchangeCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading SymbolList2...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'SymbolList2', { | ||
Exchange: exchangeCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.SYMBOLS2) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolList2 (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var symbols = {}; | ||
if (result.RESPONSE.SYMBOLS2[0].SYMBOL2) { | ||
result.RESPONSE.SYMBOLS2[0].SYMBOL2.forEach(function (symbol) { | ||
symbols[symbol.$.c] = symbol.$.n; | ||
}); | ||
} | ||
debug(util.format('SymbolList2 (%s): %d', | ||
exchangeCode, | ||
_.keys(symbols).length)); | ||
return symbols; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get SymbolList2 (%s): %s', | ||
exchangeCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getTechnicalList = function (exchangeCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading TechnicalList...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'TechnicalList'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.TECHNICALS) { | ||
e = new Error(util.format( | ||
'Failed to get TechnicalList (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var technicals = {}; | ||
if (result.RESPONSE.TECHNICALS[0].TECHNICAL) { | ||
result.RESPONSE.TECHNICALS[0].TECHNICAL.forEach(function (technical) { | ||
technicals[technical.$.Symbol] = technical.$; | ||
}); | ||
} | ||
debug(util.format('TechnicalList (%s): %d', | ||
exchangeCode, | ||
_.keys(technicals).length).yellow); | ||
return _.isFunction(cb) ? cb(null, technicals) : dfd.resolve(technicals); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get TechnicalList (%s): status %d', | ||
exchangeCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading TechnicalList...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'TechnicalList', { | ||
Exchange: exchangeCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.TECHNICALS) { | ||
throw new Error(util.format( | ||
'Failed to get TechnicalList (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var technicals = {}; | ||
if (result.RESPONSE.TECHNICALS[0].TECHNICAL) { | ||
result.RESPONSE.TECHNICALS[0].TECHNICAL.forEach(function (technical) { | ||
technicals[technical.$.Symbol] = technical.$; | ||
}); | ||
} | ||
debug(util.format('TechnicalList (%s): %d', | ||
exchangeCode, | ||
_.keys(technicals).length)); | ||
return technicals; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get TechnicalList (%s): %s', | ||
exchangeCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getTop10Gains = function (exchangeCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading Top10Gains...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'Top10Gains'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES) { | ||
e = new Error(util.format( | ||
'Failed to get Top10Gains (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = []; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes.push(quote.$); | ||
}); | ||
} | ||
debug(util.format('Top10Gains (%s): %d', | ||
exchangeCode, | ||
quotes.length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get Top10Gains (%s): status %d', | ||
exchangeCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading Top10Gains...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'Top10Gains', { | ||
Exchange: exchangeCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES) { | ||
throw new Error(util.format( | ||
'Failed to get Top10Gains (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = []; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes.push(quote.$); | ||
}); | ||
} | ||
debug(util.format('Top10Gains (%s): %d', | ||
exchangeCode, | ||
quotes.length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get Top10Gains (%s): %s', | ||
exchangeCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
Data.prototype.getTop10Losses = function (exchangeCode, cb) { | ||
var self = this, | ||
dfd = Q.defer(), | ||
e; | ||
this._taskQueue.push({run: function (next) { | ||
self._getToken(function (err, token) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
debug('Downloading Top10Losses...'.cyan); | ||
request.post({ | ||
url: url.resolve(self._config.endpoint, 'Top10Losses'), | ||
form: { | ||
'Token': token, | ||
'Exchange': exchangeCode | ||
}, | ||
timeout: self._config.timeout | ||
}, function (err, res, body) { | ||
next(); | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (res.statusCode === 200) { | ||
xml2js.parseString(body, function (err, result) { | ||
if (err) { return _.isFunction(cb) ? cb(err) : dfd.reject(err); } | ||
if (!result.RESPONSE.QUOTES) { | ||
e = new Error(util.format( | ||
'Failed to get Top10Losses (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
var quotes = []; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes.push(quote.$); | ||
}); | ||
} | ||
debug(util.format('Top10Losses (%s): %d', | ||
exchangeCode, | ||
quotes.length).yellow); | ||
return _.isFunction(cb) ? cb(null, quotes) : dfd.resolve(quotes); | ||
}); | ||
} else { | ||
e = new Error(util.format( | ||
'Failed to get Top10Losses (%s): status %d', | ||
exchangeCode, | ||
res.statusCode | ||
)); | ||
return _.isFunction(cb) ? cb(e) : dfd.reject(e); | ||
} | ||
debug('Downloading Top10Losses...'); | ||
return Promise.bind(this) | ||
.then(function () { | ||
return _requestWithToken.call(this, 'Top10Losses', { | ||
Exchange: exchangeCode | ||
}); | ||
}); | ||
}}); | ||
return dfd.promise; | ||
}) | ||
.then(function (result) { | ||
if (!result.RESPONSE.QUOTES) { | ||
throw new Error(util.format( | ||
'Failed to get Top10Losses (%s): %s', | ||
exchangeCode, | ||
result.RESPONSE.$.Message | ||
)); | ||
} | ||
var quotes = []; | ||
if (result.RESPONSE.QUOTES[0].QUOTE) { | ||
result.RESPONSE.QUOTES[0].QUOTE.forEach(function (quote) { | ||
quotes.push(quote.$); | ||
}); | ||
} | ||
debug(util.format('Top10Losses (%s): %d', | ||
exchangeCode, | ||
quotes.length)); | ||
return quotes; | ||
}) | ||
.catch(function (err) { | ||
throw new Error(util.format( | ||
'Failed to get Top10Losses (%s): %s', | ||
exchangeCode, | ||
err.message | ||
)); | ||
}) | ||
.nodeify(cb); | ||
}; | ||
// Public API | ||
exports = module.exports = Data; |
@@ -1,9 +0,1 @@ | ||
/* | ||
* lib/index.js | ||
*/ | ||
'use strict'; | ||
require('colors'); | ||
exports.Data = require('./data'); |
{ | ||
"name": "eoddata", | ||
"description": "EODData client library for Node.js", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"license": "MIT", | ||
@@ -22,2 +22,3 @@ "author": { | ||
"price", | ||
"quote", | ||
"historical", | ||
@@ -30,16 +31,16 @@ "eod", | ||
"dependencies": { | ||
"async": "~0.2.10", | ||
"colors": "~0.6.2", | ||
"debug": "~0.7.4", | ||
"bluebird": "^2.3.2", | ||
"debug": "^0.7.4", | ||
"lodash": "~2.4.1", | ||
"moment": "~2.5.1", | ||
"q": "~1.0.0", | ||
"request": "~2.33.0", | ||
"xml2js": "~0.4.1" | ||
"moment": "^2.5.1", | ||
"request": "^2.33.0", | ||
"xml2js": "^0.4.4" | ||
}, | ||
"devDependencies": { | ||
"grunt": "~0.4.2", | ||
"grunt-contrib-jshint": "~0.8.0", | ||
"grunt-contrib-watch": "~0.5.3", | ||
"matchdep": "~0.3.0" | ||
"colors": "~0.6.2", | ||
"grunt": "^0.4.5", | ||
"grunt-concurrent": "^1.0.0", | ||
"grunt-contrib-jshint": "^0.8.0", | ||
"grunt-contrib-watch": "^0.5.3", | ||
"load-grunt-tasks": "^0.6.0" | ||
}, | ||
@@ -46,0 +47,0 @@ "scripts": { |
@@ -28,5 +28,5 @@ [![NPM](https://nodei.co/npm/eoddata.png?downloads=false&stars=false)](https://npmjs.org/package/eoddata) [![NPM](https://nodei.co/npm-dl/eoddata.png?months=6)](https://npmjs.org/package/eoddata) | ||
The client automatically handles token authentication therefore the following API calls can be made right away. All tasks are internally queued. | ||
The client automatically handles token authentication therefore the following API calls can be made right away. | ||
All API functions accept callback as the last parameter. Whether you pass a callback function or not, they will always return a promise object built using Q. You can do whatever you want with the returned promise, or stick with the traditional callback style. | ||
All API functions accept callback as the last parameter. Whether you pass a callback function or not, they will always return a promise object built using [Bluebird](https://github.com/petkaantonov/bluebird). You can do whatever you want with the returned promise, or stick with the traditional callback style. | ||
@@ -33,0 +33,0 @@ - **Date Format:** JavaScript Date Object or String format supported by [Moment.js](http://momentjs.com/docs/) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
6
46737
6
969
1
+ Addedbluebird@^2.3.2
+ Addedajv@6.12.6(transitive)
+ Addedasn1@0.2.6(transitive)
+ Addedassert-plus@1.0.0(transitive)
+ Addedasynckit@0.4.0(transitive)
+ Addedaws-sign2@0.7.0(transitive)
+ Addedaws4@1.13.2(transitive)
+ Addedbcrypt-pbkdf@1.0.2(transitive)
+ Addedbluebird@2.11.0(transitive)
+ Addedcaseless@0.12.0(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addedcore-util-is@1.0.2(transitive)
+ Addeddashdash@1.14.1(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addedecc-jsbn@0.1.2(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedextsprintf@1.3.0(transitive)
+ Addedfast-deep-equal@3.1.3(transitive)
+ Addedfast-json-stable-stringify@2.1.0(transitive)
+ Addedforever-agent@0.6.1(transitive)
+ Addedform-data@2.3.3(transitive)
+ Addedgetpass@0.1.7(transitive)
+ Addedhar-schema@2.0.0(transitive)
+ Addedhar-validator@5.1.5(transitive)
+ Addedhttp-signature@1.2.0(transitive)
+ Addedis-typedarray@1.0.0(transitive)
+ Addedisstream@0.1.2(transitive)
+ Addedjsbn@0.1.1(transitive)
+ Addedjson-schema@0.4.0(transitive)
+ Addedjson-schema-traverse@0.4.1(transitive)
+ Addedjsprim@1.4.2(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addedmoment@2.30.1(transitive)
+ Addedoauth-sign@0.9.0(transitive)
+ Addedperformance-now@2.1.0(transitive)
+ Addedpsl@1.15.0(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedqs@6.5.3(transitive)
+ Addedrequest@2.88.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedsshpk@1.18.0(transitive)
+ Addedtough-cookie@2.5.0(transitive)
+ Addedtunnel-agent@0.6.0(transitive)
+ Addedtweetnacl@0.14.5(transitive)
+ Addeduri-js@4.4.1(transitive)
+ Addeduuid@3.4.0(transitive)
+ Addedverror@1.10.0(transitive)
- Removedasync@~0.2.10
- Removedcolors@~0.6.2
- Removedq@~1.0.0
- Removedasn1@0.1.11(transitive)
- Removedassert-plus@0.1.5(transitive)
- Removedasync@0.2.100.9.2(transitive)
- Removedaws-sign2@0.5.0(transitive)
- Removedboom@0.4.2(transitive)
- Removedcolors@0.6.2(transitive)
- Removedcombined-stream@0.0.7(transitive)
- Removedcryptiles@0.2.2(transitive)
- Removedctype@0.5.3(transitive)
- Removeddelayed-stream@0.0.5(transitive)
- Removedforever-agent@0.5.2(transitive)
- Removedform-data@0.1.4(transitive)
- Removedhawk@1.0.0(transitive)
- Removedhoek@0.9.1(transitive)
- Removedhttp-signature@0.10.1(transitive)
- Removedmime@1.2.11(transitive)
- Removedmoment@2.5.1(transitive)
- Removednode-uuid@1.4.8(transitive)
- Removedoauth-sign@0.3.0(transitive)
- Removedq@1.0.1(transitive)
- Removedqs@0.6.6(transitive)
- Removedrequest@2.33.0(transitive)
- Removedsntp@0.2.4(transitive)
- Removedtldts@6.1.71(transitive)
- Removedtldts-core@6.1.71(transitive)
- Removedtough-cookie@5.1.0(transitive)
- Removedtunnel-agent@0.3.0(transitive)
Updateddebug@^0.7.4
Updatedmoment@^2.5.1
Updatedrequest@^2.33.0
Updatedxml2js@^0.4.4