Skip to main content

Build, test, and deploy prediction market trading strategies

Project description

wato

Build, test, and deploy prediction market trading bots. Strategies are plain Python classes that return declarative trade intents; wato handles order management, risk checks, paper simulation, and live execution against Polymarket and Kalshi.

Install

pip install wato

Requires Python 3.11+.

Quick start

Scaffold a new strategy:

wato init my_bot
cd my_bot

This writes strategy.py with a stubbed MarketBot. Replace it with the minimal market-maker below:

from decimal import Decimal
from wato import MarketBot, StrategyContext
from wato.strategy.intents import Quote, CancelAll
from wato.types import OrderBook


class MidQuoter(MarketBot):
    async def on_book(self, ctx: StrategyContext, book: OrderBook) -> list:
        if not book.bids or not book.asks:
            return []

        mid = (book.bids[0].price + book.asks[0].price) / 2
        return [
            CancelAll(market_id=book.market_id, outcome_id=book.outcome_id),
            Quote(
                market_id=book.market_id,
                outcome_id=book.outcome_id,
                fair_price=mid,
                spread=Decimal("0.02"),
                size=Decimal("10"),
            ),
        ]


strategy = MidQuoter()   # module must expose a top-level `strategy` variable

Run it in paper mode against live Polymarket data:

wato paper strategy.py --exchange polymarket --markets asset_id

Lifecycle handlers

Strategies subclass MarketBot and implement async handlers. Each returns a list of intents (Quote, TargetPosition, RawOrder, CancelAll, CancelOrder).

Handler Fires on
on_start(ctx) engine start
on_book(ctx, book) new L2 order book snapshot
on_trade(ctx, trade) public trade print
on_tick(ctx) periodic tick (default 1000ms)
on_fill(ctx, fill) one of your orders filled
on_order(ctx, update) order status change
on_market(ctx, market) market metadata update
on_stop(ctx) shutdown

Use PortfolioBot instead of MarketBot for strategies that need to coordinate across multiple venues. See the docs for the full context API, intent reference, and risk-limit catalog.

CLI

wato init [NAME]            Scaffold a new strategy project
wato paper STRATEGY.py      Run a strategy in paper mode (simulated fills)
wato live STRATEGY.py       Run a strategy with real Kalshi orders
wato run CONFIG.yaml        Run a strategy from a YAML config (paper, live, or portfolio)
wato skills install         Install the Claude Code skill for wato bots
wato login                  Authenticate with the wato dashboard
wato logout                 Remove stored credentials
wato whoami                 Show current auth status

Run wato <command> --help for per-command flags.

Paper trading

Paper mode never sends real orders. The engine replays live order books and applies a fill simulator (default: mid-touch) so you can test logic and risk against real prices.

Polymarket — public data only; no API keys.

wato paper strategy.py --exchange polymarket --markets asset_id

Kalshi — the feed is an authenticated WebSocket, so you need a Kalshi API key and an RSA private key in PKCS#8 PEM form (-----BEGIN PRIVATE KEY-----), registered under Kalshi Settings → API.

  • Demo vs production data: The WebSocket host follows KALSHI_ENVIRONMENT: use demo with credentials created on the Kalshi demo stack (demo-api.kalshi.co). Production keys only work against the production feed; mixing them returns 401s.
  • wato paper does not take --kalshi-environment. Set KALSHI_ENVIRONMENT=demo (or leave unset for production data). In YAML configs, use kalshi.environment instead (see below).
  • .env is not loaded automaticallyexport variables or source .env in your shell.
export KALSHI_API_KEY="your-uuid"
export KALSHI_PRIVATE_KEY_PATH="$HOME/.kalshi/key.pem"
export KALSHI_ENVIRONMENT=demo   # optional; omit for production market data

wato paper strategy.py --exchange kalshi --markets KXBTC-25DEC31
# Multiple tickers: --markets KXBTC-25DEC31,KXOTHER-TICKER

Optional flags: --balance (starting paper cash), --tick-interval, --tui (terminal dashboard), --fill-model mid.

From a config file (handy when you want environment: demo without shell exports):

# wato.yaml
mode: paper
strategy: strategy.py
exchange: kalshi
markets:
  - KXBTC-25DEC31
balance: 10000
kalshi:
  api_key: your-uuid        # or rely on KALSHI_API_KEY
  private_key: ~/.kalshi/key.pem
  environment: demo         # or prod (default if omitted resolves like live)
wato run wato.yaml

Paper vs Kalshi demo “live”: Paper = simulated fills only. To place real resting orders on Kalshi’s demo exchange (fake money, real matching engine), use wato live ... --kalshi-environment demo with demo API credentials instead.

Live trading (Kalshi only)

wato live strategy.py \
  --markets KXBTC-25DEC31 \
  --kalshi-api-key "$KALSHI_API_KEY" \
  --kalshi-private-key /path/to/key.pem \
  --kalshi-environment demo \
  --max-capital 5

--kalshi-environment defaults to prod (real money). Always pass demo until you trust the strategy. See the live trading docs for the full credential setup and shutdown behavior.

Risk limits

Cap downside before going live:

wato live strategy.py --markets KXBTC-25DEC31 \
  --max-loss 200 --max-position 100 --max-capital 500 \
  --kalshi-api-key $KALSHI_API_KEY \
  --kalshi-private-key ~/.kalshi/key.pem

Or programmatically:

from decimal import Decimal
from wato.risk.limits import MaxPosition, MaxLoss, MaxCapitalAtRisk

risk_checks = [
    MaxPosition(max_size=Decimal("100")),
    MaxLoss(max_loss=Decimal("200"), initial_balance=Decimal("1000")),
    MaxCapitalAtRisk(max_capital=Decimal("500")),
]

Claude Code skill

wato ships a Claude Code skill that teaches Claude how to write, run, and debug wato bots. Install it once:

wato skills install

After restarting Claude Code, ask Claude to "write me a wato market-maker bot" and the skill auto-loads with the full SDK reference, intent API, and Kalshi gotchas.

Dashboard

Authenticated runs stream traces, orders, fills, errors, and P&L to dash.watolabs.com for real-time observability. Set a version attribute on your strategy class to track deployments:

class MyBot(MarketBot):
    version = "2.1.0"

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wato-0.1.3.tar.gz (69.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wato-0.1.3-py3-none-any.whl (96.6 kB view details)

Uploaded Python 3

File details

Details for the file wato-0.1.3.tar.gz.

File metadata

  • Download URL: wato-0.1.3.tar.gz
  • Upload date:
  • Size: 69.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.13

File hashes

Hashes for wato-0.1.3.tar.gz
Algorithm Hash digest
SHA256 d59a83125d5d96a30c6319340c5e25b8b66232cee273b48f7e3b5eb032ee2b8d
MD5 3e85cc5dcc270e4e40529815bb048fb8
BLAKE2b-256 072043a9b73cab1d261f8ea717a8a378f600a96926270d72bba7640c8aeeb9d0

See more details on using hashes here.

File details

Details for the file wato-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: wato-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 96.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.13

File hashes

Hashes for wato-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ab2bfaff13176bcd40f54eb94386319d89a4f568a4032ad9bb74bff59c362306
MD5 bed10991f2d7011f379d6f8bd1c3f80e
BLAKE2b-256 a68ff4d8b6f99124e8c261aeecbef4ddb4dbdd76fd0176209f3eb6c77d1b2666

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page