Vest: record every trade, the bot's and outside ones, and list them

Vest's position history (GET /v3/positions) gives each position's size,
open and close price, P&L, fees, funding and why it closed. The client
reads it hourly and a minute after a position closes (or a flat balance
moves) into a new trades table, and stores open positions as they
appear. Vest can't tell an API order from a click, so the bot marks its
own opens and closes as it sends them; an unmarked trade since marking
began was someone else's.

The dashboard's Vest firm row gets a Trades button listing every trade
on its accounts with who opened it and how it closed; the account page
shows its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-10-26 19:23:24 -05:00
co-authored by Claude Opus 5.5
parent 29eaf64a6b
commit 95cc3bd23f
10 changed files with 603 additions and 4 deletions
+27
View File
@@ -176,3 +176,30 @@ export interface FirmState {
connected: boolean;
accounts: AccountState[];
}
/** One recorded position (GET /api/trades) — Vest's position history plus
* what this instance did itself. */
export interface TradeView {
positionId: string;
accountId: number;
accountName: string;
symbol: string;
side: 'long' | 'short';
quantity: number;
openPrice: number | null;
closePrice: number | null;
/** Realized P&L before fees and funding. */
pnl: number | null;
fee: number | null;
funding: number | null;
/** pnl − fee + funding; null while open (or unknown). */
net: number | null;
openedAt: number;
closedAt: number | null;
/** null: opened before this instance began marking its own trades. */
openedBy: 'bot' | 'outside' | null;
/** null while open; else 'bot', 'outside' (closed by hand or another
* tool), or the platform's own reason (stop_loss, take_profit,
* liquidation, …; user_requested from before marking began). */
closedBy: string | null;
}