From 5e14daa6697e4cba2857b7e9a4c8de621c85d1e7 Mon Sep 17 00:00:00 2001 From: Brandon Li Date: Sun, 13 Sep 2026 13:57:06 -0500 Subject: [PATCH] =?UTF-8?q?Drain=20days=20draw=20from=20a=20$4=E2=80=93$15?= =?UTF-8?q?=20half-dollar=20grid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 23 deterministic values per (account, date) instead of $5/$10/$15; the qualifying floor moves to the grid minimum so every draw counts toward the cycle. The per-stage min-day field no longer drives the amount. Co-Authored-By: Claude Fable 5 --- lib/trading-logic.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/trading-logic.ts b/lib/trading-logic.ts index 7f57630..712f9d9 100644 --- a/lib/trading-logic.ts +++ b/lib/trading-logic.ts @@ -6,7 +6,8 @@ export interface WithdrawalStage { * days of ~minDayPnL (tiny MNQ trades), then wait for the withdrawal. */ drain?: boolean; /** Drain stages only: the per-day booked amount (default $5; randomized - * $5–$15 by drainDayAmount). */ + * the fixed $4–$15 half-dollar grid by drainDayAmount; this field is + * kept for the wire format but no longer drives the amount). */ minDayPnL?: number; /** Payout overrides for the withdrawal that completes THIS stage; absent * fields fall back to the account type's defaults. */ @@ -62,7 +63,9 @@ export function resolveEffectiveConfig( profitTarget: 0, consistency: 0, minTradingDays: stage.minTradingDays || minTradingDays, - minDayPnL: stage.minDayPnL || 5, + // Drain amounts come from the fixed $4–$15 grid, so the + // qualifying bar sits at the grid floor — every draw counts. + minDayPnL: DRAIN_DAY_MIN, drain: true, }; } @@ -138,14 +141,20 @@ export function currentTradeDateCT(now: Date = new Date()): string { * depending on the (account, trade date) pair). Seeded like dailyBump so * every consumer of the plan computes the same number. */ -export function drainDayAmount(accountId: number, tradeDate: string, minDay: number): number { +/** Drain-day target grid: $4–$15 in $0.50 steps (23 values), always traded + * on MNQ. Drain days qualify at ≥ DRAIN_DAY_MIN, so every draw counts. */ +export const DRAIN_DAY_MIN = 4; +export const DRAIN_DAY_MAX = 15; +const DRAIN_DAY_STEPS = Math.round((DRAIN_DAY_MAX - DRAIN_DAY_MIN) / 0.5) + 1; + +export function drainDayAmount(accountId: number, tradeDate: string): number { const key = `${accountId}|drain|${tradeDate}`; let hash = 0x811c9dc5; for (let i = 0; i < key.length; i++) { hash ^= key.charCodeAt(i); hash = Math.imul(hash, 0x01000193) >>> 0; } - return round2(minDay + (hash % 21) * 0.5); + return round2(DRAIN_DAY_MIN + (hash % DRAIN_DAY_STEPS) * 0.5); } /** @@ -759,7 +768,7 @@ export function computeDayPlan( : priorDays.filter((d) => d.pnl !== 0); const dayTarget = qualifying.length >= minTradingDays ? 0 - : drainDayAmount(accountId, tradeDate, minDayPnL || 5); + : drainDayAmount(accountId, tradeDate); return { dayTarget, remainingToday: round2(dayTarget - realizedPnL),