8.2 KiB
DLOB + L1…L10 — podstawy (co jest czym i gdzie to liczymy)
Ten dokument wyjaśnia pojęcia:
- DLOB (Drift Limit Order Book),
- L1 / L2 / L3 oraz potoczne L1…L10,
- na jakich warstwach w naszym stacku powstają dane i metryki,
- gdzie “pracuje AI” (modele/strategie) vs gdzie jest execution (order placement).
Co to jest DLOB
DLOB = Decentralized Limit Order Book w Drift.
W praktyce: to jest księga zleceń dla rynku (np. SOL-PERP):
- bids = zlecenia kupna (po stronie bid),
- asks = zlecenia sprzedaży (po stronie ask).
Księga ma wiele “poziomów” cenowych; przy każdej cenie stoi pewna ilość (size).
L1 / L2 / L3 (format i sens)
L1 (Top of Book)
L1 to skrót od “top of book”:
- best bid = najwyższa cena kupna (pierwszy poziom po stronie bid),
- best ask = najniższa cena sprzedaży (pierwszy poziom po stronie ask).
Z L1 najczęściej liczysz:
- spread =
best_ask - best_bid, - mid =
(best_bid + best_ask) / 2.
L2 (zagregowane poziomy)
L2 to lista poziomów (levels) po obu stronach:
bids: [{ price, size }, ...](zwykle posortowane malejąco poprice)asks: [{ price, size }, ...](zwykle posortowane rosnąco poprice)
To jest najpopularniejszy “orderbook UI”: słupki/heat per poziom ceny.
L3 (pojedyncze zlecenia)
L3 to “niezagregowane” dane: pojedyncze zlecenia (większy wolumen danych). U nas pod UI i metryki zazwyczaj wystarcza L2.
L1…L10 (co to znaczy w praktyce)
L1…L10 to potoczne określenie:
“pierwsze 10 poziomów z L2 najbliżej top of book”.
To nie jest osobny format; to po prostu wycinek L2.
W naszym stacku “ile leveli bierzemy” kontroluje:
DLOB_DEPTH(np. 10 → “L1…L10”).
Jak to działa w naszym stacku (warstwy)
Poniżej “łańcuch” od źródła do metryk:
Warstwa A: On-chain → DLOB w pamięci (VPS/k3s)
Komponent: dlob-publisher.
- Łączy się do Solany przez
ENDPOINT(HTTP RPC) iWS_ENDPOINT(WebSocket). - Subskrybuje konta/zdarzenia i buduje DLOB (orderbook) w pamięci.
- Publikuje snapshoty do Redis (u nas:
dlob-redis).
To jest najbliżej źródła i zwykle najbardziej “real-time”.
Warstwa B: Cache + REST API (VPS/k3s)
Komponenty: dlob-redis + dlob-server.
dlob-redistrzyma snapshoty/publish.dlob-serverudostępnia HTTP:GET /l2?marketName=SOL-PERP&depth=10→ L2 (bids/asks + best bid/ask itp.)GET /l3?...→ L3 (jeśli potrzebujesz)
To jest warstwa dystrybucji danych “w klastrze”, żeby inne serwisy nie musiały gadać bezpośrednio z Solaną.
Uwaga o rynkach:
dlob-publisherładuje rynki wgPERP_MARKETS_TO_LOAD(indeksy) /SPOT_MARKETS_TO_LOAD.- Jeśli rynek nie jest załadowany przez publisher,
dlob-servernie rozpoznamarketName.
Warstwa C: Metryki w DB/Hasura (VPS/k3s)
Komponenty: dlob-worker, dlob-depth-worker, dlob-slippage-worker.
To są “workery pod UI/AI”, które liczą metryki i zapisują je do Postgresa (Hasura).
dlob-worker (collector + basic stats)
Wejście:
- odpytuje
dlob-serverpo HTTP/l2(źródło L2), - rynki:
DLOB_MARKETS, - głębokość (ile leveli):
DLOB_DEPTH, - częstotliwość:
DLOB_POLL_MS.
Wyjście (upsert do DB):
dlob_l2_latest= snapshot L2 “latest” per market,dlob_stats_latest= pochodne metryki liczone z top‑N leveli (N=DLOB_DEPTH), m.in.:mid_price,spread_abs,spread_bps,depth_bid_*/depth_ask_*,imbalance.
Czyli: jeśli pytasz “gdzie liczymy L1…L10 metryki” → tutaj (w dlob-worker), bo bierze top‑N leveli z L2.
dlob-depth-worker (depth w bandach bps)
Wejście:
- czyta z DB
dlob_l2_latest(czyli już “przetworzone” L2).
Wyjście:
dlob_depth_bps_latest= płynność w pasmach wokół mid (np. ±5/10/20/50/100/200 bps).
To nie jest “L1…L10”, tylko “ile płynności mieści się w oknie cenowym” wokół mid.
dlob-slippage-worker (slippage vs size)
Wejście:
- czyta z DB
dlob_l2_latest.
Wyjście:
dlob_slippage_latest= symulacja wykonania zlecenia (market) po L2 dla progówDLOB_SLIPPAGE_SIZES_USD.
To jest bardzo użyteczne jako feature do strategii (“ile kosztuje wejście/wyjście teraz dla X USD”).
Gdzie “pracuje AI” (TFT itp.)
AI/strategia powinna pracować na warstwie “features”, a nie na surowych subskrypcjach Solany:
Najczęstszy zestaw wejść dla modelu:
- candles/ticki (np.
drift_ticks+get_drift_candles(...)), - bieżące statsy z DLOB:
dlob_stats_latest(mid/spread/depth/imbalance),dlob_depth_bps_latest(depth w bandach),dlob_slippage_latest(slippage vs size),
- opcjonalnie pełny snapshot L2 (z
dlob_l2_latest), jeśli model potrzebuje “kształtu” książki.
Kluczowa zasada bezpieczeństwa:
- Model (np. na Vast) może sugerować “desired state” (wejść/wyjść/parametry),
- Executor na VPS zawsze odpowiada za:
- risk checks,
- składanie/cancel/close,
- klucze prywatne i podpisywanie transakcji,
- kill switch.
Szybki słownik (1-liner)
- bid: kupno, zielona strona książki
- ask: sprzedaż, czerwona strona książki
- best bid / best ask (L1): top-of-book
- spread: koszt “wejścia/wyjścia natychmiast” (ask-bid)
- mid: punkt odniesienia między bid/ask
- L2: lista poziomów
{price,size} - L1…L10: top 10 poziomów z L2 (u nas kontrolowane przez
DLOB_DEPTH)
Jak liczymy “liquidity” i “kasa” (USD) w metrykach
W UI/DB słowo “liquidity” zwykle oznacza depth: “ile wolumenu stoi w orderbooku blisko ceny”. U nas trzymamy to rozdzielnie dla bid/ask oraz w dwóch wariantach:
A) Top‑N leveli (np. L1…L10) — dlob_stats_latest
Liczone w dlob-worker na podstawie L2 z /l2:
- Bierzemy pierwsze
N = DLOB_DEPTHleveli zbidsiasks. - Każdy level ma:
price = price_int / PRICE_PRECISIONsize_base = size_int / BASE_PRECISION- “kasa” (notional) na tym levelu:
size_usd = size_base * price
- Sumujemy po levelach:
depth_bid_base = Σ size_base(po stronie bid),depth_bid_usd = Σ (size_base * price)(po stronie bid),- analogicznie
depth_ask_base,depth_ask_usd(po stronie ask).
To odpowiada intuicji “ile jest płynności na L1…LN”.
B) Okno cenowe w bps od mid — dlob_depth_bps_latest
Liczone w dlob-depth-worker na podstawie dlob_l2_latest:
- Dla pasma
band_bpswyznaczamy:minBidPrice = mid * (1 - band_bps/10_000)maxAskPrice = mid * (1 + band_bps/10_000)
- Sumujemy wszystkie levele, które mieszczą się w tym oknie:
- bids:
price >= minBidPrice - asks:
price <= maxAskPrice
- bids:
- Liczymy sumy:
bid_base,bid_usd,ask_base,ask_usdtak jak wyżej (usd = base * price).
To odpowiada intuicji “ile płynności jest blisko ceny w ±X bps”.
Ważne doprecyzowanie
Te liczby to notional z orderbooka (ile “stoi” na poziomach cenowych). Nie są to “pieniądze w kontrakcie”, tylko przybliżenie kosztu/pojemności wykonania przy danej cenie i bez przesunięcia rynku.
Spec: Orderbook UI (L1…L10 + “liquidity bars”)
Wizualizacja orderbooka (jak na screenach) jest oparta o L2 i pokazuje tylko top‑N leveli:
N= liczba leveli wyświetlanych na stronę (np. 10 → “L1…L10”).
Kolumny / wartości
Na każdym levelu liczymy:
size_usd = size_base * price
W UI pokazujemy:
Size (USD)=size_usddla danego poziomu,Total (USD)= suma skumulowana od best‑price “w głąb” (cumulative):- bids: kumulacja od best bid w dół,
- asks: kumulacja od best ask w górę (w UI zwykle best ask jest bliżej środka).
“Liquidity bars” (znormalizowane słupki tła)
Żeby “na oko” widzieć gdzie stoi płynność:
- Level bar (per‑poziom) — normalizacja do największego
size_usdw widocznych levelach danej strony:level_scale = size_usd / max(size_usd w widoku)
- Total bar (cumulative) — normalizacja do największego
total_usdw widocznych levelach danej strony:total_scale = total_usd / max(total_usd w widoku)
Żeby duże “ściany” nie zabijały kontrastu, warto użyć krzywej:
scale_curved = sqrt(clamp01(scale))
Interpretacja:
- level bar = “ile stoi na tym poziomie”,
- total bar = “ile stoi łącznie do tego poziomu”.