3D Order Book Depth Map: Plotly.js + Three.js live visualization

Architecture:
- depth-map-utils.ts: L2RingBuffer, l2SnapshotsToSurface, computeImbalance
  └─ O(1) ring buffer, 60-snapshot capacity
  └─ Surface matrix: ±50 bps × 100 resolution
  └─ Imbalance formula: I = (V_b-V_a)/(V_b+V_a) with wall detection

- depth-map-plotly.tsx: Plotly.js 3D Surface
  └─ 7-stop warm colorscale (dark→amber→gold)
  └─ contour projection, ambient+diffuse lighting
  └─ Live imbalance overlay: gauge bar + formula
  └─ uirevision for stable camera on updates

- depth-map-three.tsx: Three.js high-perf alternative
  └─ BufferGeometry + vertex colors + OrbitControls
  └─ 60fps suitable, WebGL renderer with alpha
  └─ Warm gradient matching Plotly colorscale
  └─ Double-sided faces, dark grid helper

- obi-detail.tsx: Combined strategy detail panel
  └─ Engine toggle: Plotly.js ↔ Three.js
  └─ Synthetic data generation for testing
  └─ 6-stat metrics row (PnL, BTC B&H, Sharpe, Hit Rate, Max DD, Signal)
  └─ Equity curve comparison + trade history table

- Page integration: OBI strategy triggers dedicated 3D view
This commit is contained in:
ramseshk
2026-08-05 06:11:33 +00:00
parent 156ea40e78
commit 8855c013a6
5 changed files with 934 additions and 0 deletions
+18
View File
@@ -11,6 +11,7 @@ import { ChevronDown, ChevronRight, Activity, Database, TrendingUp, TrendingDown
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 { useLiveMetrics, usePaperMetrics, fetchHistorical, fetchBacktestDetail, recalcBacktest } from "@/lib/api";
import type { Strategy, BacktestSummary, BacktestFull, Trade, Position, Order } from "@/lib/types";
@@ -147,6 +148,21 @@ export default function Dashboard() {
</header>
<div className="max-w-[1440px] mx-auto px-6 py-6 space-y-6">
{/* OBI Strategy: 3D Depth Map View */}
{detailTab === "live" && detailName.includes("Order Book Imbalance") && detailStrat && liveData && (
<OBIDetail
strategy={detailStrat}
strategyName={detailName}
equityData={detailEquity}
trades={detailTrades}
liveData={liveData}
color={STRAT_COLORS[Object.keys(strategies).indexOf(detailName) % STRAT_COLORS.length] ?? "#22c55e"}
/>
)}
{/* Regular detail for non-OBI strategies */}
{!(detailTab === "live" && detailName.includes("Order Book Imbalance")) && (
<>
{detailStrat && (
<p className="text-xs text-muted-foreground leading-relaxed p-4 bg-muted/50 rounded-lg border border-border">
{detailStrat.description || "No description available."}
@@ -259,6 +275,8 @@ export default function Dashboard() {
)}
</div>
<div className="h-8" />
</>
)}
</div>
</div>
);