"use client"; import { useState, useEffect, useCallback } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { ChevronDown, ChevronRight, TrendingDown, ArrowLeft } from "lucide-react"; import { StrategyCard } from "@/components/strategy-card"; import { EquityChart } from "@/components/equity-chart"; import { PositionsPanel } from "@/components/positions-panel"; import { OBIDetail } from "@/components/obi-detail"; import OrderBookDepthMap from "@/components/orderbook-depth-map"; import L2Terminal from "@/components/L2Terminal"; import { useLiveMetrics, usePaperMetrics, fetchHistorical, fetchBacktestDetail, recalcBacktest } from "@/lib/api"; import type { Strategy, BacktestSummary, BacktestFull, Trade, Position, Order } from "@/lib/types"; type Tab = "live" | "paper" | "historical"; const STRAT_COLORS = ["#22c55e","#3b82f6","#a855f7","#f59e0b","#ef4444","#06b6d4","#ec4899","#84cc16","#6366f1","#14b8a6","#f97316","#8b5cf6"]; export default function Dashboard() { const [tab, setTab] = useState("live"); const { data: liveData, connected: liveConn } = useLiveMetrics(); const { data: paperData } = usePaperMetrics(); const [historical, setHistorical] = useState>({}); const [detailOpen, setDetailOpen] = useState(false); const [l2TerminalOpen, setL2TerminalOpen] = useState(false); const [detailName, setDetailName] = useState(""); const [detailTab, setDetailTab] = useState("live"); const [filter, setFilter] = useState("ALL"); const [btFull, setBtFull] = useState(null); const [feeOn, setFeeOn] = useState(true); const [feeTier, setFeeTier] = useState(0); const [stakingTier, setStakingTier] = useState("none"); const [posOpen, setPosOpen] = useState(false); const [tickerFilter, setTickerFilter] = useState("ALL"); useEffect(() => { fetchHistorical().then(setHistorical); }, []); const strategies = tab === "live" ? liveData?.strategies ?? {} : tab === "paper" ? paperData?.strategies ?? {} : {}; const handleCardClick = useCallback(async (name: string, t: Tab) => { setDetailName(name); setDetailTab(t); setBtFull(null); setDetailOpen(true); if (t === "historical") { const ht = historical[name]; if (ht) { try { const full = await fetchBacktestDetail(ht.name); setBtFull(full); } catch { /* ignore */ } } } }, [historical]); const handleFeeRecalc = useCallback(async () => { if (!detailName || detailTab !== "historical") return; const ht = historical[detailName]; if (!ht) return; try { const full = await recalcBacktest(ht.name, feeTier, stakingTier); setBtFull(full); } catch { /* ignore */ } }, [detailName, detailTab, feeTier, stakingTier, historical]); const detailStrat = detailTab === "historical" ? null : (tab === "paper" ? paperData : liveData)?.strategies?.[detailName] ?? null; let detailEquity: { t: number; v: number }[] = []; let detailTrades: Trade[] = []; let detailPositions: Position[] = []; let detailOrders: Order[] = []; if (detailTab === "live" && liveData) { if (detailName) { detailEquity = (liveData.strategy_equity ?? {})[detailName] ?? liveData.equity_history ?? []; } detailTrades = (liveData.trades ?? []).filter((t) => t.strategy === detailName); detailPositions = (liveData.open_positions ?? []).filter((p) => p.strategy === detailName); detailOrders = liveData.open_orders ?? []; } else if (detailTab === "paper" && paperData) { if (detailName) { detailEquity = (paperData.strategy_equity ?? {})[detailName] ?? paperData.equity_history ?? []; } detailTrades = (paperData.per_strategy_trades ?? {})[detailName] ?? []; detailPositions = (paperData.open_positions ?? []).filter((p) => p.strategy === detailName); detailOrders = paperData.open_orders ?? []; } else if (detailTab === "historical" && btFull) { detailEquity = (btFull.equity_curve ?? []).map((e) => ({ t: typeof e.t === "string" ? Math.floor(new Date(e.t).getTime() / 1000) : e.t, v: e.v, })); detailTrades = btFull.trades ?? []; } if (detailOpen) { return (

{detailName}

{detailStrat && ( <> {detailStrat.type} {detailStrat.status?.toUpperCase()} {detailStrat.instrument} )} {detailTab === "historical" && btFull && ( 30d · {btFull.total_trades} trades · {btFull.fee_model ?? "taker"} model )}
{detailTab === "historical" && (
)}
{/* OBI Strategy: 3D Depth Map View */} {detailTab === "live" && detailName.includes("Order Book Imbalance") && detailStrat && liveData && ( )} {/* Regular detail for non-OBI strategies */} {!(detailTab === "live" && detailName.includes("Order Book Imbalance")) && ( <> {detailStrat && (

{detailStrat.description || "No description available."}

)} {detailTab === "historical" && btFull && (

{btFull.strategy} — {btFull.num_periods} periods, {btFull.total_trades} trades, total fees ${btFull.fees_total?.toFixed(2)}, model: {btFull.fee_model ?? "taker"}

)}
{detailStrat ? ( [ { l: "PnL", v: `$${detailStrat.pnl?.toFixed(4)}` }, { l: "PnL%", v: `${detailStrat.pnl_pct >= 0 ? "+" : ""}${detailStrat.pnl_pct?.toFixed(2)}%`, up: detailStrat.pnl_pct >= 0 }, { l: "Trades", v: String(detailStrat.trades_today ?? 0) }, { l: "Win Rate", v: `${Math.round((detailStrat.win_rate ?? 0) * 100)}%` }, { l: "Fees", v: `$${(detailStrat.fee_paid ?? 0).toFixed(4)}`, up: false }, { l: "Position", v: (detailStrat.position ?? 0).toFixed(4) }, ].map(({ l, v, up }) => (

{l}

{v}

)) ) : detailTab === "historical" && btFull ? ( [ { l: feeOn ? "Net PnL" : "Gross PnL", v: `${(feeOn ? (btFull.pnl_net_pct ?? btFull.pnl_pct ?? 0) : (btFull.pnl_gross_pct ?? btFull.pnl_pct ?? 0)) >= 0 ? "+" : ""}${(feeOn ? (btFull.pnl_net_pct ?? btFull.pnl_pct ?? 0) : (btFull.pnl_gross_pct ?? btFull.pnl_pct ?? 0)).toFixed(2)}%`, up: (feeOn ? (btFull.pnl_net_pct ?? btFull.pnl_pct ?? 0) : (btFull.pnl_gross_pct ?? btFull.pnl_pct ?? 0)) >= 0 }, { l: "Sharpe", v: (btFull.sharpe ?? 0).toFixed(2) }, { l: "Sortino", v: (btFull.sortino ?? 0).toFixed(2) }, { l: "Max DD", v: `${((btFull.max_dd ?? 0) * 100).toFixed(1)}%`, up: false }, { l: "Win Rate", v: `${Math.round((btFull.win_rate ?? 0) * 100)}%` }, { l: "Fees", v: `$${(btFull.fees_total ?? 0).toFixed(2)}`, up: false }, ].map(({ l, v, up }) => (

{l}

{v}

)) ) : (
Loading...
)}
{detailEquity.length > 0 && (
)} {detailTab !== "historical" && (detailPositions.length > 0 || detailOrders.length > 0) && (

Open Positions & Orders {detailName ? `for ${detailName}` : ""}

)}

Trade History {detailTrades.length > 0 ? `(${detailTrades.length})` : ""}

{detailTrades.length > 0 ? (
Time Side Size Price PnL Fee Reason {detailTrades.slice(-200).reverse().map((t, i) => { const tp = detailTab === "historical" ? (feeOn ? (t.pnl_net ?? t.pnl ?? 0) : (t.pnl_gross ?? t.pnl ?? 0)) : (t.pnl ?? 0); return ( {(t.time ?? "").substring(0, 16)} = 0 ? "bg-green-500/10 text-green-500" : "bg-red-500/10 text-red-500"}`}> {t.side ?? "—"} {t.size} ${(t.price ?? 0).toFixed(1)} = 0 ? "text-green-500" : "text-red-500"}`}> {tp >= 0 ? "+" : ""}${Math.abs(tp).toFixed(4)} ${(t.fee ?? 0).toFixed(4)} {t.reason ?? "—"} ); })}
) : (

No trades recorded yet

)}
{/* Live L2 Order Book + Trade Tape (all strategies, live tab only) */} {detailTab === "live" && (
)}
)}
); } return (

FTDT Quant Lab

{tab === "live" ? `Live Testnet · Equity $${liveData?.total_equity?.toFixed(2) ?? "—"}` : tab === "paper" ? `Paper Mainnet · Equity $${paperData?.total_equity?.toLocaleString() ?? "—"}` : "Historical · Mainnet Real Data"}

{liveConn ? "LIVE" : "OFFLINE"}
setTab(v as Tab)} className="max-w-[1440px] mx-auto px-6"> LiveTestnet Paper$100K Mainnet HistoricalReal Data
{/* Ticker filter for Historical tab */} {tab === "historical" && (
Ticker: {["ALL", "BTC", "ETH", "HYPE", "VVV"].map((t) => ( ))}
)}
{Object.entries(strategies).map(([name, s], i) => ( handleCardClick(name, tab)} /> ))} {tab === "historical" && Object.entries(historical).filter(([, b]) => tickerFilter === "ALL" || b.coin === tickerFilter).map(([name, b], i) => ( handleCardClick(name, "historical")} 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" /> ))}
{/* L2 Terminal launcher */}
{/* Fullscreen L2 Terminal */} {l2TerminalOpen && (
)}
); }