Skip to content

v3.2.0

Choose a tag to compare

@github-actions github-actions released this 05 Jun 19:25
· 15 commits to main since this release
eed032d

Adds full SDK support for the Kalshi Perps (margin) API — a separate
perpetual-futures exchange — as standalone clients alongside the existing
prediction-API surface. Additive release: no changes to KalshiClient.

Added

  • PerpsClient / AsyncPerpsClient — standalone clients for the perps
    exchange (external-api.kalshi.com / demo external-api.demo.kalshi.co,
    /trade-api/v2), with their own PerpsConfig and a separate KALSHI_PERPS_*
    credential namespace. They reuse the prediction-API RSA-PSS signer and HTTP
    transport unchanged. The constructors and from_env() also accept
    ws_base_url (set the WS endpoint independently from REST) and password
    (passphrase for an encrypted key), and read KALSHI_PERPS_WS_BASE_URL /
    KALSHI_PERPS_PRIVATE_KEY_PASSPHRASE from the environment; passing config=
    together with demo/base_url/ws_base_url is rejected. Resource families:
    exchange (status / enabled gate /
    risk parameters), markets (list / get / orderbook / candlesticks), orders
    (create / get / list / cancel / decrease / amend + FCM), order_groups,
    portfolio (positions / fills / trades), margin (balance / risk /
    notional risk limit / fee tiers), funding (rate estimate / historical /
    history), and transfers (intra-exchange-instance + margin subaccounts).
    Margin order side is bid / ask; prices are DollarDecimal
    (FixedPointDollars), counts FixedPointCount, and number/double ratios
    (leverage, funding rate, ROE, fee tiers) are MultiplierDecimal (exact
    Decimal, string-serialized) — consistent across the REST, WS, and exchange
    surfaces. Margin-account list responses tolerate a server-returned null.
  • PerpsWebSocket — the perps margin WebSocket
    (external-api-margin-ws.kalshi.com, /trade-api/ws/v2/margin) with six typed
    channels (subscribe_orderbook_delta, subscribe_ticker — carrying
    funding_rate + next_funding_time_ms, subscribe_trade, subscribe_fill,
    subscribe_user_orders, subscribe_order_group). Reuses the event-contract
    WS connection / sequence-gap / backpressure machinery; perps WS timestamps are
    Unix epoch milliseconds (*_ms fields).
  • KlearClient / AsyncKlearClient — the Self-Clearing-Member "Klear"
    settlement API (api.klear.kalshi.com / demo demo-api.kalshi.co,
    /klear-api/v1) with a third auth model: cookie-session + MFA via
    login(email=..., password=..., code=...). Resource margin covers reports,
    active/historical obligations, settlement estimate, settlement + guaranty-fund
    balances, settlement-balance history, and settlement-balance withdrawal.
    Klear money fields are integer centicents; the single real-money write
    (withdraw_settlement_balance) validates a positive amount at construction.
    Credentials and the session cookie are never logged or shown in repr().
  • docs/perps.md (+ mkdocs nav), README "Perps (margin) trading" section, and
    runnable examples/perps_create_order.py / perps_stream_ticker.py /
    perps_balance_risk.py.

Changed

  • Prediction-API list endpoints markets.candlesticks / bulk_candlesticks /
    bulk_orderbooks now validate a typed response envelope: a missing
    spec-required array key raises ValidationError (surfacing spec drift instead
    of silently returning []), while a null array coerces to [] (Kalshi's
    empty-as-null convention — the prior data.get(...) extraction would
    TypeError on a null array). The perps markets.list / markets.candlesticks
    / funding.historical_rates / funding.history responses use the same
    NullableList envelopes, so null-handling is consistent across both surfaces.
    The optional order_groups.list stays tolerant of a missing/null array.

Fixed

  • KalshiWebSocket._stop() now retrieves an already-finished receive-loop's
    exception, so a session torn down after a permanent close no longer logs
    asyncio's "Task exception was never retrieved" on garbage collection.

Internal

  • Vendored the three perps specs (specs/perps_openapi.yaml,
    perps_asyncapi.yaml, perps_scm_openapi.yaml); scripts/sync_spec.py and the
    weekly spec-sync workflow now fetch/diff/checksum them and fold their sha256
    into the drift fingerprint (preserving the contents: read + issues: write
    security model).
  • Parameterized the contract-drift harness per spec: TestPerps*Drift /
    TestPerpsScm*Drift validate the perps REST + SCM surfaces against their own
    specs, alongside the existing prediction-API drift suites.
  • README / docs/index.md banners note the perps surface (34 REST operations,
    6 WS channels, 10 SCM operations).