-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnyse.ts
115 lines (106 loc) · 2.98 KB
/
nyse.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
105
106
107
108
109
110
111
112
113
114
115
import { MarketTime } from './market-time';
import { NYTimeNow, NYTimeNowTy } from './ny-time';
type CalendarTy = {[key: string]: {[key: string]: number[]}};
export interface NYSEMarket {
readonly holidays: CalendarTy;
readonly earlyCloseDays: CalendarTy;
open(): boolean;
preMarket(): boolean;
afterMarket(): boolean;
minutesToClose(): number;
}
// All NYSE markets observe U.S. holidays as listed below for 2023, 2024, and 2025.
// Source: https://www.nyse.com/markets/hours-calendars
export class NYSEMarket implements NYSEMarket {
readonly holidays: CalendarTy = {
2023: {
January: [16],
February: [20],
April: [7],
May: [29],
June: [19],
July: [4],
September: [4],
November: [23],
December: [25]
},
2024: {
January: [1, 15],
February: [19],
March: [29],
May: [27],
June: [19],
July: [4],
September: [2],
November: [28],
December: [25]
},
2025: {
January: [1, 9, 20],
February: [17],
April: [18],
May: [26],
June: [19],
July: [4],
September: [1],
November: [27],
December: [25]
}
};
readonly earlyCloseDays: CalendarTy = {
2023: {
July: [3],
November: [24]
},
2024: {
July: [3],
November: [29],
December: [24]
},
2025: {
July: [3],
November: [28],
December: [24]
}
};
open(): boolean {
const now: NYTimeNowTy = new NYTimeNow();
if (!this.openDay(now)) return false;
// On early close days each market will close early at 1:00 p.m
if (this.isDateOnCalendar(this.earlyCloseDays, now) && MarketTime.earlyClosed()) return false;
return MarketTime.coreOpen();
}
minutesToClose(): number {
if (this.open()) {
const now: NYTimeNowTy = new NYTimeNow();
let close: Date = MarketTime.closeTime;
if (this.isDateOnCalendar(this.earlyCloseDays, now)) close = MarketTime.earlyCloseTime;
const diffMs = close.getTime() - now.time.getTime();
return Math.floor(diffMs / (1000 * 60));
}
return 0;
}
preMarket(): boolean {
const now: NYTimeNowTy = new NYTimeNow();
if (this.openDay(now) && MarketTime.preMarket()) return true;
return false;
}
afterMarket(): boolean {
const now: NYTimeNowTy = new NYTimeNow();
const earlyCloseDay: boolean = this.isDateOnCalendar(this.earlyCloseDays, now);
if (this.openDay(now) && MarketTime.afterMarket(earlyCloseDay)) return true;
return false;
}
private isDateOnCalendar(data: CalendarTy, now: NYTimeNowTy): boolean {
if (data[now.year] && data[now.year][now.month]) {
const found: number | undefined = data[now.year][now.month].find((e: number) => e === now.day);
if (found) return true;
}
return false;
}
private openDay(now: NYTimeNowTy): boolean {
if (now.weekDay === 0 || now.weekDay === 6) return false;
if (this.isDateOnCalendar(this.holidays, now)) return false;
return true;
}
}