"use client"; import { DrawdownChart, LinesChart, type LineSpec } from "@/components/charts"; import { Badge, Card, Empty, KV, Table, Td, Th, cx } from "@/components/ui"; import { fmtBps, fmtDate, fmtNum, fmtPct, fmtPctPlain, fmtRatio, fmtTs, fmtUsd, signClass } from "@/lib/format"; import type { Artifacts, Metrics, Run } from "@/lib/types"; const BENCH_COLORS: Record = { buy_and_hold: "#f59e0b", cash: "#66718a", simple_momentum: "#a855f7", equal_risk: "#14b8a6" }; export function MetricsGrid({ m, compact = false }: { m: Metrics; compact?: boolean }) { const ci = m.bootstrap?.sharpe_ci; const items: [string, string, string?][] = [ ["CAGR", fmtPct(m.cagr), signClass(m.cagr)], ["Total return", fmtPct(m.total_return), signClass(m.total_return)], ["Volatility (ann.)", fmtPctPlain(m.volatility)], ["Sharpe", `${fmtRatio(m.sharpe)}${ci && ci[0] != null ? ` [${fmtRatio(ci[0])}, ${fmtRatio(ci[1])}]` : ""}`], ["Deflated Sharpe (prob.)", m.deflated_sharpe?.dsr != null ? `${fmtPctPlain(m.deflated_sharpe.dsr)} (${m.deflated_sharpe.n_trials ?? 1} trials)` : "—"], ["Sortino", fmtRatio(m.sortino)], ["Max drawdown", fmtPct(m.max_drawdown), "text-down"], ["Calmar", fmtRatio(m.calmar)], ["Turnover (ann.)", `${fmtRatio(m.turnover_annual, 1)}×`], ["Exposure", fmtPctPlain(m.exposure)], ["Trades / round trips", `${m.n_trades ?? "—"} / ${m.n_round_trips ?? "—"}`], ["Hit rate", fmtPctPlain(m.hit_rate)], ["Profit factor", fmtRatio(m.profit_factor)], ["Avg round-trip P&L", fmtUsd(m.avg_trade_pnl)], ["Fee drag", fmtPctPlain(m.fee_drag, 2)], ["Slippage drag", fmtPctPlain(m.slippage_drag, 2)], ["VaR 95% (1 bar)", fmtPct(m.var_95_bar), "text-down"], ["CVaR 95% (1 bar)", fmtPct(m.cvar_95_bar), "text-down"], ["Underwater time", fmtPctPlain(m.underwater_bars_pct)], ["Skew / kurtosis", `${fmtRatio(m.skew)} / ${fmtRatio(m.kurtosis)}`], ["Bars / years", `${m.bars ?? "—"} / ${fmtRatio(m.years)}`], ["Final equity", fmtUsd(m.final_equity)], ]; return (
{items.map(([k, v, cls]) => (
{k}
{v}
))}
); } export function EquityVsBenchmarks({ a, label }: { a: Artifacts; label: string }) { const series: LineSpec[] = [{ id: "strategy", label, color: "#4f8cff", width: 2, points: a.equity.map((p) => ({ ts: p.ts, value: p.equity })) }]; for (const [name, b] of Object.entries(a.benchmarks ?? {})) series.push({ id: name, label: name.replace(/_/g, " "), color: BENCH_COLORS[name] ?? "#888", width: 1, points: b.equity.map((p) => ({ ts: p.ts, value: p.equity })) }); return ( <>
{series.map((s) => {s.label})}
); } export function BenchmarkTable({ a, m }: { a: Artifacts; m: Metrics }) { const rows = [["strategy", m] as [string, Metrics], ...Object.entries(a.benchmarks ?? {}).map(([k, v]) => [k, v.metrics] as [string, Metrics])]; return ( {rows.map(([k, v]) => ( ))}
SeriesCAGRVolSharpeMax DDCalmarTurnoverFee drag
{k.replace(/_/g, " ")}{fmtPct(v.cagr)}{fmtPctPlain(v.volatility)}{fmtRatio(v.sharpe)}{fmtPct(v.max_drawdown)}{fmtRatio(v.calmar)}{fmtRatio(v.turnover_annual, 1)}×{fmtPctPlain(v.fee_drag, 2)}
); } export function Underwater({ a }: { a: Artifacts }) { return ; } export function RollingSharpe({ a }: { a: Artifacts }) { if (!a.rolling_sharpe?.length) return ; return ({ ts: p.ts, value: p.sharpe })) }]} height={180} />; } export function WalkForward({ wf }: { wf: Artifacts["walk_forward"] }) { if (!wf) return Enable it in the Strategy Lab to see out-of-sample folds.; if (wf.error) return {wf.error}; return ( <>
{wf.anchored ? "anchored" : "rolling"} train{wf.n_trials} grid pointsembargo {wf.embargo_bars ?? 0} bars {wf.stitched_oos && 0 ? "up" : "down"}>stitched OOS Sharpe {fmtRatio(wf.stitched_oos.sharpe)} · return {fmtPct(wf.stitched_oos.total_return)} · {wf.stitched_oos.bars} bars}
{wf.folds.map((f) => ( ))}
FoldTrainTest (OOS)Best params (IS)IS SharpeOOS SharpeOOS returnOOS max DD
{f.fold + 1}{fmtDate(f.train[0])} → {fmtDate(f.train[1])}{fmtDate(f.test[0])} → {fmtDate(f.test[1])}{JSON.stringify(f.best_params)}{fmtRatio(f.is_sharpe)}{fmtRatio(f.oos_sharpe)}{fmtPct(f.oos_return)}{fmtPct(f.oos_max_dd)}
); } export function SensitivityHeatmap({ s }: { s: Artifacts["sensitivity"] }) { if (!s) return Enable it in the Strategy Lab (two parameters × value lists).; const flat = s.z.flat().filter((v): v is number => v != null); const min = Math.min(...flat), max = Math.max(...flat); const color = (v: number | null) => { if (v == null) return "transparent"; const t = max === min ? 0.5 : (v - min) / (max - min); return v >= 0 ? `rgba(34,197,94,${0.15 + 0.7 * t})` : `rgba(239,68,68,${0.15 + 0.7 * (1 - t)})`; }; return (
{s.x.values.map((x) => )}{s.y.values.map((y, j) => ( {s.z[j].map((v, i) => )} ))}
{s.metric} by {s.x.name} (columns) × {s.y.name} (rows)
{s.y.name} \ {s.x.name}{String(x)}
{String(y)}{v == null ? "—" : v.toFixed(2)}
); } export function StressTable({ stress, base }: { stress: Artifacts["stress"]; base: Metrics }) { const rows = Object.entries(stress ?? {}); if (!rows.length) return ; return ( {rows.map(([k, v]) => )}
ScenarioSharpeΔ SharpeReturnMax DDFee drag
base{fmtRatio(base.sharpe)}—{fmtPct(base.total_return)}{fmtPct(base.max_drawdown)}{fmtPctPlain(base.fee_drag, 2)}
{k.replace(/_/g, " ")}{fmtRatio(v.sharpe)}{v.sharpe != null && base.sharpe != null ? fmtRatio(v.sharpe - base.sharpe) : "—"}{fmtPct(v.total_return)}{fmtPct(v.max_drawdown)}{v.fee_drag != null ? fmtPctPlain(v.fee_drag, 2) : "—"}
); } export function ShuffledTrades({ s }: { s: Artifacts["shuffled_trades"] }) { if (!s || !s.n) return ; return ; } export function TradeLedger({ trades, page, setPage, pageSize = 50 }: { trades: Artifacts["trades"]; page: number; setPage: (p: number) => void; pageSize?: number }) { if (!trades?.length) return The strategy never changed exposure enough to trade, or all orders were rejected.; const pages = Math.ceil(trades.length / pageSize); const slice = trades.slice(page * pageSize, (page + 1) * pageSize); return ( <> {slice.map((t, i) => ( ))}
TimeSideQtyFillRef (open)SlipNotionalFeeTargetNote
{fmtTs(t.ts)}{t.side}{fmtNum(t.qty, 6)}{fmtNum(t.price, 2)}{fmtNum(t.ref_price, 2)}{fmtBps(((t.price - t.ref_price) / t.ref_price) * 1e4 * (t.side === "buy" ? 1 : -1), 1)}{fmtUsd(t.notional)}{fmtUsd(t.fee)}{fmtPctPlain(t.strategy_target, 0)}{t.partial ? "partial" : ""}{t.reason !== "rebalance" ? ` ${t.reason}` : ""}
{pages > 1 &&
page {page + 1} / {pages}
} ); } export function Provenance({ run }: { run: Run }) { const p = run.provenance ?? {}; const w = p.window as [number, number] | undefined; return ( ); } export function RejectedOrders({ rejected }: { rejected: Artifacts["rejected"] }) { if (!rejected?.length) return

No orders were rejected by the risk gateway.

; return ( {rejected.map((r, i) => )}
TimeSideQtyReasons
{fmtTs(r.ts)}{r.side}{fmtNum(r.qty, 6)}{r.reasons.join("; ")}
); } export { Card };