Vest: a split day's next leg gives back the day's gain plus the limit

On a split day the next Vest leg's daily-loss room now adds the day's gain
still in the account to the bot's limit (floorRoom's `gain`), never past
Vest's own floor, and the leg sizes up for the same target hold (Dingo's
next eval leg: $455k -> $842k at 1.5 h, win 28% -> 56%). Other platforms
are unchanged: dllRoom still never widens on a green day.

The gain only widens a leg all but sure to close before Vest's 8 PM ET
reset (resetClearStop, held to the shortest leg the day may carve), and
none of a hand claim's profit counts. The last-stand margin is measured
against the limit, so a green day can't drop a leg's stop.

Around the reset: no new Vest position opens in the last 7 minutes, and
the guard re-fits every 15 s on fresh positions instead of one pass. An
account's positions share the next-day room (stops first, least at risk
first; locked-in profit counts), a hand-moved stop is fitted again, and a
close or profit-side stop that doesn't take is retried or closed.

The dashboard's next stop now reserves for the leg's notional, as fireLeg
does, so DXtrade labels read smaller (display only).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-10-27 07:21:52 -05:00
co-authored by Claude Opus 5.5
parent 1e844178de
commit f0c1569d96
9 changed files with 364 additions and 89 deletions
+5 -2
View File
@@ -11,7 +11,7 @@ import type { PlatformContract } from './platform-client';
import type { SymbolStats } from './master-protocol';
import {
combineCmeSessions, computeDayPlan, resolveEffectiveConfig, obfuscationStopDollars, dllRoom as computeDllRoom,
planLegSize, rankForTarget, maxLossRoom, lastStand, dllStopDollars, stageInputsFor, floorRoom,
planLegSize, rankForTarget, maxLossRoom, lastStand, dllStopDollars, stageInputsFor, floorRoom, shortestNextLeg,
FALLBACK_COMMISSION_PER_CONTRACT,
} from './trading-logic';
@@ -27,6 +27,8 @@ export function dayLossRoom(
dll: number,
cash: { amount: number; realizedPnL: number },
combinedRealized: number,
/** The shortest take-profit the next leg may have (shortestNextLeg). */
nextLeg: number,
): number | null {
if (!(dll > 0)) return null;
const floor: number | null | undefined = client.dailyLossFloor?.(accountId);
@@ -35,6 +37,7 @@ export function dayLossRoom(
return floorRoom({
dailyLossLimit: dll, closedBalance: cash.amount, floor,
realizedToday: Math.min(cash.realizedPnL, combinedRealized),
gain: client.dayGainForRoom?.(accountId, { leg: nextLeg, limit: dll }) ?? 0,
});
}
const dayStart = client.dayStartBalance?.(accountId);
@@ -143,7 +146,7 @@ function accountPlan(
);
if (!plan) return null;
const dll = effective.dailyLossLimit;
const room = dayLossRoom(client, acc.id, dll, cash, combined.realizedPnL);
const room = dayLossRoom(client, acc.id, dll, cash, combined.realizedPnL, shortestNextLeg(plan));
const obfuscation = obfuscationStopDollars(cfg, combined.dailyPnL, plan, combined.tradeDate, plan.remainingToday);
return { cfg, cash, plan, dll, room, obfuscation };
}