This repository has been archived by the owner on Apr 2, 2024. It is now read-only.
generated from bennycode/ts-node-starter
-
Notifications
You must be signed in to change notification settings - Fork 63
/
CandleBucketUtil.ts
104 lines (85 loc) · 3.69 KB
/
CandleBucketUtil.ts
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
import {Candle, CandleGranularity} from '.';
import {ISO_8601_MS_UTC} from '..';
/** The maximum number of data points for a single historic rates API request on Coinbase Pro is 300 candles: https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_getproductcandles */
const MAXIMUM_HISTORIC_DATA_POINTS = 300;
export interface CandleBatchBucket {
start: ISO_8601_MS_UTC;
stop: ISO_8601_MS_UTC;
}
export class CandleBucketUtil {
static getMinPrice(candles: Candle[], property: 'close' | 'high' | 'low' | 'open' = 'close'): number {
const values: number[] = candles.map(candle => candle[property]);
return Math.min(...values);
}
static getMaxPrice(candles: Candle[], property: 'close' | 'high' | 'low' | 'open' = 'close'): number {
const values: number[] = candles.map(candle => candle[property]);
return Math.max(...values);
}
static addUnitMillis(openTime: number | string, granularityInSeconds: CandleGranularity, amount: number): number {
const granularityInMillis = granularityInSeconds * 1000;
const units = amount * granularityInMillis;
return new Date(openTime).getTime() + units;
}
static addUnitISO(
openTime: number | string,
granularityInSeconds: CandleGranularity,
amount: number
): ISO_8601_MS_UTC {
const nextTimestamp = CandleBucketUtil.addUnitMillis(openTime, granularityInSeconds, amount);
return new Date(nextTimestamp).toISOString();
}
static removeUnitMillis(openTime: number | string, granularityInSeconds: CandleGranularity, amount: number): number {
const granularityInMillis = granularityInSeconds * 1000;
const units = amount * granularityInMillis;
return new Date(openTime).getTime() - units;
}
static removeUnitISO(
openTime: number | string,
granularityInSeconds: CandleGranularity,
amount: number
): ISO_8601_MS_UTC {
const nextTimestamp = CandleBucketUtil.removeUnitMillis(openTime, granularityInSeconds, amount);
return new Date(nextTimestamp).toISOString();
}
static getIntervals(): number[] {
return [60, 300, 900, 3600, 21600, 86400];
}
static mapInterval(intervals: number[], interval: number): number {
return intervals.reduce((previous, current) => {
return Math.abs(current - interval) < Math.abs(previous - interval) ? current : previous;
});
}
static mapGranularity(candleSizeInMillis: number): CandleGranularity {
return this.mapInterval(CandleBucketUtil.getIntervals(), candleSizeInMillis);
}
static expectedBuckets(fromInMillis: number, toInMillis: number, candleSizeInMillis: CandleGranularity): number {
const timeSpanInMillis = toInMillis - fromInMillis;
return timeSpanInMillis / candleSizeInMillis;
}
static getBucketsInMillis(fromInMillis: number, toInMillis: number, candleSizeInMillis: number): number[] {
const bucketsInMillis: number[] = [];
const batch = MAXIMUM_HISTORIC_DATA_POINTS * candleSizeInMillis;
let current = fromInMillis;
bucketsInMillis.push(current); // push initial start
current = current + batch;
while (current < toInMillis) {
bucketsInMillis.push(current - 1); // intermediate stop
bucketsInMillis.push(current); // intermediate start
current = current + batch;
}
bucketsInMillis.push(toInMillis); // push initial stop
return bucketsInMillis;
}
static getBucketsInISO(bucketsInMillis: number[]): CandleBatchBucket[] {
const bucketsInISO: CandleBatchBucket[] = [];
for (let i = 0; i < bucketsInMillis.length - 1; i += 2) {
const start = new Date(bucketsInMillis[i]).toISOString();
const stop = new Date(bucketsInMillis[i + 1]).toISOString();
bucketsInISO.push({
start,
stop,
});
}
return bucketsInISO;
}
}