Public beta: Banger supports paper trading only. Live execution is disabled, and historical backtesting currently supports only in-memory/synthetic tick sources.
N°03 / Build

Venue adapters

A Venue normalizes markets and ticks for a strategy. The bangertrades distribution includes Polymarket and Kalshi adapters. The public beta simulates execution in paper mode.

Polymarket

uv pip install bangertrades
from banger.venues.polymarket import Polymarket

class MyStrategy(Strategy):
    venues = [Polymarket()]
    universe = signals.polymarket_markets(
        category="crypto",
        min_volume_usd=10_000,
        time_to_resolution_lt="7d",
    )
    ...

No Polymarket private key is required or used for paper deployments. The legacy live extra is not a supported customer-money path.

Universe filters

  • category: case-insensitive substring match against the market’s category
  • min_volume_usd: exclude markets with cumulative volume below this
  • time_to_resolution_lt: "24h", "7d", etc. — resolves later than this is excluded
  • limit: cap result count (default 200)

Tick payload

Polymarket sends events on the public market WebSocket (no auth needed). Each event normalizes to a banger.Tick:

  • book snapshot → tick.yes_price / tick.no_price from best bid
  • price_change → updated best_bid
  • last_trade_pricetick.last_price

Kalshi

uv pip install bangertrades
from banger.venues.kalshi import Kalshi

class MyStrategy(Strategy):
    venues = [Kalshi()]
    universe = signals.kalshi_markets(
        category="NFL",
        time_to_resolution_lt="24h",
    )
    ...

Optional local WebSocket credentials

VariablePurpose
KALSHI_API_KEY_IDAPI key UUID from your Kalshi account
KALSHI_PRIVATE_KEYRSA private key (PEM). \n-escaped multiline works.

Kalshi authenticates WebSocket connections. Without these variables, the paper adapter falls back to public REST polling, so hosted paper strategies still receive ticks without a Kalshi account.

Signing

Banger signs every authenticated Kalshi request with RSA-PSS-SHA256 over {timestamp}{METHOD}{path}, per Kalshi’s spec. You don’t need to do this yourself — set the env vars and the adapter handles it. These variables are for self-managed local adapter access; Banger’s public beta does not route live orders.

Building your own adapter

Every adapter implements a small ABC:

from banger.venue import Venue

class MyVenue(Venue):
    name = "my_venue"

    async def list_markets(self, **filters):
        ...  # discover

    async def subscribe_ticks(self, markets):
        ...  # async generator yielding Tick

    async def place_order(self, order):
        ...  # adapter-level order contract; hosted beta simulates in Context

    async def cancel_order(self, order_id):
        ...

    async def get_positions(self):
        ...

See packages/adapters/polymarket/ in the repo for a worked market-data example with WebSocket reconnects and graceful public-data fallback.

See also