Vest: only a long closure holds entries back; the maintenance hour is ridden

The close gate held every Vest entry within four holds of any close,
which with a 2 h hold meant no weekday entry from about 9 AM to 5 PM ET
for the one-hour maintenance break. That hour reopens before the reset,
as CME's daily break does for futures legs, so only a weekend or holiday
closure gates an entry now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-10-27 14:51:00 -05:00
co-authored by Claude Opus 5.5
parent ef15200e5e
commit b5939a06a0
3 changed files with 28 additions and 14 deletions
+11 -7
View File
@@ -1625,10 +1625,11 @@ export class VestClient implements PlatformClient {
if (known.length > 0) await this.refreshMarks(known);
const vols = await this.volatility(known);
const now = Date.now();
// A leg its symbol's market close (the weekend, the daily maintenance
// hour) catches open can't be exited until the market reopens, and
// meets the reopen's gap with its stop: none starts under
// RESET_CLEAR_HOLDS holds of the close — the daily reset's clearance.
// A leg a long closure (a weekend, a holiday) catches open can't be
// exited until the market reopens, and meets the reopen's gap with
// its stop: none starts under RESET_CLEAR_HOLDS holds of one — the
// daily reset's clearance. The daily maintenance hour reopens before
// the reset and is ridden, as futures legs ride CME's daily break.
// Such a symbol stays on the board (the dashboard's candidates) but
// isn't picked (legCloseNote); fireLeg holds each account's own leg
// to it too.
@@ -1648,8 +1649,11 @@ export class VestClient implements PlatformClient {
const mark = this.marks.get(symbol);
const vol = vols.get(symbol);
let hours: { open: boolean; closesAt: number | null };
let gateAt: number | null;
try {
hours = marketOpen(await this.marketHours(spec.assetId), now);
const periods = await this.marketHours(spec.assetId);
hours = marketOpen(periods, now);
gateAt = hours.closesAt !== null && longClosure(periods, hours.closesAt) ? hours.closesAt : null;
} catch (err) {
board.push({ symbol, score: null, note: `market hours unknown (${errorMessage(err)})` });
continue;
@@ -1673,7 +1677,7 @@ export class VestClient implements PlatformClient {
volatilityPerHour: vol?.vol ?? null,
});
if (score === null) { board.push({ symbol, score: null, note: 'no volatility' }); continue; }
const closing = legCloseNote(hours.closesAt, hold, now);
const closing = legCloseNote(gateAt, hold, now);
board.push({
symbol,
score,
@@ -1692,7 +1696,7 @@ export class VestClient implements PlatformClient {
spreadFraction: spread,
minContracts: 1,
marginRate: spec.marginRate || undefined,
closesAt: hours.closesAt ?? undefined,
closesAt: gateAt ?? undefined,
},
});
}