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:
co-authored by
Claude Opus 5.5
parent
29eaf64a6b
commit
95cc3bd23f
@@ -5,6 +5,7 @@ import Link from 'next/link';
|
||||
import type { FirmConfig, FirmState, AccountState } from '@/types';
|
||||
import { stagePillClasses } from '@/lib/stage-colors';
|
||||
import { RulesDate } from '@/app/components/RulesDate';
|
||||
import { TradesTable } from '@/app/components/TradesTable';
|
||||
|
||||
type SortKey = 'name' | 'balance' | 'dayPnL' | 'daysTraded' | 'target' | 'status';
|
||||
type SortDir = 'asc' | 'desc';
|
||||
@@ -533,6 +534,7 @@ function FirmRows({ state, firm, hideDead, privacy, sortKey, sortDir, tradeSymbo
|
||||
onStateChanged: () => void;
|
||||
}) {
|
||||
const [open, setOpen] = useState(true);
|
||||
const [showTrades, setShowTrades] = useState(false);
|
||||
const [confirmCreds, setConfirmCreds] = useState(false);
|
||||
const [removingCreds, setRemovingCreds] = useState(false);
|
||||
const hasCredentials = firm.hasCredentials;
|
||||
@@ -650,6 +652,15 @@ function FirmRows({ state, firm, hideDead, privacy, sortKey, sortDir, tradeSymbo
|
||||
)}
|
||||
<td className="px-4 py-3.5">
|
||||
<div className="flex items-center justify-end gap-1">
|
||||
{firm.platform === 'vest' && hasCredentials && (
|
||||
<button
|
||||
onClick={(e) => { e.stopPropagation(); setShowTrades((v) => !v); }}
|
||||
className={`px-2 py-0.5 text-xs font-semibold rounded-md transition-colors ${showTrades ? 'bg-violet-100 text-violet-700' : 'text-slate-500 hover:bg-slate-200'}`}
|
||||
title="Every trade on this firm's accounts — the bot's and anyone else's — with how each one closed"
|
||||
>
|
||||
Trades
|
||||
</button>
|
||||
)}
|
||||
{hasCredentials && !confirmCreds && (
|
||||
<button
|
||||
onClick={(e) => { e.stopPropagation(); setConfirmCreds(true); }}
|
||||
@@ -672,6 +683,14 @@ function FirmRows({ state, firm, hideDead, privacy, sortKey, sortDir, tradeSymbo
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{showTrades && hasCredentials && (
|
||||
<tr className="border-b border-slate-100">
|
||||
<td colSpan={7} className="px-4 py-3 pl-12 bg-white">
|
||||
<TradesTable query={`firmId=${encodeURIComponent(firm.id)}`} showAccount formatAccount={(n) => maskName(n, privacy)} />
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
|
||||
{open && hasCredentials && (
|
||||
state.accounts.length === 0 ? (
|
||||
<tr>
|
||||
|
||||
Reference in New Issue
Block a user