lynx-client 0.0.33 → 0.0.35

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.
Files changed (153) hide show
  1. package/dist/cjs/index.js +2 -0
  2. package/dist/cjs/lib/addresses/lensAddresses.js +6 -6
  3. package/dist/cjs/lib/constants/feeIds.js +20 -0
  4. package/dist/cjs/lib/constants/groupIds.js +20 -0
  5. package/dist/cjs/lib/constants/pairIds.js +43 -1
  6. package/dist/cjs/lib/contractsIntegration/LexLensService/ILexLensService.js +7 -0
  7. package/dist/cjs/lib/contractsIntegration/LexLensService/LexLensService.js +2 -2
  8. package/dist/cjs/lib/contractsIntegration/TriggersAndPortalLensService/ITriggersAndPortalLensService.js +25 -1
  9. package/dist/cjs/lib/contractsIntegration/TriggersAndPortalLensService/TriggersAndPortalLensService.js +44 -0
  10. package/dist/cjs/lib/marketHours/marketHoursUtils.js +663 -0
  11. package/dist/cjs/lib/priceFeeds/flare/flareFeedConstants.js +22 -0
  12. package/dist/cjs/lib/priceFeeds/pyth/pythFeedConstants.js +44 -0
  13. package/dist/cjs/lib/typechain/factories/contracts/Lynx/FeatureFlagger/FeatureFlaggerV1__factory.js +1 -1
  14. package/dist/cjs/lib/typechain/factories/contracts/Lynx/IntentsVerifier/LiquidityIntentsVerifierV1__factory.js +1 -1
  15. package/dist/cjs/lib/typechain/factories/contracts/Lynx/IntentsVerifier/TradeIntentsVerifierV1__factory.js +1 -1
  16. package/dist/cjs/lib/typechain/factories/contracts/Lynx/Lex/LexPool/LexPoolV1__factory.js +1 -1
  17. package/dist/cjs/lib/typechain/factories/contracts/Lynx/Lex/PNLR/PNLR__factory.js +1 -1
  18. package/dist/cjs/lib/typechain/factories/contracts/Lynx/Lex/PoolAccountant/PoolAccountantV1__factory.js +1 -1
  19. package/dist/cjs/lib/typechain/factories/contracts/Lynx/OrderBook/OrderBookV1__factory.js +1 -1
  20. package/dist/cjs/lib/typechain/factories/contracts/Lynx/Registry/RegistryV1__factory.js +1 -1
  21. package/dist/cjs/lib/typechain/factories/contracts/Lynx/TradersPortal/TradersPortalV1__factory.js +284 -9
  22. package/dist/cjs/lib/typechain/factories/contracts/Lynx/TradingFloor/TradingFloorV1__factory.js +6 -1
  23. package/dist/cjs/lib/typechain/factories/contracts/Lynx/Triggers/TriggersV1__factory.js +261 -1
  24. package/dist/cjs/lib/typechain/factories/contracts/Peripheral/Lens/LexLens__factory.js +136 -1
  25. package/dist/cjs/lib/typechain/factories/contracts/Peripheral/Lens/RateModelLens__factory.js +1 -1
  26. package/dist/cjs/lib/typechain/factories/contracts/Peripheral/Lens/TradingFloorLens__factory.js +1 -1
  27. package/dist/cjs/lib/typechain/factories/contracts/Peripheral/Lens/TriggersAndPortalLens__factory.js +220 -1
  28. package/dist/esm/index.d.ts +1 -0
  29. package/dist/esm/index.d.ts.map +1 -1
  30. package/dist/esm/index.js +2 -0
  31. package/dist/esm/lib/addresses/lensAddresses.d.ts +6 -6
  32. package/dist/esm/lib/addresses/lensAddresses.js +6 -6
  33. package/dist/esm/lib/constants/feeIds.d.ts +5 -1
  34. package/dist/esm/lib/constants/feeIds.d.ts.map +1 -1
  35. package/dist/esm/lib/constants/feeIds.js +20 -0
  36. package/dist/esm/lib/constants/groupIds.d.ts +5 -1
  37. package/dist/esm/lib/constants/groupIds.d.ts.map +1 -1
  38. package/dist/esm/lib/constants/groupIds.js +20 -0
  39. package/dist/esm/lib/constants/pairIds.d.ts +19 -1
  40. package/dist/esm/lib/constants/pairIds.d.ts.map +1 -1
  41. package/dist/esm/lib/constants/pairIds.js +43 -1
  42. package/dist/esm/lib/contractsIntegration/LexLensService/ILexLensService.d.ts.map +1 -1
  43. package/dist/esm/lib/contractsIntegration/LexLensService/ILexLensService.js +7 -0
  44. package/dist/esm/lib/contractsIntegration/LexLensService/LexLensService.d.ts.map +1 -1
  45. package/dist/esm/lib/contractsIntegration/LexLensService/LexLensService.js +2 -2
  46. package/dist/esm/lib/contractsIntegration/TriggersAndPortalLensService/ITriggersAndPortalLensService.d.ts +29 -4
  47. package/dist/esm/lib/contractsIntegration/TriggersAndPortalLensService/ITriggersAndPortalLensService.d.ts.map +1 -1
  48. package/dist/esm/lib/contractsIntegration/TriggersAndPortalLensService/ITriggersAndPortalLensService.js +25 -1
  49. package/dist/esm/lib/contractsIntegration/TriggersAndPortalLensService/TriggersAndPortalLensService.d.ts +5 -1
  50. package/dist/esm/lib/contractsIntegration/TriggersAndPortalLensService/TriggersAndPortalLensService.d.ts.map +1 -1
  51. package/dist/esm/lib/contractsIntegration/TriggersAndPortalLensService/TriggersAndPortalLensService.js +44 -0
  52. package/dist/esm/lib/marketHours/marketHoursUtils.d.ts +52 -0
  53. package/dist/esm/lib/marketHours/marketHoursUtils.d.ts.map +1 -0
  54. package/dist/esm/lib/marketHours/marketHoursUtils.js +663 -0
  55. package/dist/esm/lib/priceFeeds/flare/flareFeedConstants.d.ts.map +1 -1
  56. package/dist/esm/lib/priceFeeds/flare/flareFeedConstants.js +22 -0
  57. package/dist/esm/lib/priceFeeds/pyth/pythFeedConstants.d.ts.map +1 -1
  58. package/dist/esm/lib/priceFeeds/pyth/pythFeedConstants.js +44 -0
  59. package/dist/esm/lib/typechain/contracts/Lynx/TradersPortal/TradersPortalV1.d.ts +182 -9
  60. package/dist/esm/lib/typechain/contracts/Lynx/TradersPortal/TradersPortalV1.d.ts.map +1 -1
  61. package/dist/esm/lib/typechain/contracts/Lynx/TradingFloor/TradingFloorV1.d.ts +5 -3
  62. package/dist/esm/lib/typechain/contracts/Lynx/TradingFloor/TradingFloorV1.d.ts.map +1 -1
  63. package/dist/esm/lib/typechain/contracts/Lynx/Triggers/TriggersV1.d.ts +164 -2
  64. package/dist/esm/lib/typechain/contracts/Lynx/Triggers/TriggersV1.d.ts.map +1 -1
  65. package/dist/esm/lib/typechain/contracts/Peripheral/Lens/LexLens.d.ts +22 -1
  66. package/dist/esm/lib/typechain/contracts/Peripheral/Lens/LexLens.d.ts.map +1 -1
  67. package/dist/esm/lib/typechain/contracts/Peripheral/Lens/TriggersAndPortalLens.d.ts +126 -3
  68. package/dist/esm/lib/typechain/contracts/Peripheral/Lens/TriggersAndPortalLens.d.ts.map +1 -1
  69. package/dist/esm/lib/typechain/factories/contracts/Lynx/FeatureFlagger/FeatureFlaggerV1__factory.d.ts +1 -1
  70. package/dist/esm/lib/typechain/factories/contracts/Lynx/FeatureFlagger/FeatureFlaggerV1__factory.js +1 -1
  71. package/dist/esm/lib/typechain/factories/contracts/Lynx/IntentsVerifier/LiquidityIntentsVerifierV1__factory.d.ts +1 -1
  72. package/dist/esm/lib/typechain/factories/contracts/Lynx/IntentsVerifier/LiquidityIntentsVerifierV1__factory.js +1 -1
  73. package/dist/esm/lib/typechain/factories/contracts/Lynx/IntentsVerifier/TradeIntentsVerifierV1__factory.d.ts +1 -1
  74. package/dist/esm/lib/typechain/factories/contracts/Lynx/IntentsVerifier/TradeIntentsVerifierV1__factory.js +1 -1
  75. package/dist/esm/lib/typechain/factories/contracts/Lynx/Lex/LexPool/LexPoolV1__factory.d.ts +1 -1
  76. package/dist/esm/lib/typechain/factories/contracts/Lynx/Lex/LexPool/LexPoolV1__factory.js +1 -1
  77. package/dist/esm/lib/typechain/factories/contracts/Lynx/Lex/PNLR/PNLR__factory.d.ts +1 -1
  78. package/dist/esm/lib/typechain/factories/contracts/Lynx/Lex/PNLR/PNLR__factory.js +1 -1
  79. package/dist/esm/lib/typechain/factories/contracts/Lynx/Lex/PoolAccountant/PoolAccountantV1__factory.d.ts +1 -1
  80. package/dist/esm/lib/typechain/factories/contracts/Lynx/Lex/PoolAccountant/PoolAccountantV1__factory.js +1 -1
  81. package/dist/esm/lib/typechain/factories/contracts/Lynx/OrderBook/OrderBookV1__factory.d.ts +1 -1
  82. package/dist/esm/lib/typechain/factories/contracts/Lynx/OrderBook/OrderBookV1__factory.js +1 -1
  83. package/dist/esm/lib/typechain/factories/contracts/Lynx/Registry/RegistryV1__factory.d.ts +1 -1
  84. package/dist/esm/lib/typechain/factories/contracts/Lynx/Registry/RegistryV1__factory.js +1 -1
  85. package/dist/esm/lib/typechain/factories/contracts/Lynx/TradersPortal/TradersPortalV1__factory.d.ts +221 -9
  86. package/dist/esm/lib/typechain/factories/contracts/Lynx/TradersPortal/TradersPortalV1__factory.d.ts.map +1 -1
  87. package/dist/esm/lib/typechain/factories/contracts/Lynx/TradersPortal/TradersPortalV1__factory.js +284 -9
  88. package/dist/esm/lib/typechain/factories/contracts/Lynx/TradingFloor/TradingFloorV1__factory.d.ts +5 -1
  89. package/dist/esm/lib/typechain/factories/contracts/Lynx/TradingFloor/TradingFloorV1__factory.d.ts.map +1 -1
  90. package/dist/esm/lib/typechain/factories/contracts/Lynx/TradingFloor/TradingFloorV1__factory.js +6 -1
  91. package/dist/esm/lib/typechain/factories/contracts/Lynx/Triggers/TriggersV1__factory.d.ts +203 -1
  92. package/dist/esm/lib/typechain/factories/contracts/Lynx/Triggers/TriggersV1__factory.d.ts.map +1 -1
  93. package/dist/esm/lib/typechain/factories/contracts/Lynx/Triggers/TriggersV1__factory.js +261 -1
  94. package/dist/esm/lib/typechain/factories/contracts/Peripheral/Lens/LexLens__factory.d.ts +109 -1
  95. package/dist/esm/lib/typechain/factories/contracts/Peripheral/Lens/LexLens__factory.d.ts.map +1 -1
  96. package/dist/esm/lib/typechain/factories/contracts/Peripheral/Lens/LexLens__factory.js +136 -1
  97. package/dist/esm/lib/typechain/factories/contracts/Peripheral/Lens/RateModelLens__factory.d.ts +1 -1
  98. package/dist/esm/lib/typechain/factories/contracts/Peripheral/Lens/RateModelLens__factory.js +1 -1
  99. package/dist/esm/lib/typechain/factories/contracts/Peripheral/Lens/TradingFloorLens__factory.d.ts +1 -1
  100. package/dist/esm/lib/typechain/factories/contracts/Peripheral/Lens/TradingFloorLens__factory.js +1 -1
  101. package/dist/esm/lib/typechain/factories/contracts/Peripheral/Lens/TriggersAndPortalLens__factory.d.ts +169 -1
  102. package/dist/esm/lib/typechain/factories/contracts/Peripheral/Lens/TriggersAndPortalLens__factory.d.ts.map +1 -1
  103. package/dist/esm/lib/typechain/factories/contracts/Peripheral/Lens/TriggersAndPortalLens__factory.js +220 -1
  104. package/dist/types/index.d.ts +1 -0
  105. package/dist/types/index.d.ts.map +1 -1
  106. package/dist/types/lib/addresses/lensAddresses.d.ts +6 -6
  107. package/dist/types/lib/constants/feeIds.d.ts +5 -1
  108. package/dist/types/lib/constants/feeIds.d.ts.map +1 -1
  109. package/dist/types/lib/constants/groupIds.d.ts +5 -1
  110. package/dist/types/lib/constants/groupIds.d.ts.map +1 -1
  111. package/dist/types/lib/constants/pairIds.d.ts +19 -1
  112. package/dist/types/lib/constants/pairIds.d.ts.map +1 -1
  113. package/dist/types/lib/contractsIntegration/LexLensService/ILexLensService.d.ts.map +1 -1
  114. package/dist/types/lib/contractsIntegration/LexLensService/LexLensService.d.ts.map +1 -1
  115. package/dist/types/lib/contractsIntegration/TriggersAndPortalLensService/ITriggersAndPortalLensService.d.ts +29 -4
  116. package/dist/types/lib/contractsIntegration/TriggersAndPortalLensService/ITriggersAndPortalLensService.d.ts.map +1 -1
  117. package/dist/types/lib/contractsIntegration/TriggersAndPortalLensService/TriggersAndPortalLensService.d.ts +5 -1
  118. package/dist/types/lib/contractsIntegration/TriggersAndPortalLensService/TriggersAndPortalLensService.d.ts.map +1 -1
  119. package/dist/types/lib/marketHours/marketHoursUtils.d.ts +52 -0
  120. package/dist/types/lib/marketHours/marketHoursUtils.d.ts.map +1 -0
  121. package/dist/types/lib/priceFeeds/flare/flareFeedConstants.d.ts.map +1 -1
  122. package/dist/types/lib/priceFeeds/pyth/pythFeedConstants.d.ts.map +1 -1
  123. package/dist/types/lib/typechain/contracts/Lynx/TradersPortal/TradersPortalV1.d.ts +182 -9
  124. package/dist/types/lib/typechain/contracts/Lynx/TradersPortal/TradersPortalV1.d.ts.map +1 -1
  125. package/dist/types/lib/typechain/contracts/Lynx/TradingFloor/TradingFloorV1.d.ts +5 -3
  126. package/dist/types/lib/typechain/contracts/Lynx/TradingFloor/TradingFloorV1.d.ts.map +1 -1
  127. package/dist/types/lib/typechain/contracts/Lynx/Triggers/TriggersV1.d.ts +164 -2
  128. package/dist/types/lib/typechain/contracts/Lynx/Triggers/TriggersV1.d.ts.map +1 -1
  129. package/dist/types/lib/typechain/contracts/Peripheral/Lens/LexLens.d.ts +22 -1
  130. package/dist/types/lib/typechain/contracts/Peripheral/Lens/LexLens.d.ts.map +1 -1
  131. package/dist/types/lib/typechain/contracts/Peripheral/Lens/TriggersAndPortalLens.d.ts +126 -3
  132. package/dist/types/lib/typechain/contracts/Peripheral/Lens/TriggersAndPortalLens.d.ts.map +1 -1
  133. package/dist/types/lib/typechain/factories/contracts/Lynx/FeatureFlagger/FeatureFlaggerV1__factory.d.ts +1 -1
  134. package/dist/types/lib/typechain/factories/contracts/Lynx/IntentsVerifier/LiquidityIntentsVerifierV1__factory.d.ts +1 -1
  135. package/dist/types/lib/typechain/factories/contracts/Lynx/IntentsVerifier/TradeIntentsVerifierV1__factory.d.ts +1 -1
  136. package/dist/types/lib/typechain/factories/contracts/Lynx/Lex/LexPool/LexPoolV1__factory.d.ts +1 -1
  137. package/dist/types/lib/typechain/factories/contracts/Lynx/Lex/PNLR/PNLR__factory.d.ts +1 -1
  138. package/dist/types/lib/typechain/factories/contracts/Lynx/Lex/PoolAccountant/PoolAccountantV1__factory.d.ts +1 -1
  139. package/dist/types/lib/typechain/factories/contracts/Lynx/OrderBook/OrderBookV1__factory.d.ts +1 -1
  140. package/dist/types/lib/typechain/factories/contracts/Lynx/Registry/RegistryV1__factory.d.ts +1 -1
  141. package/dist/types/lib/typechain/factories/contracts/Lynx/TradersPortal/TradersPortalV1__factory.d.ts +221 -9
  142. package/dist/types/lib/typechain/factories/contracts/Lynx/TradersPortal/TradersPortalV1__factory.d.ts.map +1 -1
  143. package/dist/types/lib/typechain/factories/contracts/Lynx/TradingFloor/TradingFloorV1__factory.d.ts +5 -1
  144. package/dist/types/lib/typechain/factories/contracts/Lynx/TradingFloor/TradingFloorV1__factory.d.ts.map +1 -1
  145. package/dist/types/lib/typechain/factories/contracts/Lynx/Triggers/TriggersV1__factory.d.ts +203 -1
  146. package/dist/types/lib/typechain/factories/contracts/Lynx/Triggers/TriggersV1__factory.d.ts.map +1 -1
  147. package/dist/types/lib/typechain/factories/contracts/Peripheral/Lens/LexLens__factory.d.ts +109 -1
  148. package/dist/types/lib/typechain/factories/contracts/Peripheral/Lens/LexLens__factory.d.ts.map +1 -1
  149. package/dist/types/lib/typechain/factories/contracts/Peripheral/Lens/RateModelLens__factory.d.ts +1 -1
  150. package/dist/types/lib/typechain/factories/contracts/Peripheral/Lens/TradingFloorLens__factory.d.ts +1 -1
  151. package/dist/types/lib/typechain/factories/contracts/Peripheral/Lens/TriggersAndPortalLens__factory.d.ts +169 -1
  152. package/dist/types/lib/typechain/factories/contracts/Peripheral/Lens/TriggersAndPortalLens__factory.d.ts.map +1 -1
  153. package/package.json +3 -2
@@ -0,0 +1,663 @@
1
+ "use strict";
2
+ /**
3
+ * Market hours utilities for Lynx trading pairs
4
+ * Data sourced from Pyth Network: https://docs.pyth.network/price-feeds/market-hours
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getMarketTypeFromGroupId = getMarketTypeFromGroupId;
8
+ exports.isUSInDST = isUSInDST;
9
+ exports.getMarketStatus = getMarketStatus;
10
+ exports.getForexMarketStatus = getForexMarketStatus;
11
+ exports.findNextForexOpen = findNextForexOpen;
12
+ exports.getCommoditiesMarketStatus = getCommoditiesMarketStatus;
13
+ exports.getNextCommoditiesClose = getNextCommoditiesClose;
14
+ exports.findNextCommoditiesOpen = findNextCommoditiesOpen;
15
+ exports.isMarketOpen = isMarketOpen;
16
+ exports.getMarketStatusForPair = getMarketStatusForPair;
17
+ exports.isMarketOpenForPair = isMarketOpenForPair;
18
+ exports.getMarketSchedule = getMarketSchedule;
19
+ exports.getMarketScheduleForPair = getMarketScheduleForPair;
20
+ const groupIds_1 = require("../constants/groupIds");
21
+ const pairIds_1 = require("../constants/pairIds");
22
+ // ============================================================================
23
+ // NYSE Holidays (stocks market closures)
24
+ // Source: https://www.nyse.com/markets/hours-calendars
25
+ // ============================================================================
26
+ const NYSE_HOLIDAYS_2025 = [
27
+ { date: "2025-01-01", name: "New Year's Day" },
28
+ { date: "2025-01-20", name: "Martin Luther King Jr. Day" },
29
+ { date: "2025-02-17", name: "Presidents Day" },
30
+ { date: "2025-04-18", name: "Good Friday" },
31
+ { date: "2025-05-26", name: "Memorial Day" },
32
+ { date: "2025-06-19", name: "Juneteenth" },
33
+ { date: "2025-07-04", name: "Independence Day" },
34
+ { date: "2025-09-01", name: "Labor Day" },
35
+ { date: "2025-11-27", name: "Thanksgiving" },
36
+ { date: "2025-12-25", name: "Christmas" },
37
+ ];
38
+ const NYSE_HOLIDAYS_2026 = [
39
+ { date: "2026-01-01", name: "New Year's Day" },
40
+ { date: "2026-01-19", name: "Martin Luther King Jr. Day" },
41
+ { date: "2026-02-16", name: "Presidents Day" },
42
+ { date: "2026-04-03", name: "Good Friday" },
43
+ { date: "2026-05-25", name: "Memorial Day" },
44
+ { date: "2026-06-19", name: "Juneteenth" },
45
+ { date: "2026-07-03", name: "Independence Day (observed)" },
46
+ { date: "2026-09-07", name: "Labor Day" },
47
+ { date: "2026-11-26", name: "Thanksgiving" },
48
+ { date: "2026-12-25", name: "Christmas" },
49
+ ];
50
+ const ALL_NYSE_HOLIDAYS = [
51
+ ...NYSE_HOLIDAYS_2025,
52
+ ...NYSE_HOLIDAYS_2026,
53
+ ];
54
+ // ============================================================================
55
+ // Market Schedules
56
+ // All times are in EST (UTC-5), adjusted for EDT (UTC-4) when DST is active
57
+ // ============================================================================
58
+ const CRYPTO_SCHEDULE = {
59
+ marketType: "crypto",
60
+ sessions: [], // 24/7, no session boundaries
61
+ holidays: [],
62
+ };
63
+ // Forex: Sunday 5:00 PM ET → Friday 5:00 PM ET
64
+ // EST: Sunday 22:00 UTC → Friday 22:00 UTC
65
+ // EDT: Sunday 21:00 UTC → Friday 21:00 UTC
66
+ const FOREX_SCHEDULE = {
67
+ marketType: "forex",
68
+ sessions: [
69
+ // Represented as: opens Sunday evening, closes Friday evening
70
+ { dayOfWeek: 0, openTimeUTC: "22:00", closeTimeUTC: "23:59" }, // Sunday open
71
+ { dayOfWeek: 1, openTimeUTC: "00:00", closeTimeUTC: "23:59" }, // Monday
72
+ { dayOfWeek: 2, openTimeUTC: "00:00", closeTimeUTC: "23:59" }, // Tuesday
73
+ { dayOfWeek: 3, openTimeUTC: "00:00", closeTimeUTC: "23:59" }, // Wednesday
74
+ { dayOfWeek: 4, openTimeUTC: "00:00", closeTimeUTC: "23:59" }, // Thursday
75
+ { dayOfWeek: 5, openTimeUTC: "00:00", closeTimeUTC: "22:00" }, // Friday close
76
+ ],
77
+ holidays: [
78
+ { date: "2025-12-25", name: "Christmas" },
79
+ { date: "2026-12-25", name: "Christmas" },
80
+ ],
81
+ };
82
+ // US Stocks: Weekdays 9:30 AM - 4:00 PM ET
83
+ // EST: 14:30 - 21:00 UTC
84
+ // EDT: 13:30 - 20:00 UTC
85
+ const STOCKS_SCHEDULE = {
86
+ marketType: "stocks",
87
+ sessions: [
88
+ { dayOfWeek: 1, openTimeUTC: "14:30", closeTimeUTC: "21:00" }, // Monday
89
+ { dayOfWeek: 2, openTimeUTC: "14:30", closeTimeUTC: "21:00" }, // Tuesday
90
+ { dayOfWeek: 3, openTimeUTC: "14:30", closeTimeUTC: "21:00" }, // Wednesday
91
+ { dayOfWeek: 4, openTimeUTC: "14:30", closeTimeUTC: "21:00" }, // Thursday
92
+ { dayOfWeek: 5, openTimeUTC: "14:30", closeTimeUTC: "21:00" }, // Friday
93
+ ],
94
+ holidays: ALL_NYSE_HOLIDAYS,
95
+ };
96
+ // Commodities: Sunday 6:00 PM ET → Friday 5:00 PM ET with daily 5-6 PM break
97
+ // EST: Sunday 23:00 UTC → Friday 22:00 UTC, daily break 22:00-23:00 UTC
98
+ // EDT: Sunday 22:00 UTC → Friday 21:00 UTC, daily break 21:00-22:00 UTC
99
+ const COMMODITIES_SCHEDULE = {
100
+ marketType: "commodities",
101
+ sessions: [
102
+ { dayOfWeek: 0, openTimeUTC: "23:00", closeTimeUTC: "23:59" }, // Sunday open
103
+ { dayOfWeek: 1, openTimeUTC: "00:00", closeTimeUTC: "22:00" }, // Monday (break at 22:00)
104
+ { dayOfWeek: 1, openTimeUTC: "23:00", closeTimeUTC: "23:59" }, // Monday reopen
105
+ { dayOfWeek: 2, openTimeUTC: "00:00", closeTimeUTC: "22:00" }, // Tuesday
106
+ { dayOfWeek: 2, openTimeUTC: "23:00", closeTimeUTC: "23:59" }, // Tuesday reopen
107
+ { dayOfWeek: 3, openTimeUTC: "00:00", closeTimeUTC: "22:00" }, // Wednesday
108
+ { dayOfWeek: 3, openTimeUTC: "23:00", closeTimeUTC: "23:59" }, // Wednesday reopen
109
+ { dayOfWeek: 4, openTimeUTC: "00:00", closeTimeUTC: "22:00" }, // Thursday
110
+ { dayOfWeek: 4, openTimeUTC: "23:00", closeTimeUTC: "23:59" }, // Thursday reopen
111
+ { dayOfWeek: 5, openTimeUTC: "00:00", closeTimeUTC: "22:00" }, // Friday close
112
+ ],
113
+ holidays: [
114
+ { date: "2025-12-25", name: "Christmas" },
115
+ { date: "2026-12-25", name: "Christmas" },
116
+ ],
117
+ dailyBreaks: [
118
+ { startTimeUTC: "22:00", endTimeUTC: "23:00", daysOfWeek: [1, 2, 3, 4] },
119
+ ],
120
+ };
121
+ // ============================================================================
122
+ // Group ID to Market Type Mapping
123
+ // ============================================================================
124
+ const GROUP_ID_TO_MARKET_TYPE = {
125
+ [groupIds_1.GROUP_CONFIGS_IDS.basicCryptoGroup]: "crypto",
126
+ [groupIds_1.GROUP_CONFIGS_IDS.catCryptoGroup]: "crypto",
127
+ [groupIds_1.GROUP_CONFIGS_IDS.forexGroup]: "forex",
128
+ [groupIds_1.GROUP_CONFIGS_IDS.catForexGroup]: "forex",
129
+ [groupIds_1.GROUP_CONFIGS_IDS.stocksGroup]: "stocks",
130
+ [groupIds_1.GROUP_CONFIGS_IDS.catStocksGroup]: "stocks",
131
+ [groupIds_1.GROUP_CONFIGS_IDS.commoditiesGroup]: "commodities",
132
+ [groupIds_1.GROUP_CONFIGS_IDS.catCommoditiesGroup]: "commodities",
133
+ };
134
+ const MARKET_TYPE_TO_SCHEDULE = {
135
+ crypto: CRYPTO_SCHEDULE,
136
+ forex: FOREX_SCHEDULE,
137
+ stocks: STOCKS_SCHEDULE,
138
+ commodities: COMMODITIES_SCHEDULE,
139
+ };
140
+ function getMarketTypeFromGroupId(groupId) {
141
+ const marketType = GROUP_ID_TO_MARKET_TYPE[groupId];
142
+ if (!marketType) {
143
+ throw new Error(`Unknown group ID: ${groupId}`);
144
+ }
145
+ return marketType;
146
+ }
147
+ // ============================================================================
148
+ // DST Detection
149
+ // US DST: 2nd Sunday of March 2:00 AM → 1st Sunday of November 2:00 AM
150
+ // ============================================================================
151
+ /**
152
+ * Get the nth occurrence of a specific day of week in a month
153
+ * @param year Full year (e.g., 2025)
154
+ * @param month Month (0-11)
155
+ * @param dayOfWeek Day of week (0 = Sunday)
156
+ * @param n Which occurrence (1 = first, 2 = second, etc.)
157
+ * @returns Date object for that day at 00:00 UTC
158
+ */
159
+ function getNthDayOfMonth(year, month, dayOfWeek, n) {
160
+ const firstDay = new Date(Date.UTC(year, month, 1));
161
+ const firstDayOfWeek = firstDay.getUTCDay();
162
+ let dayOffset = dayOfWeek - firstDayOfWeek;
163
+ if (dayOffset < 0)
164
+ dayOffset += 7;
165
+ const nthDay = 1 + dayOffset + (n - 1) * 7;
166
+ return new Date(Date.UTC(year, month, nthDay));
167
+ }
168
+ /**
169
+ * Check if a given timestamp falls within US Daylight Saving Time
170
+ * DST starts: 2nd Sunday of March at 2:00 AM local (7:00 UTC)
171
+ * DST ends: 1st Sunday of November at 2:00 AM local (6:00 UTC)
172
+ */
173
+ function isUSInDST(timestamp) {
174
+ const date = new Date(timestamp);
175
+ const year = date.getUTCFullYear();
176
+ // DST starts: 2nd Sunday of March at 7:00 UTC (2:00 AM EST → 3:00 AM EDT)
177
+ const dstStart = getNthDayOfMonth(year, 2, 0, 2); // March, Sunday, 2nd
178
+ dstStart.setUTCHours(7, 0, 0, 0);
179
+ // DST ends: 1st Sunday of November at 6:00 UTC (2:00 AM EDT → 1:00 AM EST)
180
+ const dstEnd = getNthDayOfMonth(year, 10, 0, 1); // November, Sunday, 1st
181
+ dstEnd.setUTCHours(6, 0, 0, 0);
182
+ return timestamp >= dstStart.getTime() && timestamp < dstEnd.getTime();
183
+ }
184
+ // ============================================================================
185
+ // Internal Helpers
186
+ // ============================================================================
187
+ function getScheduleForGroupId(groupId) {
188
+ const marketType = getMarketTypeFromGroupId(groupId);
189
+ return MARKET_TYPE_TO_SCHEDULE[marketType];
190
+ }
191
+ function parseTimeUTC(timeStr) {
192
+ const [hours, minutes] = timeStr.split(':').map(Number);
193
+ return { hours, minutes };
194
+ }
195
+ function adjustTimeForDST(timeStr, isDST) {
196
+ if (!isDST)
197
+ return timeStr;
198
+ const { hours, minutes } = parseTimeUTC(timeStr);
199
+ const adjustedHours = hours - 1; // DST = 1 hour earlier in UTC
200
+ return `${adjustedHours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
201
+ }
202
+ function getDateString(timestamp) {
203
+ const date = new Date(timestamp);
204
+ const year = date.getUTCFullYear();
205
+ const month = (date.getUTCMonth() + 1).toString().padStart(2, '0');
206
+ const day = date.getUTCDate().toString().padStart(2, '0');
207
+ return `${year}-${month}-${day}`;
208
+ }
209
+ function isHoliday(timestamp, holidays) {
210
+ const dateStr = getDateString(timestamp);
211
+ return holidays.some(h => h.date === dateStr);
212
+ }
213
+ // ============================================================================
214
+ // Public API
215
+ // ============================================================================
216
+ function getMarketStatus(groupId, timestamp) {
217
+ const ts = timestamp ?? Date.now();
218
+ const schedule = getScheduleForGroupId(groupId);
219
+ // Crypto is always open
220
+ if (schedule.marketType === "crypto") {
221
+ return {
222
+ isOpen: true,
223
+ nextOpen: null,
224
+ nextClose: null,
225
+ marketType: "crypto",
226
+ };
227
+ }
228
+ if (schedule.marketType === "stocks") {
229
+ return getStocksMarketStatus(ts, schedule);
230
+ }
231
+ if (schedule.marketType === "forex") {
232
+ return getForexMarketStatus(ts, schedule);
233
+ }
234
+ if (schedule.marketType === "commodities") {
235
+ return getCommoditiesMarketStatus(ts, schedule);
236
+ }
237
+ throw new Error(`Market type ${schedule.marketType} not yet implemented`);
238
+ }
239
+ function getStocksMarketStatus(timestamp, schedule) {
240
+ const date = new Date(timestamp);
241
+ const dayOfWeek = date.getUTCDay();
242
+ const isDST = isUSInDST(timestamp);
243
+ // Check if it's a holiday
244
+ if (isHoliday(timestamp, schedule.holidays)) {
245
+ return {
246
+ isOpen: false,
247
+ nextOpen: findNextStocksOpen(timestamp, schedule, isDST),
248
+ nextClose: null,
249
+ marketType: "stocks",
250
+ };
251
+ }
252
+ // Check if it's a weekend
253
+ if (dayOfWeek === 0 || dayOfWeek === 6) {
254
+ return {
255
+ isOpen: false,
256
+ nextOpen: findNextStocksOpen(timestamp, schedule, isDST),
257
+ nextClose: null,
258
+ marketType: "stocks",
259
+ };
260
+ }
261
+ // Find today's session
262
+ const session = schedule.sessions.find(s => s.dayOfWeek === dayOfWeek);
263
+ if (!session) {
264
+ return {
265
+ isOpen: false,
266
+ nextOpen: findNextStocksOpen(timestamp, schedule, isDST),
267
+ nextClose: null,
268
+ marketType: "stocks",
269
+ };
270
+ }
271
+ // Adjust times for DST
272
+ const openTime = adjustTimeForDST(session.openTimeUTC, isDST);
273
+ const closeTime = adjustTimeForDST(session.closeTimeUTC, isDST);
274
+ const { hours: openHours, minutes: openMinutes } = parseTimeUTC(openTime);
275
+ const { hours: closeHours, minutes: closeMinutes } = parseTimeUTC(closeTime);
276
+ const currentHours = date.getUTCHours();
277
+ const currentMinutes = date.getUTCMinutes();
278
+ const currentTimeMinutes = currentHours * 60 + currentMinutes;
279
+ const openTimeMinutes = openHours * 60 + openMinutes;
280
+ const closeTimeMinutes = closeHours * 60 + closeMinutes;
281
+ if (currentTimeMinutes >= openTimeMinutes && currentTimeMinutes < closeTimeMinutes) {
282
+ // Market is open
283
+ const closeDate = new Date(timestamp);
284
+ closeDate.setUTCHours(closeHours, closeMinutes, 0, 0);
285
+ return {
286
+ isOpen: true,
287
+ nextOpen: null,
288
+ nextClose: closeDate,
289
+ marketType: "stocks",
290
+ };
291
+ }
292
+ // Market is closed
293
+ return {
294
+ isOpen: false,
295
+ nextOpen: findNextStocksOpen(timestamp, schedule, isDST),
296
+ nextClose: null,
297
+ marketType: "stocks",
298
+ };
299
+ }
300
+ function findNextStocksOpen(timestamp, schedule, isDST) {
301
+ const date = new Date(timestamp);
302
+ let checkDate = new Date(timestamp);
303
+ // Get the open time (adjusted for DST)
304
+ const baseOpenTime = schedule.sessions.find(s => s.dayOfWeek === 1).openTimeUTC;
305
+ const openTime = adjustTimeForDST(baseOpenTime, isDST);
306
+ const { hours: openHours, minutes: openMinutes } = parseTimeUTC(openTime);
307
+ // If we're before today's open and today is a trading day, return today's open
308
+ const currentTimeMinutes = date.getUTCHours() * 60 + date.getUTCMinutes();
309
+ const openTimeMinutes = openHours * 60 + openMinutes;
310
+ const dayOfWeek = date.getUTCDay();
311
+ if (dayOfWeek >= 1 &&
312
+ dayOfWeek <= 5 &&
313
+ currentTimeMinutes < openTimeMinutes &&
314
+ !isHoliday(timestamp, schedule.holidays)) {
315
+ checkDate.setUTCHours(openHours, openMinutes, 0, 0);
316
+ return checkDate;
317
+ }
318
+ // Otherwise, find the next trading day
319
+ checkDate.setUTCDate(checkDate.getUTCDate() + 1);
320
+ checkDate.setUTCHours(openHours, openMinutes, 0, 0);
321
+ // Loop until we find a valid trading day (max 10 days to prevent infinite loop)
322
+ for (let i = 0; i < 10; i++) {
323
+ const checkDayOfWeek = checkDate.getUTCDay();
324
+ // Skip weekends
325
+ if (checkDayOfWeek === 0) {
326
+ checkDate.setUTCDate(checkDate.getUTCDate() + 1);
327
+ continue;
328
+ }
329
+ if (checkDayOfWeek === 6) {
330
+ checkDate.setUTCDate(checkDate.getUTCDate() + 2);
331
+ continue;
332
+ }
333
+ // Check DST for the check date and adjust if needed
334
+ const checkIsDST = isUSInDST(checkDate.getTime());
335
+ if (checkIsDST !== isDST) {
336
+ const newOpenTime = adjustTimeForDST(baseOpenTime, checkIsDST);
337
+ const { hours: newOpenHours, minutes: newOpenMinutes } = parseTimeUTC(newOpenTime);
338
+ checkDate.setUTCHours(newOpenHours, newOpenMinutes, 0, 0);
339
+ }
340
+ // Skip holidays
341
+ if (isHoliday(checkDate.getTime(), schedule.holidays)) {
342
+ checkDate.setUTCDate(checkDate.getUTCDate() + 1);
343
+ continue;
344
+ }
345
+ return checkDate;
346
+ }
347
+ return checkDate;
348
+ }
349
+ function getForexMarketStatus(timestamp, schedule) {
350
+ const date = new Date(timestamp);
351
+ const dayOfWeek = date.getUTCDay();
352
+ const isDST = isUSInDST(timestamp);
353
+ // Forex hours (EST): Sunday 22:00 UTC → Friday 22:00 UTC
354
+ // EDT adjustment: Sunday 21:00 UTC → Friday 21:00 UTC
355
+ const openHour = isDST ? 21 : 22;
356
+ const closeHour = isDST ? 21 : 22;
357
+ // Check if holiday
358
+ if (isHoliday(timestamp, schedule.holidays)) {
359
+ return {
360
+ isOpen: false,
361
+ nextOpen: findNextForexOpen(timestamp, isDST),
362
+ nextClose: null,
363
+ marketType: "forex",
364
+ };
365
+ }
366
+ const currentHours = date.getUTCHours();
367
+ // Saturday: always closed
368
+ if (dayOfWeek === 6) {
369
+ return {
370
+ isOpen: false,
371
+ nextOpen: findNextForexOpen(timestamp, isDST),
372
+ nextClose: null,
373
+ marketType: "forex",
374
+ };
375
+ }
376
+ // Sunday: open after openHour
377
+ if (dayOfWeek === 0) {
378
+ if (currentHours >= openHour) {
379
+ // Find Friday close time
380
+ const fridayClose = new Date(timestamp);
381
+ fridayClose.setUTCDate(fridayClose.getUTCDate() + 5); // Next Friday
382
+ fridayClose.setUTCHours(closeHour, 0, 0, 0);
383
+ return {
384
+ isOpen: true,
385
+ nextOpen: null,
386
+ nextClose: fridayClose,
387
+ marketType: "forex",
388
+ };
389
+ }
390
+ else {
391
+ return {
392
+ isOpen: false,
393
+ nextOpen: findNextForexOpen(timestamp, isDST),
394
+ nextClose: null,
395
+ marketType: "forex",
396
+ };
397
+ }
398
+ }
399
+ // Friday: closed after closeHour
400
+ if (dayOfWeek === 5) {
401
+ if (currentHours >= closeHour) {
402
+ return {
403
+ isOpen: false,
404
+ nextOpen: findNextForexOpen(timestamp, isDST),
405
+ nextClose: null,
406
+ marketType: "forex",
407
+ };
408
+ }
409
+ }
410
+ // Monday-Friday (before close): open
411
+ const fridayClose = new Date(timestamp);
412
+ fridayClose.setUTCDate(date.getUTCDate() + (5 - dayOfWeek));
413
+ fridayClose.setUTCHours(closeHour, 0, 0, 0);
414
+ return {
415
+ isOpen: true,
416
+ nextOpen: null,
417
+ nextClose: fridayClose,
418
+ marketType: "forex",
419
+ };
420
+ }
421
+ function findNextForexOpen(timestamp, isDST) {
422
+ const date = new Date(timestamp);
423
+ const dayOfWeek = date.getUTCDay();
424
+ const openHour = isDST ? 21 : 22;
425
+ // Calculate days until next Sunday
426
+ let daysUntilSunday = (7 - dayOfWeek) % 7;
427
+ if (dayOfWeek === 0 && date.getUTCHours() >= openHour) {
428
+ // It's Sunday after open, next open is next week
429
+ daysUntilSunday = 7;
430
+ }
431
+ if (dayOfWeek === 0 && date.getUTCHours() < openHour) {
432
+ // It's Sunday before open, open is today
433
+ daysUntilSunday = 0;
434
+ }
435
+ const nextOpen = new Date(timestamp);
436
+ nextOpen.setUTCDate(date.getUTCDate() + daysUntilSunday);
437
+ nextOpen.setUTCHours(openHour, 0, 0, 0);
438
+ // Check DST for the open date
439
+ const openIsDST = isUSInDST(nextOpen.getTime());
440
+ if (openIsDST !== isDST) {
441
+ nextOpen.setUTCHours(openIsDST ? 21 : 22, 0, 0, 0);
442
+ }
443
+ return nextOpen;
444
+ }
445
+ // ============================================================================
446
+ // Commodities Market Functions
447
+ // Schedule: Sunday 23:00 UTC (EST) → Friday 22:00 UTC (EST)
448
+ // Sunday 22:00 UTC (EDT) → Friday 21:00 UTC (EDT)
449
+ // Daily break: 22:00-23:00 UTC (EST) / 21:00-22:00 UTC (EDT) on Mon-Thu
450
+ // ============================================================================
451
+ function getCommoditiesMarketStatus(timestamp, schedule) {
452
+ const date = new Date(timestamp);
453
+ const dayOfWeek = date.getUTCDay();
454
+ const isDST = isUSInDST(timestamp);
455
+ // Commodities hours (EST): Sunday 23:00 UTC → Friday 22:00 UTC
456
+ // EDT adjustment: Sunday 22:00 UTC → Friday 21:00 UTC
457
+ // Daily break (EST): 22:00-23:00 UTC on Mon-Thu
458
+ // Daily break (EDT): 21:00-22:00 UTC on Mon-Thu
459
+ const openHour = isDST ? 22 : 23; // Sunday open
460
+ const closeHour = isDST ? 21 : 22; // Friday close and daily break start
461
+ const breakEndHour = isDST ? 22 : 23; // Daily break end
462
+ // Check if holiday
463
+ if (isHoliday(timestamp, schedule.holidays)) {
464
+ return {
465
+ isOpen: false,
466
+ nextOpen: findNextCommoditiesOpen(timestamp, isDST),
467
+ nextClose: null,
468
+ marketType: "commodities",
469
+ };
470
+ }
471
+ const currentHours = date.getUTCHours();
472
+ // Saturday: always closed
473
+ if (dayOfWeek === 6) {
474
+ return {
475
+ isOpen: false,
476
+ nextOpen: findNextCommoditiesOpen(timestamp, isDST),
477
+ nextClose: null,
478
+ marketType: "commodities",
479
+ };
480
+ }
481
+ // Sunday: open after openHour (23:00 EST / 22:00 EDT)
482
+ if (dayOfWeek === 0) {
483
+ if (currentHours >= openHour) {
484
+ return {
485
+ isOpen: true,
486
+ nextOpen: null,
487
+ nextClose: getNextCommoditiesClose(timestamp, isDST),
488
+ marketType: "commodities",
489
+ };
490
+ }
491
+ else {
492
+ return {
493
+ isOpen: false,
494
+ nextOpen: findNextCommoditiesOpen(timestamp, isDST),
495
+ nextClose: null,
496
+ marketType: "commodities",
497
+ };
498
+ }
499
+ }
500
+ // Friday: closed after closeHour (22:00 EST / 21:00 EDT)
501
+ if (dayOfWeek === 5) {
502
+ if (currentHours >= closeHour) {
503
+ return {
504
+ isOpen: false,
505
+ nextOpen: findNextCommoditiesOpen(timestamp, isDST),
506
+ nextClose: null,
507
+ marketType: "commodities",
508
+ };
509
+ }
510
+ // Friday before close - market is open
511
+ return {
512
+ isOpen: true,
513
+ nextOpen: null,
514
+ nextClose: getNextCommoditiesClose(timestamp, isDST),
515
+ marketType: "commodities",
516
+ };
517
+ }
518
+ // Monday-Thursday: check for daily break (22:00-23:00 EST / 21:00-22:00 EDT)
519
+ if (dayOfWeek >= 1 && dayOfWeek <= 4) {
520
+ // During break
521
+ if (currentHours >= closeHour && currentHours < breakEndHour) {
522
+ // During daily break - return next open as end of break
523
+ const breakEnd = new Date(timestamp);
524
+ breakEnd.setUTCHours(breakEndHour, 0, 0, 0);
525
+ return {
526
+ isOpen: false,
527
+ nextOpen: breakEnd,
528
+ nextClose: null,
529
+ marketType: "commodities",
530
+ };
531
+ }
532
+ // Before break or after break reopens
533
+ return {
534
+ isOpen: true,
535
+ nextOpen: null,
536
+ nextClose: getNextCommoditiesClose(timestamp, isDST),
537
+ marketType: "commodities",
538
+ };
539
+ }
540
+ // Should not reach here, but fallback
541
+ return {
542
+ isOpen: false,
543
+ nextOpen: findNextCommoditiesOpen(timestamp, isDST),
544
+ nextClose: null,
545
+ marketType: "commodities",
546
+ };
547
+ }
548
+ function getNextCommoditiesClose(timestamp, isDST) {
549
+ const date = new Date(timestamp);
550
+ const dayOfWeek = date.getUTCDay();
551
+ const currentHours = date.getUTCHours();
552
+ const closeHour = isDST ? 21 : 22; // Daily break start / Friday close
553
+ const breakEndHour = isDST ? 22 : 23;
554
+ // If we're before the daily break on Mon-Thu, the next close is today's break
555
+ if (dayOfWeek >= 1 && dayOfWeek <= 4) {
556
+ if (currentHours < closeHour) {
557
+ // Next close is today's daily break
558
+ const todayBreak = new Date(timestamp);
559
+ todayBreak.setUTCHours(closeHour, 0, 0, 0);
560
+ return todayBreak;
561
+ }
562
+ // If we're after the break reopened (>= breakEndHour), next close is tomorrow
563
+ if (currentHours >= breakEndHour) {
564
+ if (dayOfWeek === 4) {
565
+ // Thursday after break - next close is Friday close
566
+ const fridayClose = new Date(timestamp);
567
+ fridayClose.setUTCDate(date.getUTCDate() + 1);
568
+ fridayClose.setUTCHours(closeHour, 0, 0, 0);
569
+ return fridayClose;
570
+ }
571
+ else {
572
+ // Mon-Wed after break - next close is tomorrow's break
573
+ const tomorrowBreak = new Date(timestamp);
574
+ tomorrowBreak.setUTCDate(date.getUTCDate() + 1);
575
+ tomorrowBreak.setUTCHours(closeHour, 0, 0, 0);
576
+ return tomorrowBreak;
577
+ }
578
+ }
579
+ }
580
+ // Friday before close - next close is today
581
+ if (dayOfWeek === 5 && currentHours < closeHour) {
582
+ const fridayClose = new Date(timestamp);
583
+ fridayClose.setUTCHours(closeHour, 0, 0, 0);
584
+ return fridayClose;
585
+ }
586
+ // Sunday after open - next close is Monday's break
587
+ if (dayOfWeek === 0) {
588
+ const mondayBreak = new Date(timestamp);
589
+ mondayBreak.setUTCDate(date.getUTCDate() + 1);
590
+ mondayBreak.setUTCHours(closeHour, 0, 0, 0);
591
+ return mondayBreak;
592
+ }
593
+ // Fallback: return next Monday's break
594
+ const daysUntilMonday = (8 - dayOfWeek) % 7 || 7;
595
+ const mondayBreak = new Date(timestamp);
596
+ mondayBreak.setUTCDate(date.getUTCDate() + daysUntilMonday);
597
+ mondayBreak.setUTCHours(closeHour, 0, 0, 0);
598
+ return mondayBreak;
599
+ }
600
+ function findNextCommoditiesOpen(timestamp, isDST) {
601
+ const date = new Date(timestamp);
602
+ const dayOfWeek = date.getUTCDay();
603
+ const currentHours = date.getUTCHours();
604
+ const openHour = isDST ? 22 : 23; // Sunday open
605
+ const breakEndHour = isDST ? 22 : 23; // Daily break end
606
+ // During daily break (Mon-Thu) - next open is end of break (same day)
607
+ const closeHour = isDST ? 21 : 22;
608
+ if (dayOfWeek >= 1 && dayOfWeek <= 4) {
609
+ if (currentHours >= closeHour && currentHours < breakEndHour) {
610
+ const breakEnd = new Date(timestamp);
611
+ breakEnd.setUTCHours(breakEndHour, 0, 0, 0);
612
+ return breakEnd;
613
+ }
614
+ }
615
+ // Sunday before open - open is today
616
+ if (dayOfWeek === 0 && currentHours < openHour) {
617
+ const sundayOpen = new Date(timestamp);
618
+ sundayOpen.setUTCHours(openHour, 0, 0, 0);
619
+ return sundayOpen;
620
+ }
621
+ // Calculate days until next Sunday
622
+ let daysUntilSunday = (7 - dayOfWeek) % 7;
623
+ if (dayOfWeek === 0 && currentHours >= openHour) {
624
+ // It's Sunday after open, next open is next week's Sunday
625
+ daysUntilSunday = 7;
626
+ }
627
+ if (daysUntilSunday === 0 && dayOfWeek !== 0) {
628
+ // Not Sunday, so we need to go to next Sunday
629
+ daysUntilSunday = 7;
630
+ }
631
+ const nextOpen = new Date(timestamp);
632
+ nextOpen.setUTCDate(date.getUTCDate() + daysUntilSunday);
633
+ nextOpen.setUTCHours(openHour, 0, 0, 0);
634
+ // Check DST for the open date and adjust if needed
635
+ const openIsDST = isUSInDST(nextOpen.getTime());
636
+ if (openIsDST !== isDST) {
637
+ nextOpen.setUTCHours(openIsDST ? 22 : 23, 0, 0, 0);
638
+ }
639
+ return nextOpen;
640
+ }
641
+ function isMarketOpen(groupId, timestamp) {
642
+ return getMarketStatus(groupId, timestamp).isOpen;
643
+ }
644
+ function getMarketStatusForPair(pairId, timestamp) {
645
+ const pairConfig = (0, pairIds_1.getPairConfigsIdentifierFromPairId)(pairId);
646
+ if (!pairConfig) {
647
+ throw new Error(`Unknown pair ID: ${pairId}`);
648
+ }
649
+ return getMarketStatus(pairConfig.groupId, timestamp);
650
+ }
651
+ function isMarketOpenForPair(pairId, timestamp) {
652
+ return getMarketStatusForPair(pairId, timestamp).isOpen;
653
+ }
654
+ function getMarketSchedule(groupId) {
655
+ return getScheduleForGroupId(groupId);
656
+ }
657
+ function getMarketScheduleForPair(pairId) {
658
+ const pairConfig = (0, pairIds_1.getPairConfigsIdentifierFromPairId)(pairId);
659
+ if (!pairConfig) {
660
+ throw new Error(`Unknown pair ID: ${pairId}`);
661
+ }
662
+ return getMarketSchedule(pairConfig.groupId);
663
+ }
@@ -29,6 +29,28 @@ exports.FLARE_PAIRS_PRICE_FEED_IDS = {
29
29
  [pairIds_1.PAIR_CONFIGS_IDS.NZD_USD_CAT]: "",
30
30
  [pairIds_1.PAIR_CONFIGS_IDS.USD_JPY_CAT]: "",
31
31
  [pairIds_1.PAIR_CONFIGS_IDS.USD_CHF_CAT]: "",
32
+ // Stocks (Flare feed IDs to be configured)
33
+ [pairIds_1.PAIR_CONFIGS_IDS.TSLA_USD]: "",
34
+ [pairIds_1.PAIR_CONFIGS_IDS.AAPL_USD]: "",
35
+ [pairIds_1.PAIR_CONFIGS_IDS.NVDA_USD]: "",
36
+ [pairIds_1.PAIR_CONFIGS_IDS.AMZN_USD]: "",
37
+ [pairIds_1.PAIR_CONFIGS_IDS.GOOGL_USD]: "",
38
+ [pairIds_1.PAIR_CONFIGS_IDS.MSFT_USD]: "",
39
+ [pairIds_1.PAIR_CONFIGS_IDS.META_USD]: "",
40
+ // Commodities (Flare feed IDs to be configured)
41
+ [pairIds_1.PAIR_CONFIGS_IDS.GOLD_USD]: "",
42
+ [pairIds_1.PAIR_CONFIGS_IDS.SILVER_USD]: "",
43
+ // CAT Mode Stocks
44
+ [pairIds_1.PAIR_CONFIGS_IDS.TSLA_USD_CAT]: "",
45
+ [pairIds_1.PAIR_CONFIGS_IDS.AAPL_USD_CAT]: "",
46
+ [pairIds_1.PAIR_CONFIGS_IDS.NVDA_USD_CAT]: "",
47
+ [pairIds_1.PAIR_CONFIGS_IDS.AMZN_USD_CAT]: "",
48
+ [pairIds_1.PAIR_CONFIGS_IDS.GOOGL_USD_CAT]: "",
49
+ [pairIds_1.PAIR_CONFIGS_IDS.MSFT_USD_CAT]: "",
50
+ [pairIds_1.PAIR_CONFIGS_IDS.META_USD_CAT]: "",
51
+ // CAT Mode Commodities
52
+ [pairIds_1.PAIR_CONFIGS_IDS.GOLD_USD_CAT]: "",
53
+ [pairIds_1.PAIR_CONFIGS_IDS.SILVER_USD_CAT]: "",
32
54
  };
33
55
  // Reverse mapping
34
56
  exports.FLARE_PRICE_FEED_ID_TO_PAIR = Object.entries(exports.FLARE_PAIRS_PRICE_FEED_IDS).reduce((acc, [pairId, feedId]) => {