diff --git a/dashboard-next/src/app/page.tsx b/dashboard-next/src/app/page.tsx index 43145a2..9a44c5b 100644 --- a/dashboard-next/src/app/page.tsx +++ b/dashboard-next/src/app/page.tsx @@ -32,6 +32,7 @@ export default function Dashboard() { const [feeTier, setFeeTier] = useState(0); const [stakingTier, setStakingTier] = useState("none"); const [posOpen, setPosOpen] = useState(false); + const [tickerFilter, setTickerFilter] = useState("ALL"); useEffect(() => { fetchHistorical().then(setHistorical); }, []); @@ -301,6 +302,18 @@ export default function Dashboard() {
+ {/* Ticker filter for Historical tab */} + {tab === "historical" && ( +
+ Ticker: + {["ALL", "BTC", "ETH", "HYPE", "VVV"].map((t) => ( + + ))} +
+ )}
{Object.entries(strategies).map(([name, s], i) => ( @@ -309,10 +322,11 @@ export default function Dashboard() { ))} - {tab === "historical" && Object.entries(historical).map(([name, b], i) => ( + {tab === "historical" && Object.entries(historical).filter(([, b]) => tickerFilter === "ALL" || b.coin === tickerFilter).map(([name, b], i) => ( handleCardClick(name, "historical")} - badge={`30d · ${b.coin ?? "BTC"} · Mainnet`} + coin={String(b.coin ?? "?")} + badge={`30d · Mainnet`} stats={[{ label: "Sharpe", value: b.sharpe.toFixed(2) }, { label: "Max DD", value: `${(b.max_dd * 100).toFixed(1)}%`, negative: true }, { label: "Win", value: `${Math.round(b.win_rate * 100)}%` }]} pnlPct={b.pnl_pct} status="REAL DATA" /> diff --git a/dashboard-next/src/components/strategy-card.tsx b/dashboard-next/src/components/strategy-card.tsx index 30f8119..5fca463 100644 --- a/dashboard-next/src/components/strategy-card.tsx +++ b/dashboard-next/src/components/strategy-card.tsx @@ -11,12 +11,13 @@ interface StrategyCardProps { tab: "live" | "paper" | "backtest" | "historical"; onClick: () => void; badge?: string; + coin?: string; stats?: { label: string; value: string; negative?: boolean }[]; pnlPct?: number; status?: string; } -export function StrategyCard({ name, strategy, tab, onClick, badge, stats, pnlPct, status }: StrategyCardProps) { +export function StrategyCard({ name, strategy, tab, onClick, badge, stats, pnlPct, status, coin }: StrategyCardProps) { if (strategy) { const equity = strategy.allocation + (strategy.pnl ?? 0); const isUp = equity >= strategy.allocation; @@ -76,6 +77,7 @@ export function StrategyCard({ name, strategy, tab, onClick, badge, stats, pnlPc

{badge ?? "Backtest"}

{status ?? "BACKTEST"} + {coin && {coin}}
= 0 ? "text-green-500" : "text-red-500"}`}> {(pnlPct ?? 0) >= 0 ? : } diff --git a/dashboard-next/src/lib/api.ts b/dashboard-next/src/lib/api.ts index ecc8475..1665137 100644 --- a/dashboard-next/src/lib/api.ts +++ b/dashboard-next/src/lib/api.ts @@ -82,7 +82,8 @@ export async function fetchHistorical(): Promise = {}; for (const b of list) { - if (!byStrat[b.strategy]) byStrat[b.strategy] = b; + const key = `${b.strategy} · ${b.coin ?? "?"}`; + if (!byStrat[key]) byStrat[key] = b; } return byStrat; } diff --git a/dashboard-next/src/lib/types.ts b/dashboard-next/src/lib/types.ts index 29be13a..a83d625 100644 --- a/dashboard-next/src/lib/types.ts +++ b/dashboard-next/src/lib/types.ts @@ -93,7 +93,7 @@ export interface BacktestSummary { max_dd: number; win_rate: number; total_trades: number; - coin?: string; + coin: string; } export interface BacktestFull {