Skip to content

v1.4.2 — Multi-venue paper funding + WS hybrid

Choose a tag to compare

@sohan-shingade sohan-shingade released this 26 Apr 00:10
· 111 commits to main since this release

What's in this release

Two paper-trading correctness/UX wins.

1. Multi-venue paper funding correctness

Single-venue paper sessions were correct; multi-venue sessions silently
underreported funding. The tick loop only queried
`session.broker.venue` from `venue_funding_rates` so a
funding-dislocation-arb session holding Drift-long + HL-short would
book Drift's rate against both legs combined and miss HL entirely.

Fix (Option A from `docs/specs/paper-multivenue-funding.md`):

  • `PaperBroker.apply_funding(market, rate, mark_price, venue=None)` —
    new optional venue kwarg skips the apply when the position's venue
    doesn't match.
  • `flint/paper/engine.py`: extracted `_apply_session_funding(...)`
    helper that iterates `venues_in_book` derived from the broker's
    open positions, queries `venue_funding_rates` per venue, applies
    per-leg with `venue=` filter.
  • `paper_funding_payments` table widened: `venue` column added,
    PK becomes `(session_id, market, venue, ts)`. Migration mirrors
    the existing candles/orderbook venue-column pattern.
  • `PaperSessionStore.save_funding_payment` accepts `venue=`.

Doesn't fix Gap 2 (broker.positions still keyed by market only — same-market
opposite-leg arb collides on the dict key); deferred to D-2.1.d.

7 new tests, 39/39 paper-suite green.

2. WS hybrid hooks (drop polling-only, keep safety-net)

Live + paper session pages were poll-only on a 2s interval. Pure-WS
would be cleaner code but a single WS bug = dead UI.

New `useHybridPoll<TPoll, TWs>` hook: WS-primary, polling
secondary — adapts the polling cadence to WS health.

  • WS healthy → poll slowly (30s) for snapshot refresh
  • WS dead/silent → polling re-arms at the original cadence (2s)
  • `wsHealthy` flag exposes connection state for ConnectionBanner UX

Migrated:

  • `useSessionStatus` → `/ws/paper/{id}` + REST snapshot fallback,
    overlays live equity/cash/unrealized_pnl/total_trades on the snapshot
  • `useLiveMonitor` → `/ws/live/{id}` + REST snapshot fallback,
    appends WS equity points to the polled curve and merges WS fills
    with (fill_id, ts) dedupe

`usePaperPortfolio` stays poll-only (no `/ws/portfolio` aggregate
channel exists).

6 new tests, 139/139 vitest green (was 133).

Tests

  • 25/25 paper-funding + multi-venue Python suite
  • 139/139 vitest UI suite
  • ruff clean

Files

  • `flint/execution/paper_broker.py`, `flint/paper/engine.py`,
    `flint/paper/session_store.py`, `flint/store.py`
  • `tests/test_paper_funding.py`, `tests/test_paper_multi_venue.py`
  • `ui/src/hooks/useHybridPoll.ts` (new), `useLiveMonitor.ts`,
    `usePaperTrading.ts`
  • `ui/src/test/hooks/useHybridPoll.test.ts` (new)

🤖 Generated with Claude Code