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
+18
View File
@@ -263,6 +263,24 @@ test('resetSafeStop: fit an open position into the room the reset will leave', (
const dd = resetSafeStop({ ...base, maxDrawdownFloor: 49000, currentStop: null });
assert.equal(dd.action, 'stop');
assert.ok(dd.price > want);
// A second position on the account gets what the first leaves: $500
// already committed at the first one's stop, from the same $48,500 floor.
const second = resetSafeStop({ ...base, balance: 49500, floorBalance: 50000, currentStop: null });
assert.equal(second.action, 'stop');
assert.equal(second.price, Math.ceil((29500 - (allowed - 500) / 4) / 0.25) * 0.25);
assert.ok(second.price > want);
// ...and nothing when the first takes it all.
assert.deepEqual(resetSafeStop({ ...base, balance: 48600, floorBalance: 50000, currentStop: null }), { action: 'close' });
// With no room left, a position already up keeps going on a stop that
// locks in the shortfall: one already locking in more is left alone...
const up = { ...base, mark: 29560, balance: 48600, floorBalance: 50000 };
assert.deepEqual(resetSafeStop({ ...up, currentStop: 29520 }), { action: 'none' });
// ...one with none gets it, on the profit side, still under the mark...
const shortfall = 48600 - 48500 - 150 - 0.000025 * 4 * 29560;
assert.deepEqual(resetSafeStop({ ...up, currentStop: null }), { action: 'stop', price: Math.ceil((29500 - shortfall / 4) / 0.25) * 0.25 });
assert.ok(resetSafeStop({ ...up, currentStop: null }).price > 29500);
// ...and with no mark to tell, it closes.
assert.deepEqual(resetSafeStop({ ...up, mark: NaN, currentStop: null }), { action: 'close' });
});
test('parseHistoryPosition: a closed position from GET /v3/positions', () => {