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: usedemowith credentials created on the Kalshi demo stack (demo-api.kalshi.co). Production keys only work against the production feed; mixing them returns 401s. wato paperdoes not take--kalshi-environment. SetKALSHI_ENVIRONMENT=demo(or leave unset for production data). In YAML configs, usekalshi.environmentinstead (see below)..envis not loaded automatically —exportvariables orsource .envin 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d59a83125d5d96a30c6319340c5e25b8b66232cee273b48f7e3b5eb032ee2b8d
|
|
| MD5 |
3e85cc5dcc270e4e40529815bb048fb8
|
|
| BLAKE2b-256 |
072043a9b73cab1d261f8ea717a8a378f600a96926270d72bba7640c8aeeb9d0
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab2bfaff13176bcd40f54eb94386319d89a4f568a4032ad9bb74bff59c362306
|
|
| MD5 |
bed10991f2d7011f379d6f8bd1c3f80e
|
|
| BLAKE2b-256 |
a68ff4d8b6f99124e8c261aeecbef4ddb4dbdd76fd0176209f3eb6c77d1b2666
|