Vest: an entry never closes a hand trade, and a flatten never opens one

sendOrder takes an optional intent. On Vest an 'open' is refused when the
account already holds the symbol, where it used to close that position as
the "entry"; the leg's exits then found nothing and its flatten opened a
fresh position with no TP or stop. A 'close' only closes or reduces, and on
a flat account is refused with NothingToCloseError, which flattenAndFail
reports as nothing to flatten instead of FLATTEN FAILED. Entries, the
extra-day round trip and flattens pass their intent; the manual order route
and the other platforms keep today's behaviour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-10-27 14:03:14 -05:00
co-authored by Claude Opus 5.5
parent beddbdcf6c
commit e90f21ed91
5 changed files with 127 additions and 20 deletions
+28
View File
@@ -421,6 +421,34 @@ export function unrealizedPnl(p: Pick<VestPosition, 'side' | 'quantity' | 'openP
return (p.side === 'long' ? 1 : -1) * p.quantity * (mark - p.openPrice);
}
/**
* What an order on `side` does to the account's position in the symbol
* (`held`: its side, null when flat), or why nothing is sent. With no intent
* a flat account opens and the opposite side closes or reduces. An entry
* ('open') never closes: a hand trade the engine didn't know about would be
* closed in its place, and the leg's flatten would then open a position with
* no exits. A flatten ('close') never opens: nothingToClose says the account
* is flat in the symbol. Adding to a position is never supported.
*/
export function vestOrderEffect(o: {
symbol: string;
held: 'long' | 'short' | null;
side: 'long' | 'short';
intent?: 'open' | 'close';
}): { effect: 'open' | 'close' } | { refused: string; nothingToClose?: true } {
const { symbol, held, side, intent } = o;
if (held === side) {
return {
refused: intent === 'close'
? `the account holds a ${held} ${symbol} position, not one to close — nothing sent`
: `adding to an open ${symbol} position is not supported`,
};
}
if (held && intent === 'open') return { refused: `a ${held} ${symbol} position is already open — an entry never closes it, order not sent` };
if (!held && intent === 'close') return { refused: `no ${symbol} position to close — nothing sent`, nothingToClose: true };
return { effect: held ? 'close' : 'open' };
}
// ── transactions ────────────────────────────────────────────────────────────
/**