Demote/relabel the setup-outcome check; add exit reason to My Trades
The "tracking/drift" chip compared the live target/stop/expired outcome cohort against the backtest's target/stop bucket (overall_qualified) — a like-for-like pipeline check — but sat directly under the portfolio monitor, which shows the promoted 3x-ATR-trailing book. That juxtaposition (plus "faithfully implementing it" copy) made a plumbing/QA signal read as validation of the ATR-trail strategy you actually trade. It validates neither the trailing-stop book nor real trades. - Move the check out of the monitor block into the "Track-record maintenance" disclosure, relabelled "Setup-outcome pipeline check" with copy that says it checks the setup-grading pipeline (no look-ahead/config/data drift), NOT the ATR-trail production book. The genuine live validation stays My Trades (real paper trades, same ATR-trail exits) up top. - Add a compact "Exit" column to My Trades showing close_reason (Stop/Trail/Target/Time/Manual) — the field was already plumbed to the frontend PaperTrade type, so this is frontend-only. tsc -b && vite build pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,18 @@ function color(v: number | null): string {
|
||||
return 'text-gray-300';
|
||||
}
|
||||
|
||||
// How the trade was closed — useful context on real trades at almost no cost.
|
||||
function reasonMeta(reason: string | null): { label: string; cls: string } {
|
||||
switch (reason) {
|
||||
case 'stop': return { label: 'Stop', cls: 'text-red-400' };
|
||||
case 'trailing': return { label: 'Trail', cls: 'text-amber-400' };
|
||||
case 'target': return { label: 'Target', cls: 'text-emerald-400' };
|
||||
case 'time': return { label: 'Time', cls: 'text-gray-400' };
|
||||
case 'manual': return { label: 'Manual', cls: 'text-blue-300' };
|
||||
default: return { label: '—', cls: 'text-gray-500' };
|
||||
}
|
||||
}
|
||||
|
||||
function Stat({ label, value, valueClass = 'text-gray-100', sub }: {
|
||||
label: string; value: string; valueClass?: string; sub?: string;
|
||||
}) {
|
||||
@@ -85,6 +97,7 @@ export function MyTradesPanel() {
|
||||
<th className="px-4 py-2.5 text-right">P&L</th>
|
||||
<th className="px-4 py-2.5 text-right">R</th>
|
||||
<th className="px-4 py-2.5 text-right">Alpha</th>
|
||||
<th className="px-4 py-2.5">Exit</th>
|
||||
<th className="px-4 py-2.5 text-right">Closed</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -102,6 +115,11 @@ export function MyTradesPanel() {
|
||||
<td className={`num px-4 py-2.5 text-right font-semibold ${p ? color(p.pnl) : 'text-gray-500'}`}>{p ? money(p.pnl) : '—'}</td>
|
||||
<td className={`num px-4 py-2.5 text-right ${p?.r != null ? color(p.r) : 'text-gray-500'}`}>{p?.r != null ? fmtR(p.r) : '—'}</td>
|
||||
<td className={`num px-4 py-2.5 text-right ${t.alpha_pct != null ? color(t.alpha_pct) : 'text-gray-500'}`} title="Return vs. S&P 500 over the holding period">{t.alpha_pct != null ? `${t.alpha_pct >= 0 ? '+' : ''}${t.alpha_pct.toFixed(1)}%` : '—'}</td>
|
||||
<td className="px-4 py-2.5">
|
||||
<span className={`num text-[10px] font-semibold uppercase tracking-wider ${reasonMeta(t.close_reason).cls}`} title="How the trade was closed">
|
||||
{reasonMeta(t.close_reason).label}
|
||||
</span>
|
||||
</td>
|
||||
<td className="num px-4 py-2.5 text-right text-gray-500">{t.closed_at ? new Date(t.closed_at).toLocaleDateString() : '—'}</td>
|
||||
</tr>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user