Vest: a claim within $25 of target names its cycle, the newest goes first, and a batch on a turned day stops

The auto-claim takes a cycle as done within LEG_COMPLETION_EPSILON of its
target, so the cycle it names is judged at that tolerance too. Each saved
cycle keeps its claim's time, and the report lists a day's claims newest
first, so the master's per-slice cap can't hold the latest back. A batch
or copy whose client's day turned while it chose (Vest, at the first sync
after 8 PM ET) is abandoned rather than sized and counted on the old day.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-10-27 16:27:07 -05:00
co-authored by Claude Opus 5.5
parent dc210ffcb7
commit bf7e147507
6 changed files with 59 additions and 18 deletions
+8 -3
View File
@@ -982,7 +982,7 @@ export function endedCycleCompletion(opts: {
}
/** A completed cycle a payout claim ended (claimedCycle). */
export interface ClaimedCycle { date: string; stage: number; drain: boolean; cycle: string; cycleSeq: number }
export interface ClaimedCycle { date: string; stage: number; drain: boolean; cycle: string; cycleSeq: number; at?: number }
/**
* The cycle a payout claim about to go out ends (PlatformClient.claimProfit),
@@ -1020,6 +1020,7 @@ export function claimedCycle(
combineCmeHolidays?: boolean; tradesEveryDay?: boolean; dailyLossLimit?: number; stagesSameDay?: boolean;
},
now: Date = new Date(),
tolerance = 0,
): ClaimedCycle | null {
const cash = client.accountCashBalances[accountId];
const cycleDailyPnL = client.dailyPnL[accountId];
@@ -1029,11 +1030,15 @@ export function claimedCycle(
cfg.profitTarget, cfg.consistency, cfg.minTradingDays, cfg.targetSameEquity, cfg.withdrawalStages,
client.priorProfit?.[accountId] ?? 0, fundTransactions, cfg.minDayPnL, stageInputsFor(client, accountId, cfg),
);
// `tolerance`: how far short of the target the claim still ends the
// cycle — the engine's day is done within LEG_COMPLETION_EPSILON of it.
const judged = tolerance > 0 && effective.profitTarget > tolerance
? { ...effective, profitTarget: effective.profitTarget - tolerance } : effective;
const rawTradeDate = tradeDateFor(client, now);
const completion = cycleCompletion({
accountId, rawTradeDate, client, cycleDailyPnL, rawRealizedPnL: cash.realizedPnL,
combineCmeHolidays: cfg.combineCmeHolidays === true, tradesEveryDay: cfg.tradesEveryDay === true,
effective, equityProfit: cash.amount - cfg.accountSize, splitEnabled: cfg.splitEnabled, now,
effective: judged, equityProfit: cash.amount - cfg.accountSize, splitEnabled: cfg.splitEnabled, now,
});
if (completion === 'none') return null;
const cycle = client.lastFundDates?.[accountId] ?? '';
@@ -1041,7 +1046,7 @@ export function claimedCycle(
const place = completionPlace({ payoutDays, fundTransactions, cycle });
return {
date: combineCmeSessions(effectiveCombine(cfg), [], rawTradeDate, 0).tradeDate,
stage: place.stage, drain: effective.drain, cycle, cycleSeq: place.cycleSeq,
stage: place.stage, drain: effective.drain, cycle, cycleSeq: place.cycleSeq, at: now.getTime(),
};
}