feat: Implement market hours and intelligent sleep duration calculation
This commit is contained in:
1 parent
cef7814700
commit
652a622954
1 file changed
+62
@@ -231,6 +231,68 @@ void fmtMoney(char* buf, size_t len, float val) {
|
|||||||
snprintf(buf, len, "%d.%02d", dollars, cents);
|
snprintf(buf, len, "%d.%02d", dollars, cents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// US market hours (Eastern time) helpers
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Approximate US Eastern DST window: 2nd Sunday of March .. 1st Sunday of Nov.
|
||||||
|
// (The exact 2 AM changeover happens on a Sunday when markets are closed, so
|
||||||
|
// day-level precision is sufficient here.)
|
||||||
|
bool usEasternDST(const struct tm& u) {
|
||||||
|
int m = u.tm_mon + 1, d = u.tm_mday, wday = u.tm_wday;
|
||||||
|
if (m < 3 || m > 11) return false;
|
||||||
|
if (m > 3 && m < 11) return true;
|
||||||
|
int prevSunday = d - wday;
|
||||||
|
if (m == 3) return prevSunday >= 8; // on/after 2nd Sunday -> DST
|
||||||
|
return prevSunday <= 0; // Nov: before 1st Sunday -> DST
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break current UTC time down into US Eastern local time.
|
||||||
|
void getEasternTime(struct tm& etTm) {
|
||||||
|
time_t utc = time(nullptr);
|
||||||
|
struct tm u;
|
||||||
|
gmtime_r(&utc, &u);
|
||||||
|
int off = usEasternDST(u) ? -4 * 3600 : -5 * 3600;
|
||||||
|
time_t et = utc + off;
|
||||||
|
gmtime_r(&et, &etTm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Daily market events, as seconds-of-day in US Eastern time.
|
||||||
|
const long EVT_OPEN = 9 * 3600 + 30 * 60; // 09:30 -> 34200 s
|
||||||
|
const long EVT_MID = 12 * 3600 + 45 * 60; // 12:45 -> 45900 s (session midpoint)
|
||||||
|
const long EVT_CLOSE = 16 * 3600; // 16:00 -> 57600 s
|
||||||
|
|
||||||
|
// Which event this update corresponds to: nearest of open / mid / close.
|
||||||
|
const char* marketPhase(const struct tm& et) {
|
||||||
|
long s = et.tm_hour * 3600 + et.tm_min * 60 + et.tm_sec;
|
||||||
|
long dOpen = labs(s - EVT_OPEN);
|
||||||
|
long dMid = labs(s - EVT_MID);
|
||||||
|
long dClose = labs(s - EVT_CLOSE);
|
||||||
|
if (dOpen <= dMid && dOpen <= dClose) return "open";
|
||||||
|
if (dClose <= dMid && dClose <= dOpen) return "close";
|
||||||
|
return "mid";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Microseconds until the next market event: the opening bell (9:30 AM ET),
|
||||||
|
// midday (12:45 PM ET), or the closing bell (4:00 PM ET), whichever comes
|
||||||
|
// first, Mon-Fri only. We wake for these three events, so the ticker refreshes
|
||||||
|
// three times per session.
|
||||||
|
uint64_t usUntilNextEvent(const struct tm& et) {
|
||||||
|
const long events[3] = { EVT_OPEN, EVT_MID, EVT_CLOSE };
|
||||||
|
long secsToday = et.tm_hour * 3600 + et.tm_min * 60 + et.tm_sec;
|
||||||
|
for (int d = 0; d <= 7; d++) {
|
||||||
|
int wd = (et.tm_wday + d) % 7;
|
||||||
|
if (wd < 1 || wd > 5) continue; // skip Sat/Sun
|
||||||
|
long base = (long)d * 86400 - secsToday;
|
||||||
|
long best = -1;
|
||||||
|
for (int e = 0; e < 3; e++) {
|
||||||
|
long cand = base + events[e];
|
||||||
|
if (cand > 0 && (best < 0 || cand < best)) best = cand;
|
||||||
|
}
|
||||||
|
if (best > 0) return (uint64_t)best * 1000000ULL;
|
||||||
|
}
|
||||||
|
return 24ULL * 3600ULL * 1000000ULL; // fallback: 24h
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
// Setup
|
// Setup
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
|
|||||||
Reference in new issue
Block a user