Skip to content

execution: implement PaperVenue and CcxtVenueAdapter#7

Merged
marwinsteiner merged 6 commits intomainfrom
phase-2/venue-adapters
Feb 21, 2026
Merged

execution: implement PaperVenue and CcxtVenueAdapter#7
marwinsteiner merged 6 commits intomainfrom
phase-2/venue-adapters

Conversation

@marwinsteiner
Copy link
Copy Markdown
Owner

Summary

Implements two concrete VenueAdapter implementations for Phase 2:

  • PaperVenue (src/sysls/execution/paper.py) -- Paper trading adapter that simulates a venue entirely in-memory. Market orders fill immediately with optional latency, limit orders are accepted but not auto-filled (Phase 3+). Supports configurable partial fill probability, tracks positions and balances, and emits all order lifecycle events (OrderAccepted, FillEvent, OrderCancelled) on the event bus.

  • CcxtVenueAdapter (src/sysls/execution/venues/ccxt_venue.py) -- Crypto exchange adapter wrapping the ccxt unified API. Supports any ccxt-compatible exchange (Binance, Bybit, OKX, etc.) with sync ccxt calls offloaded via asyncio.to_thread(). Features sandbox/testnet mode, symbol conversion (spot/perp/future), ccxt error wrapping into sysls exception hierarchy, position and balance fetching, and market loading on connect.

  • ccxt dependency added as optional (sysls[ccxt]) and dev dependency.

Test Plan

  • 25 PaperVenue tests covering lifecycle, order submission, fills, cancellation, positions, balances, partial fills, latency, and event emission
  • 39 CcxtVenueAdapter tests (all mocked, no real API calls) covering connect/disconnect, order operations, status mapping, position/balance queries, error wrapping, symbol conversion, instrument building, sandbox mode, and credentials passthrough
  • Full test suite: 422 passed, 10 skipped (ArcticDB optional), 0 failures
  • ruff check and ruff format clean

ccxt>=4.0 added as optional dependency (sysls[ccxt]) and to the dev
dependency group so venue adapter tests can import it.
PaperVenue is a VenueAdapter that simulates a trading venue entirely
in-memory. Features:
- Market orders fill immediately with optional latency
- Limit orders are accepted but not auto-filled (Phase 3+)
- Configurable partial fill probability
- Emits OrderAccepted, FillEvent, OrderCancelled on the event bus
- Tracks positions and balances internally
- Deterministic fill price from order price or default
Tests cover:
- Connect/disconnect lifecycle and context manager
- Name and supported_order_types properties
- Initial balance defaults and customization
- Market order immediate fill with event emission
- Default fill price for market orders without price
- Limit order acceptance without fill
- Cancel order with event emission and status update
- Unknown order cancel/status raises OrderError
- Position tracking after buy/sell fills
- Balance tracking after buy/sell fills
- Partial fill probability (mock + deterministic)
- Fill latency simulation
- Multiple order accumulation
- Defensive copies from get_positions/get_balances
CcxtVenueAdapter wraps the ccxt unified API to provide connectivity
to any ccxt-compatible crypto exchange. Features:
- Async wrapper around sync ccxt calls via asyncio.to_thread()
- Sandbox/testnet mode support
- Symbol conversion from sysls Instrument to ccxt format
- Order status mapping (ccxt -> sysls OrderStatus)
- Position fetching for derivatives (fetch_positions)
- Balance fetching with zero-balance filtering
- Error wrapping: ccxt exceptions -> VenueError/OrderError/ConnectionError
- Market loading on connect with instrument building from ccxt markets
Tests cover:
- Connect/disconnect lifecycle and context manager
- Unknown exchange raises SyslsConnectionError
- load_markets failure handling
- Name and supported_order_types properties
- Sandbox mode activation
- Market and limit order submission with correct ccxt params
- Cancel order with OrderCancelled event emission
- Order status mapping for all ccxt status strings
- Derivative position parsing (long/short/zero)
- Balance fetching with zero-balance filtering
- Error wrapping: InvalidOrder, NetworkError, ExchangeError, OrderNotFound
- Not-connected guard raises VenueError
- Symbol conversion: spot, dash-format, perp, future, base-only
- Instrument building from ccxt market dicts
- API credentials and extra config passthrough
@marwinsteiner marwinsteiner merged commit 57b26c9 into main Feb 21, 2026
1 check passed
@marwinsteiner marwinsteiner deleted the phase-2/venue-adapters branch February 21, 2026 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant