From bd72c4b1f6d61171dec4eb6a71d725065d58e02a Mon Sep 17 00:00:00 2001 From: Brandon Li Date: Tue, 8 Sep 2026 21:23:12 -0500 Subject: [PATCH] Fold weekend-dated P&L rows into the next settling day when combining MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cash History rows can carry a weekend calendar date (Sunday-evening activity attributed pre-roll), and those slipped through the holiday combining as their own trading day — accounts traded only across the Labor Day Sun/Mon/Tue stretch read 2/5 instead of 1/5. Weekends never clear at CME any more than holidays do, so treat Saturday and Sunday as unsettled dates and roll them forward with the rest of the stretch. Co-Authored-By: Claude Fable 5 --- lib/trading-logic.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/trading-logic.ts b/lib/trading-logic.ts index 123f68f..2ba3c96 100644 --- a/lib/trading-logic.ts +++ b/lib/trading-logic.ts @@ -162,23 +162,28 @@ function cmeUnsettledDates(year: number): Set { return dates; } -function isUnsettledTradeDate(date: string): boolean { +/** Weekends never clear either — a weekend-dated Cash History row (Sunday + * evening activity attributed to its calendar date) belongs to the next + * settling day, which is precisely why Apex's holiday notices say "Sunday, + * Monday, and Tuesday" and not just the holiday itself. */ +function isUnsettledTradeDate(date: string, dayOfWeek: number): boolean { + if (dayOfWeek === 0 || dayOfWeek === 6) return true; return cmeUnsettledDates(Number(date.slice(0, 4))).has(date); } -/** The trade date a session clears under: holiday sessions roll forward, past - * weekends and any consecutive holiday, to the next date that settles. */ +/** The trade date a session clears under: weekend- and holiday-dated activity + * rolls forward, through any consecutive unsettled dates, to the next date + * that settles. */ export function combinedTradeDate(date: string): string { - if (!/^\d{4}-\d{2}-\d{2}$/.test(date) || !isUnsettledTradeDate(date)) return date; + if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) return date; const d = new Date(`${date}T00:00:00Z`); + if (!isUnsettledTradeDate(date, d.getUTCDay())) return date; for (let i = 0; i < 7; i++) { d.setUTCDate(d.getUTCDate() + 1); const next = fmtUTC(d); - const dow = d.getUTCDay(); - if (dow === 0 || dow === 6) continue; // weekends never settle - if (!isUnsettledTradeDate(next)) return next; + if (!isUnsettledTradeDate(next, d.getUTCDay())) return next; } - return date; // unreachable: no holiday stretch spans a week + return date; // unreachable: no unsettled stretch spans a week } export interface CombinedSessionView {