ohlcv-indicators 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -17,24 +17,28 @@ export default class OHLCV_INDICATORS {
17
17
  init(ohlcv) {
18
18
  const { BigNumber } = this
19
19
 
20
- const ohlcvObj = ohlcv.map(({ open, high, low, close, volume, timestamp }) => ({
20
+ const ohlcvObj = ohlcv.map(({ open, high, low, close, volume, ...rest }) => ({
21
21
  open: BigNumber(open),
22
22
  high: BigNumber(high),
23
23
  low: BigNumber(low),
24
24
  close: BigNumber(close),
25
25
  volume: BigNumber(volume),
26
- timestamp
27
- }))
28
-
29
- this.ohlcv = ohlcvObj.reduce((acc, { open, high, low, close, volume, timestamp }) => {
30
- acc.open.push(open)
31
- acc.high.push(high)
32
- acc.low.push(low)
33
- acc.close.push(close)
34
- acc.volume.push(volume)
35
- acc.timestamp.push(timestamp)
36
- return acc
37
- }, { open: [], high: [], low: [], close: [], volume: [], timestamp: [] })
26
+ ...rest
27
+ }));
28
+
29
+ this.ohlcv = ohlcvObj.reduce((acc, { open, high, low, close, volume, ...rest }) => {
30
+ acc.open.push(open);
31
+ acc.high.push(high);
32
+ acc.low.push(low);
33
+ acc.close.push(close);
34
+ acc.volume.push(volume);
35
+ Object.keys(rest).forEach(key => {
36
+ if (!acc[key]) acc[key] = [];
37
+ acc[key].push(rest[key]);
38
+ });
39
+ return acc;
40
+ }, { open: [], high: [], low: [], close: [], volume: [] });
41
+
38
42
 
39
43
  return this
40
44
  }
@@ -46,6 +50,17 @@ export default class OHLCV_INDICATORS {
46
50
  getData() {
47
51
  return this.ohlcv
48
52
  }
53
+ getLastValues(){
54
+ const output = {}
55
+
56
+ for(let k in this.ohlcv)
57
+ {
58
+ const arr = this.ohlcv[k]
59
+ output[k] = arr[arr.length - 1]
60
+ }
61
+
62
+ return output
63
+ }
49
64
 
50
65
  addColumn(key, arr) {
51
66
  const ohlcvLength = this.ohlcv.open.length
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ohlcv-indicators",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A JavaScript library featuring optimized trading indicators for OHLCV arrays [{open, high, low, close, value}], utilizing BigNumber precision for enhanced accuracy.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -2,19 +2,16 @@
2
2
  const apiRoot = 'https://nasdaq.jaimelias.workers.dev/api'
3
3
  const convertCurrencyToFloat = str => parseFloat(str.replace(/[,$]/g, ''))
4
4
 
5
-
6
-
7
-
8
5
  export const getOHLCV = async (symbol, limit) => {
9
6
 
10
7
 
11
- const oneDay = await (getOneDayOHLC(symbol, limit))
8
+ const oneDay = await (getOneDayOHLCV(symbol, limit))
12
9
  const latest = await getLatestOHLCV(symbol)
13
10
 
14
11
  return [...oneDay, ...latest]
15
12
  }
16
13
 
17
- const getOneDayOHLC = async (symbol, limit) => {
14
+ const getOneDayOHLCV = async (symbol, limit) => {
18
15
 
19
16
  const {fromDate, toDate} = getDateRange(limit)
20
17
  const response = await fetch(`${apiRoot}/quote/${symbol}/chart?assetclass=stocks&fromdate=${fromDate}&todate=${toDate}`)
@@ -26,13 +23,13 @@ const getOneDayOHLC = async (symbol, limit) => {
26
23
  low: convertCurrencyToFloat(z.low),
27
24
  close: convertCurrencyToFloat(z.close),
28
25
  volume: convertCurrencyToFloat(z.volume),
29
- timestamp: x
26
+ ...convertNyMillisecondsToUtc(x) //{utcTimestamp, utcDate}
30
27
  }))
31
28
 
32
29
  return ohlcv
33
30
  }
34
31
 
35
- const getLatestOHLCV = async (symbol) => {
32
+ export const getLatestOHLCV = async (symbol) => {
36
33
 
37
34
  const response = await fetch(`${apiRoot}/quote/${symbol}/chart?assetClass=stocks`)
38
35
  const data = await response.json()
@@ -45,7 +42,7 @@ const getLatestOHLCV = async (symbol) => {
45
42
  low: Math.min(...allValues),
46
43
  close: convertCurrencyToFloat(lastSalePrice),
47
44
  volume: convertCurrencyToFloat(volume),
48
- timestamp: chart[chart.length -1].x
45
+ ...convertNyMillisecondsToUtc(chart[chart.length -1].x)
49
46
  }]
50
47
  }
51
48
 
@@ -57,4 +54,130 @@ const getDateRange = limit => {
57
54
  const fromDateFormatted = fromDate.toISOString().slice(0, 10) // Get the date limit number of days ago in yyyy-mm-dd format
58
55
 
59
56
  return { fromDate: fromDateFormatted, toDate }
60
- };
57
+ };
58
+
59
+
60
+ export const fetchHistoricalOHLCV = async ({symbol, days}) => {
61
+
62
+ //this function removes the lates "today result from output"
63
+
64
+ const response = await fetch(`https://charting.nasdaq.com/data/charting/intraday?symbol=${symbol}&mostRecent=${days}&includeLatestIntradayData=1&`, {
65
+ referrer: "https://charting.nasdaq.com/dynamic/chart.html"
66
+ })
67
+
68
+ const data = await response.json()
69
+ const {marketData} = data
70
+
71
+
72
+ const parsedData = marketData.map(o => ({
73
+ value: o.Value,
74
+ volume: o.Volume,
75
+ data: o.Date,
76
+ ...convertNYDateStringToUTC(o.Date)
77
+ }))
78
+
79
+ const lastItem = parsedData[parsedData.length - 1]
80
+ const lastDay = new Date(lastItem.utcTimestamp);
81
+ lastDay.setUTCHours(0, 0, 0, 0)
82
+ const lastTimeStamp = lastDay.getTime()
83
+
84
+ const filteredData = parsedData.filter(o => o.utcTimestamp < lastTimeStamp)
85
+
86
+ return filteredData;
87
+ }
88
+
89
+
90
+ const convertNyMillisecondsToUtc = milliseconds => {
91
+ // Create a new Date object using the milliseconds
92
+ const nyDate = new Date(milliseconds);
93
+
94
+ // Calculate the timezone offset in milliseconds (New York is UTC-5 or UTC-4 during Daylight Saving Time)
95
+ const offset = nyDate.getTimezoneOffset() * 60000;
96
+
97
+ // Create a new Date object in UTC by subtracting the offset
98
+ const utcDate = new Date(milliseconds + offset);
99
+
100
+ // Get the UTC milliseconds
101
+ const utcMilliseconds = utcDate.getTime();
102
+
103
+ // Get individual components of the date
104
+ const year = utcDate.getUTCFullYear();
105
+ const month = String(utcDate.getUTCMonth() + 1).padStart(2, '0'); // Months are zero-indexed, so add 1
106
+ const day = String(utcDate.getUTCDate()).padStart(2, '0');
107
+ const hours = String(utcDate.getUTCHours()).padStart(2, '0');
108
+ const minutes = String(utcDate.getUTCMinutes()).padStart(2, '0');
109
+ const seconds = String(utcDate.getUTCSeconds()).padStart(2, '0');
110
+
111
+ // Format the date string
112
+ const utcDateString = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
113
+
114
+ // Return the result as an object
115
+ return {
116
+ utcTimestamp: utcMilliseconds,
117
+ utcDate: utcDateString
118
+ };
119
+ }
120
+
121
+
122
+ function convertNYDateStringToUTC(dateString) {
123
+ // Create a date object in the New York timezone
124
+ const nyDate = new Date(dateString + ' GMT-0400');
125
+
126
+ // Get the UTC date string
127
+ const utcDateString = nyDate.toISOString().replace('T', ' ').substring(0, 19);
128
+
129
+ // Get the UTC timestamp
130
+ const utcTimestamp = nyDate.getTime();
131
+
132
+ return {
133
+ utcDateString: utcDateString,
134
+ utcTimestamp: utcTimestamp
135
+ };
136
+ }
137
+
138
+
139
+ export const convertToOHLCV = (data, intervalMinutes) => {
140
+ const validMinuteIntervals = [5, 10, 15, 30, 45, 60, 120, 180, 240];
141
+
142
+ if (!validMinuteIntervals.includes(intervalMinutes)) {
143
+ const errMessage = `Invalid interval. Please use any of the following intervals: ${validMinuteIntervals.join(", ")}`;
144
+ throw Error(errMessage);
145
+ }
146
+
147
+ const result = [];
148
+ let tempGroup = [];
149
+ let currentIntervalStart = null;
150
+
151
+ data.forEach(item => {
152
+ if (!currentIntervalStart) {
153
+ currentIntervalStart = item.utcTimestamp;
154
+ }
155
+
156
+ if ((item.utcTimestamp - currentIntervalStart) < intervalMinutes * 60000) {
157
+ tempGroup.push(item);
158
+ } else {
159
+ result.push(calculateOHLCV(tempGroup));
160
+ tempGroup = [item];
161
+ currentIntervalStart = item.utcTimestamp;
162
+ }
163
+ });
164
+
165
+ if (tempGroup.length) {
166
+ result.push(calculateOHLCV(tempGroup));
167
+ }
168
+
169
+ return result;
170
+ };
171
+
172
+ const calculateOHLCV = (group) => {
173
+ const open = group[0].value;
174
+ const close = group[group.length - 1].value;
175
+ const high = Math.max(...group.map(item => item.value));
176
+ const low = Math.min(...group.map(item => item.value));
177
+ const volume = group[group.length - 1].volume;
178
+ const utcDateString = group[group.length - 1].utcDateString;
179
+ const utcTimestamp = group[group.length - 1].utcTimestamp;
180
+
181
+ return { open, high, low, close, volume, utcDateString, utcTimestamp };
182
+ };
183
+
package/test/test.js CHANGED
@@ -1,11 +1,22 @@
1
1
  import OHLCV_INDICATORS from '../index.js'
2
- import { getOHLCV } from './fetchLiveData.js'
2
+ import { getOHLCV, fetchHistoricalOHLCV , getLatestOHLCV, convertToOHLCV} from './fetchLiveData.js'
3
3
 
4
4
  const indicators = new OHLCV_INDICATORS();
5
5
  const {BigNumber} = indicators
6
6
 
7
7
  const TEST = async () => {
8
8
 
9
+
10
+
11
+ //console.log(await getLatestOHLCV('NVDA'))
12
+
13
+ //const historical = convertToOHLCV(await fetchHistoricalOHLCV({symbol: 'NVDA', days: 15}), 5)
14
+ //console.log(historical.length)
15
+ //console.log(historical[0])
16
+ //console.log(historical[historical.length - 1])
17
+ //return
18
+
19
+
9
20
  const ohlcv = await getOHLCV('AAPL', 230)
10
21
 
11
22
  indicators
@@ -40,12 +51,14 @@ const TEST = async () => {
40
51
  }
41
52
  })
42
53
 
43
- console.log(`${k}: ${JSON.stringify({firstValue, firstValidIndex, lastValue})}`)
44
- console.log('---\n')
54
+ //console.log(`${k}: ${JSON.stringify({firstValue, firstValidIndex, lastValue})}`)
55
+ //console.log('---\n')
45
56
  }
46
57
 
47
- console.log('<<<<<<<<<< HEADERS >>>>>>>>>>')
48
- console.log(indicators.getHeaders())
58
+ //console.log('<<<<<<<<<< HEADERS >>>>>>>>>>')
59
+ //console.log(indicators.getHeaders())
60
+
61
+ console.log(indicators.getLastValues())
49
62
  }
50
63
 
51
64
  TEST()