Skip to content

Release v2.3.0 — 13 exchanges, perpetual swaps, leverage, shorts, funding & cross-margin simulation - #7

Merged
Stenvro merged 8 commits into
masterfrom
dev
Sep 26, 2026
Merged

Stenvro merged 8 commits into
masterfrom
dev

Conversation

@Stenvro

@Stenvro Stenvro commented Sep 26, 2026

Copy link
Copy Markdown
Owner

Release v2.3.0

Three phases in one release: more exchanges, perpetual swaps with leverage, and shorts — plus the simulation realism work that makes those bots comparable across backtest, forward test and live. Spot bots are unaffected: every golden backtest is byte-identical to v2.2.1.

Exchanges

  • ExchangeSpec registry is the single source of truth (name, passphrase, ccxt config, market types, contract kinds); adding an exchange is one entry.
  • New: Bybit, Gate, Bitget, MEXC, HTX, BingX — 13 exchanges in total.
  • Frontend exchange lists (Settings, Data Manager, builder) come from GET /api/keys/exchanges; no hardcoded lists.

Perpetual swaps & leverage

  • An exchange key is bound to one market type (spot / swap); bots get market_type, leverage, margin_mode, validated against the key and the exchange's capabilities.
  • Linear and inverse contracts via ContractSpec (notional, margin, fees, PnL, liquidation price); Position.amount is base units on spot/linear and contracts on inverse.
  • Backtest/forward: margin locking, liquidation on the candle extreme after SL/TP had their chance; live: reduce-only closes, ensure_leverage at startup, position reconciliation through fetch_positions, rejected closes probed and booked as liquidations.
  • Kraken → krakenfutures, KuCoin → kucoinfutures, Binance inverse → binancecoinm; MEXC swaps excluded.

Shorts

  • Open short / Close short action blocks; short_node / cover_node mirror the long leg.
  • One direction-parameterised exit body: SL/TP/trailing/ATR mirrored for shorts (property-tested against the long rules).
  • Long and short never coexist on a pair; chart markers, Side columns, stats.bySide, "Buy to cover" force close.

Per-currency capital

  • CapitalPools keyed by currency; cash_currency on positions and orders; one cash currency per whitelist (validator).
  • /stats reports by_currency and never sums across currencies; the UI renders money only through fmtMoney.
  • profit_pct everywhere = realized PnL / locked capital (margin + entry fee).

Simulation realism

  • Funding rates: history fetched per swap symbol, settlements charged per candle in backtest and forward test (funding_paid on positions; summary funding, funding_paid, funding_events, funding_by_symbol).
  • Tiered maintenance margin: the exchange's leverage brackets are stored (refreshed weekly) and used for liquidation levels (summary mmr_source).
  • Real cross margin: an account-wide check after each candle's exits liquidates every open position when the pool no longer covers the maintenance margin.

Examples & tooling

  • New Supertrend_LongShort_Perp_1d example (1× BTC+ETH USDT perps), import test, verify_examples.py currency-aware.
  • Docs: README, BETA (swap limitations), STRATEGY_CONTEXT §1/§4.9.

Fixes

  • Flaky inverse-PnL hypothesis test: tolerance now scales with settle notional (the CI failure on dev).
  • Builder: generated layouts are re-spaced per column once ReactFlow has measured the node heights (no more overlapping blocks); routing block capped at 340px so the hint wraps.

Migrations (additive, idempotent)

  • positions: market_type, leverage, contracts, cash_currency, contract_kind, contract_size, funding_paid, funding_until (+ currency backfill for existing rows).
  • orders: market_type, reduce_only, fee_currency, fee_cash.
  • exchange_keys: market_type.
  • New tables funding_rates, leverage_tiers.

Tests

  • 231 → 244 tests: test_contracts.py, test_parity_modes.py, test_properties.py, test_swap.py, test_shorts.py, test_funding_tiers_cross.py, test_exchange_registry.py; two swap goldens added, all spot goldens unchanged.

Stenvro and others added 8 commits September 24, 2026 03:30
…s with leverage (long-only)

Phase 1 — exchanges
- ExchangeSpec registry is the single source of truth (name, passphrase,
  ccxt config, keys URL, sandbox/candle notes); SUPPORTED_EXCHANGES derived
- Added Bybit, Gate, Bitget, MEXC, HTX, BingX (13 exchanges total)
- Frontend reads GET /api/keys/exchanges via api/exchanges.js everywhere
  (Settings, DataManager, builder); no hardcoded lists

Phase 2 — market types / perpetual swaps
- ExchangeSpec.markets with MarketCaps (max leverage, ccxt id, leverage in
  order params); build_exchange pins options.defaultType, auth cache keyed
  on market type, get_exchange_symbols(exchange, market_type)
- engine/symbols.py: BASE/QUOTE:SETTLE helpers, market_type_for, leverage_for
- Additive migrations: exchange_keys.market_type, positions.market_type/
  leverage/contracts, orders.market_type/reduce_only
- Backtest/forward: entry locks notional/leverage + fees, PnL on full
  notional, liquidation at entry*(1-(1-0.005)/lev), summary adds
  market_type/leverage/liquidations/funding:"ignored"
- Live: create_order with reduceOnly/contracts on derivatives (spot path
  unchanged), ensure_leverage at startup and before the first buy,
  fetch_positions reconciliation for swaps, force-close reduce-only
- Validator: key/bot market-type match, :SETTLE form rules, leverage caps
  (warn above 3x), margin mode; keys router enforces market type per key
- Frontend: Market/Leverage/Margin controls in Exchange Routing, whitelist
  form hints, go-live checklist line, Perps chips on card/analytics/home,
  DataManager market select
- Tests: test_exchange_registry.py, test_swap.py (13); goldens unchanged

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- engine/pnl.py: side-aware PnL, liquidation, order sides, short/cover legs
- exits: mirrored short rules (SL above entry on high, TP below on low,
  trailing on lowest); long path untouched, goldens byte-identical
- backtest/forward/live: SHORT/COVER actions, long-short conflict gate,
  short liquidation on the high, reduce-only cover orders, side-aware
  reconciliation and cooldown
- validator: shorts refused on spot, short leg validated like entry
- API: positions expose market_type/leverage, orders reduce_only, stats bySide
- builder: SHORT/COVER action blocks, rebuild + serialize short legs only
  when present; chart markers, analytics side split, home short exposure
- tests/test_shorts.py (28), docs README + STRATEGY_CONTEXT
Audit (coder/trader/UI) follow-up, all in one:
- engine/contracts.py ContractSpec (spot|linear|inverse) + engine/capital.py
  CapitalPools per cash currency; one cash currency per bot (validator)
- inverse (coin-margined) swaps end to end; registry kinds, binancecoinm
- positions.cash_currency/contract_kind/contract_size, orders.fee_currency/
  fee_cash; /stats by_currency, /symbols markets, keys valuation_currency
- safety: side=None close, int coercion + per-bot tick isolation, live fee
  clamp, liquidation in forward + live detection, reconciliation failure
  refuses live, manual close under bot lock, leverage cache invalidation,
  bot_log_buffer push after commit (30s stall)
- honesty: profit_pct on locked capital everywhere, SL/TP before
  liquidation, 1x short liquidation, forward DD group, unrealized at
  candle_ts, candle-based cooldown, reduce_only-aware dedup, forward close
  frictions, max_order_value in backtest (fingerprint)
- exits.py single direction-parameterised body
- UI: Modal portal above builder (Close/Esc fix), builder name/dirty fixes,
  per-exchange live prices, side-aware close + Side columns, per-mode
  analytics tiles, fmtMoney per currency (no bare $), linear/inverse chips,
  chart/DataManager/Home/CSV fixes
- tests: 227 (parity modes, hypothesis properties, contracts, swap golden)
- docs: README, STRATEGY_CONTEXT, BETA
… backtest and forward test

- funding_rates/leverage_tiers tables, engine/funding.py + engine/tiers.py
- Position.funding_paid/funding_until, forward_pool includes open funding
- cross margin: account-level liquidation drains the pool (backtest + forward)
- Supertrend long/short perp example, verify_examples currency-aware
- swap goldens regenerated summary-only (orders unchanged)
@Stenvro
Stenvro merged commit bf89423 into master Sep 26, 2026
4 checks passed
@Stenvro
Stenvro deleted the dev branch September 26, 2026 07:49
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