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
+10
-6
@@ -1327,12 +1327,14 @@ export function obfuscationStopDollars(
|
||||
* that fills worse than its price (gaps, thin weekend books). */
|
||||
export const DLL_RESERVE_FRACTION = 0.10;
|
||||
/** …or this share of the position's notional, when that is more: a stop's
|
||||
* slippage grows with the position, a flat reserve doesn't. */
|
||||
* slippage grows with the position, a flat reserve doesn't. A platform whose
|
||||
* stops are known to fill closer states its own (stopSlippageFraction). */
|
||||
export const DLL_SLIPPAGE_FRACTION = 0.001;
|
||||
|
||||
/** The part of the day's room a stop leaves unspent. */
|
||||
export function dllReserve(dailyLossLimit: number, notional = 0): number {
|
||||
return Math.max(DLL_RESERVE_FRACTION * dailyLossLimit, DLL_SLIPPAGE_FRACTION * Math.max(0, notional));
|
||||
export function dllReserve(dailyLossLimit: number, notional = 0, slippageFraction = DLL_SLIPPAGE_FRACTION): number {
|
||||
const share = Number.isFinite(slippageFraction) && slippageFraction >= 0 ? slippageFraction : DLL_SLIPPAGE_FRACTION;
|
||||
return Math.max(DLL_RESERVE_FRACTION * dailyLossLimit, share * Math.max(0, notional));
|
||||
}
|
||||
/** Smallest daily-loss stop worth trading. Under a fair walk a leg of L with a
|
||||
* stop of S wins S/(S + L) of the time — about 9% for $50 against $500 — so
|
||||
@@ -1454,10 +1456,10 @@ export function dllRoom(o: {
|
||||
* reset has its entry fee on the old day's books, and the swap takes no more
|
||||
* than that slot on the new day's.
|
||||
*/
|
||||
export function dllStopDollars(o: { room: number; dailyLossLimit: number; entryFee: number; commissionPct: number; notional?: number }): number {
|
||||
export function dllStopDollars(o: { room: number; dailyLossLimit: number; entryFee: number; commissionPct: number; notional?: number; slippageFraction?: number }): number {
|
||||
if (!Number.isFinite(o.room)) return Infinity;
|
||||
const r = Math.max(0, o.commissionPct) / 100;
|
||||
return (o.room - dllReserve(o.dailyLossLimit, o.notional) - 2 * o.entryFee - 0.01) / (1 + r);
|
||||
return (o.room - dllReserve(o.dailyLossLimit, o.notional, o.slippageFraction) - 2 * o.entryFee - 0.01) / (1 + r);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1765,6 +1767,8 @@ export function planLegSize(o: {
|
||||
/** Infinity (or ≤ 0) = no obfuscation stop. */
|
||||
obfuscationDollars: number;
|
||||
availableFunds?: number;
|
||||
/** The platform's stopSlippageFraction; default DLL_SLIPPAGE_FRACTION. */
|
||||
slippageFraction?: number;
|
||||
}): {
|
||||
lastStand: boolean;
|
||||
cap: number;
|
||||
@@ -1780,7 +1784,7 @@ export function planLegSize(o: {
|
||||
obf,
|
||||
!dllOn ? Infinity
|
||||
: stand ? breachDistance({ dllRoom: o.dllRoom, maxLossRoom: o.maxLossRoom, entryFee: r * notional })
|
||||
: dllStopDollars({ room: o.dllRoom, dailyLossLimit: o.dailyLossLimit, entryFee: r * notional, commissionPct: o.commissionPct, notional }),
|
||||
: dllStopDollars({ room: o.dllRoom, dailyLossLimit: o.dailyLossLimit, entryFee: r * notional, commissionPct: o.commissionPct, notional, slippageFraction: o.slippageFraction }),
|
||||
);
|
||||
const cap = notionalCap({ marginRate: o.contract.marginRate, availableFunds: o.availableFunds });
|
||||
const step = o.contract.stepNotional ?? 0;
|
||||
|
||||
Reference in New Issue
Block a user