Files
trade-doc/bot-strategy-reversal.md

143 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Strategia bota: “Reversal (sekundy → minuty)” — metryki i parametry
Cel: podejmować decyzje w **sekundach**, wejść w pozycję na **minuty** tylko gdy mikrostruktura (orderbook) sprzyja, a następnie zarządzać pozycją w prosty i kontrolowalny sposób.
Ten dokument jest propozycją “MVP strategii” i listą parametrów, nad którymi będziemy iterować.
## Dane wejściowe (features) — co już mamy
### Trend/impuls (krótki horyzont)
Źródło: ticki/candles z `drift_ticks` (np. przez `get_drift_candles(...)`).
Przykładowe serie:
- `px_1s` / `px_5s`: zamknięcia z krótkich świec,
- `mom_3s`, `mom_10s`, `mom_30s`: momentum/ROC,
- `vol_30s`: zmienność krótkoterminowa.
### Mikrostruktura (koszt wejścia i “czy da się wejść”)
Źródło: DLOB workery → Hasura/DB:
- `dlob_stats_latest`: `mid_price`, `spread_bps`, `depth_bid_usd`, `depth_ask_usd`, `imbalance`
- `dlob_depth_bps_latest`: `bid_usd/ask_usd` w pasmach ±bps (np. 10/20/50)
- `dlob_slippage_latest`: `impact_bps` dla progów `size_usd` (np. 100/500/1000/…)
Ważne: “liquidity” i “kasa” (USD notional) liczymy z L2 jako sumy `size_base * price` (opis w `doc/dlob-basics.md`).
## Architektura decyzji (loop)
Strategia jest podzielona na 2 pętle:
1) **Detektor warunków (sekundy)**:
- wykrywa potencjalny reversal,
- sprawdza bramki mikrostruktury (gates),
- ustala “desired exposure” (np. +K USD, -K USD, albo 0).
2) **Zarządzanie pozycją (minuty)**:
- utrzymuje pozycję do warunku wyjścia (czas/SL/TP/degradacja warunków),
- dba o order management (limit/chase) i idempotencję.
## Bramki wejścia (gates) — żeby nie wchodzić w złych warunkach
Wejście w trade jest dozwolone tylko jeśli wszystkie gates są spełnione:
### 1) Freshness gate (dane muszą być świeże)
- `now - dlob_stats_latest.updated_at < freshness_max_ms`
- analogicznie dla depth/slippage, jeśli ich używasz w danym sygnale.
### 2) Spread gate
- `dlob_stats_latest.spread_bps <= spread_max_bps`
### 3) Slippage gate (dla planowanego rozmiaru)
- `dlob_slippage_latest.impact_bps(size_usd=entry_notional_usd, side=buy|sell) <= slippage_max_bps`
### 4) Liquidity gate
Wariant A (topN):
- `min(depth_bid_usd, depth_ask_usd) >= depth_topn_min_usd`
Wariant B (band bps):
- `min(bid_usd(band_bps=X), ask_usd(band_bps=X)) >= depth_band_min_usd`
W praktyce często warto użyć obu: topN + band (bo mierzą różne rzeczy).
## Trigger reversal (sekundy) — szkic logiki
To jest intencjonalnie prosty szkic, który można zastąpić modelem ML później.
Przykład (entry LONG):
- `mom_30s < 0` (krótkoterminowo spadkowo),
- `mom_3s > 0` (zaczyna się odbicie),
- opcjonalnie: `imbalance` rośnie (przechyla się na bid) albo spread się zawęża,
- gates spełnione.
Przykład (entry SHORT) analogicznie:
- `mom_30s > 0`, `mom_3s < 0`, itd.
## Wystawienie i “modyfikacja” wejścia (order policy)
### Zalecenie MVP: limit/post-only + chase
Zamiast market (który “nie jest modyfikowalny”), utrzymujemy order przy topofbook:
- Place entry limit:
- buy: blisko `best_bid` (np. `best_bid + tick`)
- sell: blisko `best_ask` (np. `best_ask - tick`)
- Jeśli order nie fill i cena “ucieka”:
- cancel + place nowy (reprice),
- ale z ograniczeniami: `cooldown_ms`, `max_orders_per_min`, `reprice_bps`.
Market order może być fallback tylko przy `urgency=true` i nadal spełnionych gates (zwłaszcza slippage).
## Zarządzanie pozycją (minuty) — proste reguły
Minimalne wyjścia (wystarczy na start):
- **max hold time**: `hold_max_s` (po czasie wychodzimy zawsze),
- **stop loss**: `stop_bps` od ceny wejścia,
- **take profit**: `take_bps` od ceny wejścia,
- **degradacja warunków**: wyjście, gdy np. `spread_bps` lub `impact_bps` przekracza limit przez X sekund.
## Parametry bota (do `bot_config`) — propozycja
Parametry są zgrupowane tak, żeby łatwo je stroić.
### A) Sizing i częstotliwość
- `entry_notional_usd`: ile USD “na wejście”
- `min_trade_usd`: próg “ignoruj małe delty”
- `decision_interval_ms`: jak często liczysz sygnał (np. 2501000ms)
- `hold_max_s`: maks. czas trzymania pozycji
### B) Gates mikrostruktury
- `freshness_max_ms`
- `spread_max_bps`
- `slippage_max_bps`
- `depth_topn_min_usd`
- `depth_band_bps` (np. 10 lub 20)
- `depth_band_min_usd`
### C) Reversal trigger
- `mom_fast_s` (np. 3s)
- `mom_slow_s` (np. 30s)
- `mom_entry_threshold` (jak mocny sygnał)
- `imbalance_entry_threshold` (opcjonalnie)
### D) Order policy (limit/chase)
- `order_policy`: `limit_post_only | limit | market`
- `reprice_bps`
- `reprice_after_ms`
- `cooldown_ms`
- `max_orders_per_min`
### E) Risk/exit
- `stop_bps`
- `take_bps`
- `exit_on_bad_spread_bps` + `exit_on_bad_spread_s`
- `exit_on_bad_slippage_bps` + `exit_on_bad_slippage_s`
## Metryki bota (do logowania w `bot_events`)
Żeby stroić strategię, logujemy na każdy “decision tick”:
- `features`: snapshot (albo hash + wybrane wartości: spread, slippage, depth, imbalance, mom)
- `gates`: które przeszły/nie przeszły + wartości
- `decision`: `target_exposure_usd`, `side`, `confidence`, `urgency`
- `actions`: place/cancel/close (z parametrami)
- `outcome`: fill, avg price, realized PnL (jeśli mamy), czas w pozycji
To pozwala później robić offline analizy: “dlaczego wchodził”, “gdzie przegrywa”, “jak dobrać progi”.