Add random 1-20 min daily jitter to trading session open
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a36e227e74
commit
906275cc33
+26
-3
@@ -122,11 +122,30 @@ function evaluateAccountForTrade(client: any, acc: { id: number; name: string; a
|
|||||||
|
|
||||||
// ── helpers ───────────────────────────────────────────────────────────────────
|
// ── helpers ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
// Random 1–20 minute delay added to the session open, picked once per Central
|
||||||
|
// calendar day. Re-rolling on every check would move the open boundary between
|
||||||
|
// polls, letting a trade slip through a moment the next check would reject.
|
||||||
|
const sessionOpenJitter = new Map<string, number>();
|
||||||
|
|
||||||
|
function openJitterMinutes(centralDay: string): number {
|
||||||
|
let jitter = sessionOpenJitter.get(centralDay);
|
||||||
|
if (jitter === undefined) {
|
||||||
|
jitter = 1 + Math.floor(Math.random() * 20); // 1–20 inclusive
|
||||||
|
sessionOpenJitter.clear(); // only today's entry is ever needed
|
||||||
|
sessionOpenJitter.set(centralDay, jitter);
|
||||||
|
console.log(`[trading-hours] session open delayed ${jitter} min today`);
|
||||||
|
}
|
||||||
|
return jitter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true when trading is not allowed based on the trading_hours setting.
|
* Returns true when trading is not allowed based on the trading_hours setting.
|
||||||
*
|
*
|
||||||
* "full_cme" — Sun 5:05 PM – Fri 2:55 PM Central (5 min buffer on each side)
|
* "full_cme" — Sun 5:05 PM – Fri 2:55 PM Central (5 min buffer on each side)
|
||||||
* "equity_hours" — 8:35 AM – 2:55 PM Central, Mon–Fri (5 min buffer on each side)
|
* "equity_hours" — 8:35 AM – 2:55 PM Central, Mon–Fri (5 min buffer on each side)
|
||||||
|
*
|
||||||
|
* The open side of each window is pushed back by a random 1–20 minutes per day
|
||||||
|
* (see openJitterMinutes) so sessions never start at the exact same time.
|
||||||
*/
|
*/
|
||||||
function isInNoTradeWindow(): boolean {
|
function isInNoTradeWindow(): boolean {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
@@ -143,6 +162,10 @@ function isInNoTradeWindow(): boolean {
|
|||||||
timeZone: 'America/Chicago',
|
timeZone: 'America/Chicago',
|
||||||
}).format(now); // "Sun", "Mon", ... "Sat"
|
}).format(now); // "Sun", "Mon", ... "Sat"
|
||||||
const timeMinutes = hour * 60 + minute; // minutes since midnight
|
const timeMinutes = hour * 60 + minute; // minutes since midnight
|
||||||
|
const centralDay = new Intl.DateTimeFormat('en-CA', {
|
||||||
|
timeZone: 'America/Chicago',
|
||||||
|
}).format(now); // "2026-09-06"
|
||||||
|
const jitter = openJitterMinutes(centralDay);
|
||||||
|
|
||||||
const mode = getSetting('trading_hours') ?? 'full_cme';
|
const mode = getSetting('trading_hours') ?? 'full_cme';
|
||||||
|
|
||||||
@@ -150,7 +173,7 @@ function isInNoTradeWindow(): boolean {
|
|||||||
// Equity hours: 8:30 AM – 3:00 PM Central with 5 min buffer = 8:35 AM – 2:55 PM
|
// Equity hours: 8:30 AM – 3:00 PM Central with 5 min buffer = 8:35 AM – 2:55 PM
|
||||||
// Weekdays only
|
// Weekdays only
|
||||||
if (day === 'Sat' || day === 'Sun') return true;
|
if (day === 'Sat' || day === 'Sun') return true;
|
||||||
const open = 8 * 60 + 35; // 8:35 AM
|
const open = 8 * 60 + 35 + jitter; // 8:35 AM + daily jitter
|
||||||
const close = 14 * 60 + 55; // 2:55 PM
|
const close = 14 * 60 + 55; // 2:55 PM
|
||||||
return timeMinutes < open || timeMinutes >= close;
|
return timeMinutes < open || timeMinutes >= close;
|
||||||
}
|
}
|
||||||
@@ -161,8 +184,8 @@ function isInNoTradeWindow(): boolean {
|
|||||||
// Saturday — market closed all day
|
// Saturday — market closed all day
|
||||||
if (day === 'Sat') return true;
|
if (day === 'Sat') return true;
|
||||||
|
|
||||||
// Sunday — market opens at 5:05 PM Central
|
// Sunday — market opens at 5:05 PM Central (+ daily jitter)
|
||||||
const cmeOpen = 17 * 60 + 5; // 5:05 PM
|
const cmeOpen = 17 * 60 + 5 + jitter; // 5:05 PM + daily jitter
|
||||||
if (day === 'Sun') return timeMinutes < cmeOpen;
|
if (day === 'Sun') return timeMinutes < cmeOpen;
|
||||||
|
|
||||||
// Friday — stop trading at 2:55 PM Central
|
// Friday — stop trading at 2:55 PM Central
|
||||||
|
|||||||
Reference in New Issue
Block a user