feat(visualizer): add layers + fast timeframe switching
This commit is contained in:
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user