feat(visualizer): add layers + fast timeframe switching

This commit is contained in:
u1
2026-02-01 21:17:28 +01:00
parent fc92392705
commit 89415f6793
17 changed files with 2758 additions and 127 deletions

View File

@@ -3,8 +3,10 @@ import { subscribeGraphqlWs } from '../../lib/graphqlWs';
export type OrderbookRow = {
price: number;
size: number;
total: number;
sizeBase: number;
sizeUsd: number;
totalBase: number;
totalUsd: number;
};
export type DlobL2 = {
@@ -66,11 +68,22 @@ function parseLevels(raw: unknown, pricePrecision: number, basePrecision: number
return out;
}
function withTotals(levels: Array<{ price: number; size: number }>): OrderbookRow[] {
let total = 0;
function withTotals(levels: Array<{ price: number; sizeBase: number }>): OrderbookRow[] {
let totalBase = 0;
let totalUsd = 0;
return levels.map((l) => {
total += l.size;
return { ...l, total };
const sizeUsd = l.sizeBase * l.price;
totalBase += l.sizeBase;
totalUsd += sizeUsd;
return {
price: l.price,
sizeBase: l.sizeBase,
sizeUsd,
totalBase,
totalUsd,
};
});
}
@@ -129,14 +142,25 @@ export function useDlobL2(
const row = data?.dlob_l2_latest?.[0];
if (!row?.market_name) return;
const bidsRaw = parseLevels(row.bids, pricePrecision, basePrecision).slice(0, levels);
const asksRaw = parseLevels(row.asks, pricePrecision, basePrecision).slice(0, levels);
const bidsSorted = parseLevels(row.bids, pricePrecision, basePrecision)
.slice()
.sort((a, b) => b.price - a.price)
.slice(0, levels)
.map((l) => ({ price: l.price, sizeBase: l.size }));
const bids = withTotals(bidsRaw);
const asks = withTotals(asksRaw).slice().reverse();
const asksSorted = parseLevels(row.asks, pricePrecision, basePrecision)
.slice()
.sort((a, b) => a.price - b.price)
.slice(0, levels)
.map((l) => ({ price: l.price, sizeBase: l.size }));
const bestBid = bidsRaw.length ? bidsRaw[0].price : null;
const bestAsk = asksRaw.length ? asksRaw[0].price : null;
// We compute totals from best -> worse.
// For UI we display asks with best ask closest to mid (at the bottom), so we reverse.
const bids = withTotals(bidsSorted);
const asks = withTotals(asksSorted).slice().reverse();
const bestBid = bidsSorted.length ? bidsSorted[0].price : null;
const bestAsk = asksSorted.length ? asksSorted[0].price : null;
const mid = bestBid != null && bestAsk != null ? (bestBid + bestAsk) / 2 : null;
setL2({