Vest: stops reserve 0.02% of the position for slippage, not 0.1%
A platform may now state its own stop slippage share (PlatformClient.stopSlippageFraction); the daily-loss reserve is the larger of 10% of the limit and that share of the position. Vest's 9 measured stop-outs filled 0.9 points past the trigger on average and 2.25 at worst, against the ~30 points 0.1% held back. On a $1,400 day with ~$495k of NDX the stop goes from ~$880 to ~$1,230, and the leg sizes up for the same hold. Sizing, the placed stop, the dashboard's next stop and the reset guard all use it; other platforms keep 0.1%. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f0c1569d96
commit
beddbdcf6c
@@ -419,6 +419,21 @@ test('the daily-loss reserve grows with the position past 10% of the limit', ()
|
||||
assert.equal(dllStopDollars({ room: 3000, dailyLossLimit: 3000, entryFee: 0, commissionPct: 0 }), 2699.99);
|
||||
});
|
||||
|
||||
test('a platform whose stops fill closer reserves its own share of the position', () => {
|
||||
// Me's Vest eval on 2026-10-27: $1,400 of room on $495,439 of NDX. At the
|
||||
// 0.1% default the reserve is $495.44; at 0.02% the flat $140 binds.
|
||||
const n = 495439;
|
||||
assert.ok(Math.abs(dllReserve(1400, n) - 495.439) < 1e-9);
|
||||
assert.equal(dllReserve(1400, n, 0.0002), 140);
|
||||
assert.ok(Math.abs(dllReserve(1400, 900000, 0.0002) - 180) < 1e-9, 'past $700k the share binds again');
|
||||
// Left out, or not a share at all: the default.
|
||||
for (const bad of [undefined, NaN, -0.0002, Infinity]) assert.equal(dllReserve(1400, n, bad), dllReserve(1400, n), String(bad));
|
||||
assert.equal(dllReserve(1400, n, 0), 140, 'no slippage at all still keeps the flat 10%');
|
||||
const stop = (slippageFraction) => dllStopDollars({ room: 1400, dailyLossLimit: 1400, entryFee: 12.45, commissionPct: 0, notional: n, slippageFraction });
|
||||
assert.ok(Math.abs(stop(undefined) - (1400 - 495.439 - 24.9 - 0.01)) < 1e-9);
|
||||
assert.ok(Math.abs(stop(0.0002) - (1400 - 140 - 24.9 - 0.01)) < 1e-9);
|
||||
});
|
||||
|
||||
test('max-drawdown room: the static floor, the broker floor, the higher', () => {
|
||||
assert.equal(maxLossRoom({ balance: 99757.39, accountSize: 100000, maxLoss: 6000 }), 5757.39);
|
||||
assert.equal(maxLossRoom({ balance: 99757.39, accountSize: 100000, maxLoss: -6000 }), 5757.39);
|
||||
@@ -531,6 +546,30 @@ test('planLegSize: a split day\'s next leg, with the day\'s gain on its stop, si
|
||||
assert.ok(widened.walkAt(n) > 2604.24 && widened.walkAt(n) < 4004.24, `stop ${widened.walkAt(n)}`);
|
||||
});
|
||||
|
||||
test('planLegSize: a platform\'s own slippage share widens the stop and sizes the leg up for the same hold', () => {
|
||||
// Me's first-day Vest eval leg on 2026-10-27: $5,000 to pass, $1,400 of
|
||||
// room, NDX at ~$29.8k, sized for 2.6 h.
|
||||
const ndx = { stepNotional: 2.98, volatilityPerHour: 0.0131 / Math.sqrt(24), spreadFraction: 0.0000085, marginRate: 0.02 };
|
||||
const leg = {
|
||||
leg: 5000, contract: ndx, commissionPct: 0.0025, targetHoldHours: 2.6, financingPctPerDay: 0,
|
||||
dailyLossLimit: 1400, dllRoom: 1400, obfuscationDollars: Infinity, availableFunds: 50000, maxLossRoom: 3000,
|
||||
};
|
||||
const deflt = planLegSize(leg);
|
||||
const vest = planLegSize({ ...leg, slippageFraction: 0.0002 });
|
||||
assert.equal(planLegSize({ ...leg, slippageFraction: undefined }).sizing.notional, deflt.sizing.notional);
|
||||
for (const p of [deflt, vest]) {
|
||||
assert.equal(p.lastStand, false);
|
||||
assert.ok(Math.abs(p.sizing.predictedHoldHours - 2.6) < 0.05, `hold ${p.sizing.predictedHoldHours}`);
|
||||
}
|
||||
const r = 0.0025 / 100;
|
||||
const nd = deflt.sizing.notional, nv = vest.sizing.notional;
|
||||
assert.ok(Math.abs(deflt.walkAt(nd) - (1400 - 0.001 * nd - 2 * r * nd - 0.01) / (1 + r)) < 1e-9);
|
||||
assert.ok(Math.abs(vest.walkAt(nv) - (1400 - 140 - 2 * r * nv - 0.01) / (1 + r)) < 1e-9, 'the flat $140 binds');
|
||||
assert.ok(vest.walkAt(nv) > 1200 && deflt.walkAt(nd) < 950, `stops ${vest.walkAt(nv)} vs ${deflt.walkAt(nd)}`);
|
||||
assert.ok(nv > 1.1 * nd, `${nv} vs ${nd}`);
|
||||
assert.ok(vest.sizing.winProbability > deflt.sizing.winProbability);
|
||||
});
|
||||
|
||||
test('personSizeFactor: one draw per person and trade date, within the spread', () => {
|
||||
const people = Array.from({ length: 300 }, (_, i) => `0b6f${i.toString(16).padStart(4, '0')}-5c1e-4a7e-9d2b-${i}`);
|
||||
const draws = people.map((p) => personSizeFactor(p, '2026-10-20'));
|
||||
|
||||
Reference in New Issue
Block a user