Files
trade-frontend/doc/dlob-services.md
2026-01-11 10:37:23 +00:00

8.4 KiB
Raw Blame History

Serwisy DLOB na VPS (k3s / trade-staging)

Ten dokument opisuje rolę serwisów “DLOB” uruchomionych w namespace trade-staging oraz ich przepływ danych.

Czy dlob-worker pracuje na VPS?

Tak — wszystkie serwisy wymienione niżej działają na VPS jako Deploymenty w klastrze k3s, w namespace trade-staging.

Czy na VPS jest GraphQL/WS dla stats i orderbook?

Tak — GraphQL wystawia Hasura (na VPS w k3s), a nie dlob-server.

  • Dane L2 i liczone statsy są zapisane do Postgresa jako tabele dlob_*_latest i są dostępne przez Hasurę jako GraphQL (query + subscriptions).
  • Z zewnątrz korzystamy przez frontend (proxy) pod:
    • HTTP: https://trade.rv32i.pl/graphql
    • WS: wss://trade.rv32i.pl/graphql (subskrypcje, protokół graphql-ws)

dlob-server wystawia REST (np. /l2, /l3) w klastrze; to jest źródło danych dla workerów albo do debugowania.

TL;DR: kto co robi

dlob-worker

  • Rola: kolektor L2 + wyliczenie “basic stats”.
  • Wejście: HTTP L2 z DLOB_HTTP_URL (u nas obecnie https://dlob.drift.trade, ale można przełączyć na http://dlob-server:6969).
  • Wyjście: upsert do Hasury (Postgres) tabel:
    • dlob_l2_latest (raw snapshot L2, JSON leveli)
    • dlob_stats_latest (pochodne: best bid/ask, mid, spread, depth, imbalance, itp.)
  • Częstotliwość: DLOB_POLL_MS (u nas 500 ms).

dlob-slippage-worker

  • Rola: symulacja slippage vs rozmiar zlecenia na podstawie L2.
  • Wejście: czyta z Hasury dlob_l2_latest (dla listy rynków).
  • Wyjście: upsert do Hasury tabeli dlob_slippage_latest (m.in. impact_bps, vwap_price, worst_price, fill_pct).
  • Częstotliwość: DLOB_POLL_MS (u nas 1000 ms); rozmiary w DLOB_SLIPPAGE_SIZES_USD.

dlob-depth-worker

  • Rola: metryki “głębokości” w pasmach ±bps wokół mid.
  • Wejście: czyta z Hasury dlob_l2_latest.
  • Wyjście: upsert do Hasury tabeli dlob_depth_bps_latest (per (market_name, band_bps)).
  • Częstotliwość: DLOB_POLL_MS (u nas 1000 ms); pasma w DLOB_DEPTH_BPS_BANDS.

dlob-publisher

  • Rola: utrzymuje “żywy” DLOB na podstawie subskrypcji on-chain i publikuje snapshoty do Redis.
  • Wejście: Solana RPC/WS (ENDPOINT, WS_ENDPOINT z secreta trade-dlob-rpc), Drift SDK; konfiguracja rynków np. PERP_MARKETS_TO_LOAD.
  • Wyjście: zapis/publish do dlob-redis (cache / pubsub / streamy), z którego korzysta serwer HTTP (i ewentualnie WS manager).

dlob-server

  • Rola: HTTP API do danych DLOB (np. /l2, /l3) serwowane z cache Redis.
  • Wejście: dlob-redis + slot subscriber (do oceny “świeżości” danych).
  • Wyjście: endpoint HTTP w klastrze (Service dlob-server:6969), który może być źródłem dla dlob-worker (gdy DLOB_HTTP_URL=http://dlob-server:6969).

dlob-redis

  • Rola: Redis (u nas single-node “cluster mode”) jako cache i kanał komunikacji między dlob-publisher a dlob-server.
  • Uwagi: to “klej” między komponentami publish/serve; bez niego publisher i server nie współpracują.

Jak to się spina (przepływ danych)

  1. dlob-publisher (on-chain) → publikuje snapshoty do dlob-redis.
  2. dlob-server → serwuje /l2 i /l3 z dlob-redis (HTTP w klastrze).
  3. dlob-worker → pobiera L2 (obecnie z https://dlob.drift.trade; opcjonalnie z dlob-server) i zapisuje “latest” do Hasury/DB.
  4. dlob-slippage-worker + dlob-depth-worker → liczą agregaty z dlob_l2_latest i zapisują do Hasury/DB (pod UI).

Co to jest L1 / L2 / L3 (orderbook)

  • L1 (top-of-book): tylko najlepszy bid i najlepszy ask (czasem też spread).
  • L2 (Level 2): zagregowane poziomy cenowe po stronie bid/ask — lista leveli { price, size }, gdzie size to suma wolumenu na danej cenie (to jest typowy “orderbook UI” i baza pod spread/depth/imbalance).
  • L3 (Level 3): niezagregowane, pojedyncze zlecenia (każde osobno, zwykle z dodatkowymi polami/identyfikatorami). Większy wolumen danych; przydatne do “pro” analiz i debugowania mikrostruktury.

W tym stacku:

  • dlob-server udostępnia REST endpointy /l2 i /l3.
  • Hasura/DB trzyma “latest” snapshot L2 w dlob_l2_latest oraz metryki w dlob_stats_latest / dlob_depth_bps_latest / dlob_slippage_latest.

Słownik pojęć (bid/ask/spread i metryki)

Podstawy orderbooka

  • Bid: zlecenia kupna (chęć kupna). W orderbooku “bid side”.
  • Ask: zlecenia sprzedaży (chęć sprzedaży). W orderbooku “ask side”.
  • Best bid / best ask: najlepsza (najwyższa) cena kupna i najlepsza (najniższa) cena sprzedaży na topie księgi (L1).
  • Spread: różnica pomiędzy best_ask a best_bid. Im mniejszy spread, tym “taniej” wejść/wyjść (mniej kosztów natychmiastowej realizacji).
  • Mid price: cena “po środku”: (best_bid + best_ask) / 2. Używana jako punkt odniesienia do bps i slippage.
  • Level: pojedynczy poziom cenowy w L2 (np. price=100.00, size=12.3).
  • Size: ilość/płynność na poziomie (zwykle w jednostkach “base asset”).
  • Base / Quote:
    • base = instrument bazowy (np. SOL),
    • quote = waluta wyceny (często USD).

Kolory w UI (visualizer)

  • bid / “buy side” = zielony (.pos, #22c55e)
  • ask / “sell side” = czerwony (.neg, #ef4444)
  • “flat” / brak zmiany = niebieski (#60a5fa) — używany m.in. w “brick stack” pod świecami

Jednostki i skróty

  • bps (basis points): 1 bps = 0.01% = 0.0001. Np. 25 bps = 0.25%.
  • USD: u nas wiele wartości jest przeliczanych do USD (np. size_base * price).

Metryki “stats” (np. dlob_stats_latest)

  • spread_abs (USD): best_ask - best_bid.
  • spread_bps (bps): (spread_abs / mid_price) * 10_000.
  • depth_levels: ile leveli (topN) z każdej strony braliśmy do liczenia “depth”.
  • depth_bid_base / depth_ask_base: suma size po topN levelach bid/ask (w base).
  • depth_bid_usd / depth_ask_usd: suma size_base * price po topN levelach (w USD).
  • imbalance ([-1..1]): miara asymetrii płynności:
    • (depth_bid_usd - depth_ask_usd) / (depth_bid_usd + depth_ask_usd)
    • 0 = relatywnie więcej płynności po bid, <0 = po ask.

  • oracle_price: cena z oracla (np. Pyth) jako punkt odniesienia.
  • mark_price: “mark” z rynku/perp (cena referencyjna dla rozliczeń); różni się od oracle/top-of-book.

Metryki “depth bands” (np. dlob_depth_bps_latest)

  • band_bps: szerokość pasma wokół mid_price (np. 5/10/20/50/100/200 bps).
  • bid_usd / ask_usd: płynność po danej stronie, ale tylko z poziomów mieszczących się w oknie ±band_bps wokół mid.
  • imbalance: jak wyżej, ale liczony per band.

Metryki “slippage” (np. dlob_slippage_latest)

To jest symulacja “gdybym teraz zrobił market order o rozmiarze X” na podstawie L2.

  • size_usd: docelowy rozmiar zlecenia w USD.
  • vwap_price: średnia cena realizacji (Volume Weighted Average Price) dla symulowanego fill.
  • impact_bps: koszt/odchylenie względem mid_price wyrażone w bps (zwykle na bazie vwap vs mid).
  • worst_price: najgorsza cena dotknięta podczas “zjadania” kolejnych leveli.
  • filled_usd / filled_base: ile realnie udało się wypełnić (może być < docelowego, jeśli brakuje płynności).
  • fill_pct: procent wypełnienia (100% = pełny fill).
  • levels_consumed: ile leveli zostało “zjedzonych” podczas fill.

Metadane czasu (“świeżość”)

  • ts: timestamp źródła (czas snapshotu).
  • slot: slot Solany, z którego pochodzi snapshot (monotoniczny “numer czasu” chaina).
  • updated_at: kiedy nasz worker zapisał/odświeżył rekord w DB (do oceny, czy dane są świeże).

Szybka diagnostyka na VPS

KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n trade-staging get deploy | grep -E 'dlob-(worker|slippage-worker|depth-worker|publisher|server|redis)'
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n trade-staging logs deploy/dlob-worker --tail=80
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n trade-staging logs deploy/dlob-publisher --tail=80
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n trade-staging logs deploy/dlob-server --tail=80

Ważna uwaga (źródło L2 w dlob-worker)

Jeśli chcesz, żeby dlob-worker polegał na naszym stacku (własny RPC + dlob-publisher + dlob-server), ustaw:

  • DLOB_HTTP_URL=http://dlob-server:6969

Aktualnie w trade-staging jest ustawione:

  • DLOB_HTTP_URL=https://dlob.drift.trade