-
Notifications
You must be signed in to change notification settings - Fork 20
/
yahoo-stock-prices.js
119 lines (106 loc) · 3.3 KB
/
yahoo-stock-prices.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const request = require('request');
const baseUrl = 'https://finance.yahoo.com/quote/';
/**
* @param {number} startMonth
* @param {number} startDay
* @param {number} startYear
* @param {number} endMonth
* @param {number} endDay
* @param {number} endYear
* @param {string} ticker
* @param {('1d','1wk','1mo')} frequency
* @param {Function} [callback]
*
* @return {Promise<{date: number, open: number, high:number, low:number, close:number, volume:number, adjclose:number}[]>|undefined} Returns a promise if no callback was supplied.
*/
const getHistoricalPrices = function (
startMonth,
startDay,
startYear,
endMonth,
endDay,
endYear,
ticker,
frequency,
callback,
) {
const startDate = Math.floor(Date.UTC(startYear, startMonth, startDay, 0, 0, 0) / 1000);
const endDate = Math.floor(Date.UTC(endYear, endMonth, endDay, 0, 0, 0) / 1000);
const promise = new Promise((resolve, reject) => {
request(`${baseUrl + ticker}/history?period1=${startDate}&period2=${endDate}&interval=${frequency}&filter=history&frequency=${frequency}`, (err, res, body) => {
if (err) {
reject(err);
return;
}
try {
const prices = JSON.parse(body.split('HistoricalPriceStore\":{\"prices\":')[1].split(',"isPending')[0]);
resolve(prices);
} catch (err) {
reject(err);
}
});
});
// If a callback function was supplied return the result to the callback.
// Otherwise return a promise.
if (typeof callback === 'function') {
promise
.then((price) => callback(null, price))
.catch((err) => callback(err));
} else {
return promise;
}
};
/**
* @param {string} ticker
*
* @return {Promise<{price: number, currency: string}>}
*/
const getCurrentData = function (ticker) {
return new Promise((resolve, reject) => {
request(`${baseUrl + ticker}/`, (err, res, body) => {
if (err) {
reject(err);
return;
}
try {
let price = body.split(`"${ticker}":{"sourceInterval"`)[1]
.split('regularMarketPrice')[1]
.split('fmt":"')[1]
.split('"')[0];
price = parseFloat(price.replace(',', ''));
const currencyMatch = body.match(/Currency in ([A-Za-z]{3})/);
let currency = null;
if (currencyMatch) {
currency = currencyMatch[1];
}
resolve({
currency,
price,
});
} catch (err) {
reject(err);
}
});
});
};
/**
* @param {string} ticker
* @param {Function} [callback]
*
* @return {Promise<number>|undefined} Returns a promise if no callback was supplied.
*/
const getCurrentPrice = function (ticker, callback) {
if (callback) {
getCurrentData(ticker)
.then((data) => callback(null, data.price))
.catch((err) => callback(err));
} else {
return getCurrentData(ticker)
.then((data) => data.price);
}
};
module.exports = {
getHistoricalPrices,
getCurrentData,
getCurrentPrice,
};