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:
co-authored by
Claude Opus 5.5
parent
beddbdcf6c
commit
e90f21ed91
@@ -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 ────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user