Python SDK for Polymarket — discover prediction markets, stream live prices, trade paper or real, run bots with composable strategy conditions, analyse with 19 TA indicators and AI signals, track P&L with full reporting, and manage wallets.
git clone https://github.com/Genius740Code/polyalpha.git
cd polyalpha
pip install -e .import polyalpha
client = polyalpha.Client()
market = client.markets.latest("BTC", "5m")
stream = client.stream(market)
@stream.on("price")
def on_price(up, down):
print(f"UP={up:.4f} DOWN={down:.4f}")
stream.start(background=True)
client.paper.buy(market, side="UP", amount=10.0)
client.paper.summary()Find any Up/Down market by asset + timeframe, slug, keyword, or browse all active.
client.markets.latest("BTC", "5m")
client.markets.latest("ETH", "15m")
client.markets.latest("SOL", "1h")
client.markets.get("btc-updown-5m-1751234700")
client.markets.search("ETH 15m")
client.markets.available("5m") # all active 5m marketsAssets: BTC, ETH, SOL, XRP, DOGE, HYPE, BNB
Timeframes: 5m, 15m, 1h, 4h, 24h
WebSocket stream with auto-reconnect, PING keepalive, and five event hooks.
stream = client.stream(market)
@stream.on("price") def on_price(up, down): ...
@stream.on("book") def on_book(data): ...
@stream.on("trade") def on_trade(data): ...
@stream.on("close") def on_close(): ...
@stream.on("error") def on_error(exc): ...
stream.start() # blocking
stream.start(background=True) # daemon thread
stream.stop()
# Latest prices without a handler
stream.up
stream.downSee examples/stream.py.
Simulate orders with configurable fees, slippage, execution delay, and risk limits. Attach a stream for live P&L.
client = polyalpha.Client(balance=500.0)
client.paper.buy(market, side="UP", amount=10.0)
client.paper.sell_position(market, side="UP", amount=5.0)
client.paper.limit(market, side="UP", price=0.92, amount=25.0)
client.paper.cancel(order.id)
client.paper.positions() # open positions
client.paper.all_positions() # all, incl. resolved
client.paper.balance
client.paper.summary() # P&L table
# Advanced order types (stop_loss_pct / take_profit_pct as decimals)
client.paper.buy(market, side="UP", amount=10.0,
stop_loss_pct=0.05, # 5% stop-loss
take_profit_pct=0.50) # 50% take-profit
client.paper.buy_with_tp_sl(market, side="UP", amount=10.0,
stop_loss=0.45, # absolute stop-loss price
take_profit=0.65) # absolute take-profit price
client.paper.oco_order(market, side="UP", amount=10.0,
stop_loss=0.40, take_profit=0.70) # one-cancels-other
# Attach a stream for auto-fill + live P&L
client.paper.attach_stream(stream, market)
# Resolve after settlement
client.paper.resolve(market, outcome="UP")See examples/paper.py and examples/advanced_orders.py.
Unified calculation functions for market data analysis across all data sources (Chainlink, Binance, Coinbase).
from polyalpha.calculations import MarketCalculations, VolumeCalculations
# Universal price calculations (all data sources)
MarketCalculations.change_pct(data, period=1) # % change over N periods
MarketCalculations.change_abs(data, period=1) # absolute price change
MarketCalculations.rate_of_change(data, period=1) # speed of change per second
MarketCalculations.trend(data, period=1) # UP/DOWN/NEUTRAL
MarketCalculations.direction(data, period=1) # "up"/"down"/"flat"
MarketCalculations.volatility(data, period=10) # price volatility
MarketCalculations.high(data, period=10) # highest price
MarketCalculations.low(data, period=10) # lowest price
MarketCalculations.range(data, period=10) # price range
# Volume calculations (Binance/Coinbase only)
VolumeCalculations.vol_ratio(data, period=10) # current / avg volume
VolumeCalculations.volume_trend(data, period=5) # INCREASING/DECREASING/STABLE
VolumeCalculations.volume_surge(data, multiplier=2.0) # detect volume spikes
VolumeCalculations.avg_volume(data, period=10) # average volume
VolumeCalculations.volume_momentum(data, period=5) # volume % change
VolumeCalculations.relative_volume(data, percentile=0.75) # percentile-basedSource-specific accessors that integrate calculations with live data:
from polyalpha.calculations import ChainlinkAccessor
from polyalpha.windows import TimeWindow
# Chainlink accessor (price calculations only)
window = TimeWindow(max_age=120)
cl_accessor = ChainlinkAccessor(window)
cl_accessor.update(67850.0) # Update with Chainlink price
cl_accessor.change_pct(30) # % change over 30 seconds
cl_accessor.trend(60) # trend direction
cl_accessor.is_rising(30) # convenience method
cl_accessor.is_falling(30) # convenience methodSource availability:
- Chainlink: Price calculations only (no volume data)
- Binance: Price + volume calculations
- Coinbase: Price + volume calculations (future)
See src/polyalpha/calculations/ for implementation details.
Tune realism: fee model, slippage, fill probability, execution delay, risk limits.
from polyalpha.trading.paper_config import get_paper_config_from_preset, list_presets
print(list_presets())
config = get_paper_config_from_preset("REALISTIC") # 2s delay, polymarket fees, 85% fill prob
config = get_paper_config_from_preset("AGGRESSIVE") # no delay, high fill prob
config = get_paper_config_from_preset("CONSERVATIVE") # polymarket fees, 1% slippage, 95% fill prob
config = get_paper_config_from_preset("TEST") # zero fees, instant, 100% fill
client = polyalpha.Client(balance=500.0, paper_config=config)
# or load from .env:
client = polyalpha.Client(paper_config_from_env=True)| Preset | Slippage | Delay | Fill prob | Risk |
|---|---|---|---|---|
CONSERVATIVE |
1% | 500ms | 95% | Low |
REALISTIC |
3% | 2000ms | 85% | Medium |
AGGRESSIVE |
5% | 100ms | 70% | High |
ZERO_FEE |
0% | 0ms | 100% | Medium |
HIGH_LATENCY |
8% | 5000ms | 60% | Medium |
LIQUIDITY_PROVIDER |
2% | 1000ms | 90% | Low |
SCALPER |
2% | 50ms | 98% | Low |
TEST |
0% | 0ms | 100% | None |
Bot handles the full lifecycle: discover → stream → tick → resolve → rollover → repeat.
bot = polyalpha.Bot("BTC", "5m", balance=500, mode="simple")
@bot.on_tick
def strategy(ctx):
if ctx.price.up > 0.9 and ctx.rsi > 50:
ctx.buy("UP", 20)
bot.run() # blocking, auto-rolloverThree execution templates via the mode parameter:
| Mode | Fees | Delay | Slippage | Fill prob |
|---|---|---|---|---|
"simple" (default) |
Zero | Instant | 0% | 100% |
"realistic" |
Polymarket fees | 2000ms | 3% | 85% |
"custom" |
Your PaperConfig |
Your config | Your config | Your config |
# Simple — zero fees, instant, 100% fill (default)
bot = polyalpha.Bot("BTC", "5m", balance=500)
# Realistic — polymarket fees, slippage, delay
bot = polyalpha.Bot("BTC", "5m", balance=500, mode="realistic")
# Custom — your own PaperConfig
from polyalpha.trading.paper_config import PaperConfig, get_paper_config_from_preset
bot = polyalpha.Bot("BTC", "5m", balance=500, mode="custom",
paper_config=PaperConfig(fee_mode="custom", custom_fee_rate=0.015))ctx.price.up / ctx.price.down # current prices
ctx.balance # paper balance
ctx.positions # open positions
ctx.pnl # realised P&L
ctx.rsi / ctx.sma_20 / ctx.ema_12 # indicators (requires pandas)
ctx.tick_count / ctx.trade_count
ctx.chainlink.last_price # BTC spot from Chainlink oracle
ctx.cl.value # latest Chainlink price
ctx.cl.change_pct(30) # % change over 30 seconds
ctx.cl.change_pct(60) # % change over 60 seconds
ctx.cl.age_s # seconds since last CL update
ctx.cl.trend(60) # trend direction (UP/DOWN/NEUTRAL)
ctx.cl.direction(30) # simple direction ("up"/"down"/"flat")
ctx.cl.volatility(120) # price volatility
ctx.binance.macd(12, 26, 9) # MACD from Binance data
ctx.binance.price_change(3) # BTC price change over 3 candles
ctx.binance.change_pct(3) # % price change over 3 candles
ctx.binance.vol_ratio(10) # current volume / avg of last 10 candles
ctx.binance.volume_trend(5) # volume trend (increasing/decreasing/stable)
ctx.binance.volume_surge(2.0) # detect volume spikes
ctx.buy("UP", 20) # market buy
ctx.limit("UP", 0.92, 25) # limit order
ctx.close_position("UP") # close positionUse declarative conditions with and_, or_, not_ (or &, |, ~).
from polyalpha.conditions import rsi_above, price_above, and_
bot.when(and_(rsi_above(50), price_above("up", 0.9))).buy("UP", 20)
bot.when(rsi_below(30) & price_below("down", 0.15)).buy("DOWN", 20)
bot.run()Built-in conditions: rsi_above, rsi_below, price_above, price_below, price_change_pct_above, sma_above, sma_below, trending_up, trending_down, volatility_above, volume_above, min_tick_count, max_spend, stopped, macd_bullish_crossover, macd_bearish_crossover, macd_above_zero, macd_below_zero, price_change_above, price_change_below, price_up, price_down
Mixing data sources: Conditions like macd_bullish_crossover() read from Binance BTC data via ctx.binance, while price_above() reads Polymarket UP/DOWN prices. Both work together in the same declarative rule:
from polyalpha.conditions import and_, price_above, macd_bullish_crossover
bot.when(
and_(price_above("UP", 0.90), macd_bullish_crossover())
).buy("UP", 20)
bot.run()Chainlink BTC spot is also available at ctx.chainlink.last_price in on_tick strategies or via ctx.chainlink in BotHub strategies.
Run multiple strategies from a single data connection. One market discovery, one WebSocket stream — N isolated paper engines. Eliminates redundant rate-limited connections.
hub = polyalpha.BotHub("BTC", "5m", default_balance=500)
@hub.strategy("momentum")
def momentum(ctx):
if ctx.price.up > 0.9 and ctx.rsi > 50:
ctx.buy("UP", 20)
@hub.strategy("value", balance=1000)
def value(ctx):
if ctx.price.down < 0.10:
ctx.buy("DOWN", 10)
hub.run()Each strategy gets its own balance, positions, and P&L. Error isolation — one crash doesn't stop the others.
Event hooks & timers: hub.on("tick"), hub.on("candle_open"), hub.every(30) for lifecycle callbacks.
Variants: Register strategies with params metadata and compare side-by-side via hub.compare_variants() (Rich table sorted by P&L, win rate, Sharpe, max drawdown).
Order book: ctx.orderbook.up.bids, ctx.orderbook.down.asks, ctx.orderbook.refresh() — auto-attached to the shared stream.
| Scenario | Use |
|---|---|
| One strategy | Bot |
| 20+ strategies, same asset/timeframe | BotHub |
| Different assets per strategy | Bot.run_async() |
See examples/bot_hub.py and docs/bot.md.
Trade live on Polymarket via CLOB with EIP-712 signing.
client = polyalpha.Client(
private_key="0x...",
rpc_url="https://polygon-rpc.com",
polymarket_api_key="...",
)
client.real.buy(market, side="UP", amount=10.0)
client.real.cancel(order.id)
client.real.positions()
client.real.balanceReal trading presets: CONSERVATIVE, REALISTIC, AGGRESSIVE, MINIMAL, HIGH_FREQUENCY, POSITION_TRADER, HEDGING_ENABLED, TEST.
Real trading is available via client.real — see docs/trading.md for the full API.
Schedule automatic redemption of winning positions.
from polyalpha import AutoRedeemConfig
config = AutoRedeemConfig(time_interval="1d", min_value_usd=100.0)
client.paper.set_auto_redeem_config(config)
client.paper.auto_redeem.start_scheduler()
# Manual
client.paper.auto_redeem.redeem()
client.paper.auto_redeem.get_redeem_history()Triggers: time interval, market count, value threshold. Safety: dry-run, min age, max value caps.
Auto-redeem is available via client.paper.auto_redeem — see docs/trading.md for usage.
REST snapshots + optional WebSocket deltas, in-memory O(1) manager, analytics, and backtestable strategies.
# REST
feed = client.orderbook(market)
feed.refresh()
feed.bids[:3]
feed.asks[:3]
# Attach stream for live updates
feed.attach_stream(client.stream(market))
# Analytics
from polyalpha.orderbook import estimate_fill, book_summary, cumulative_depth
estimate_fill(snapshot, side="UP", amount=100.0)
# Strategies + backtesting
from polyalpha.orderbook import MomentumStrategy, SpreadStrategy, BacktestEngineStrategies: MomentumStrategy, SpreadStrategy (market making), ImbalanceStrategy.
See docs/orderbook.md for the full order book API.
Multi-source data feed and 19 TA indicators.
from polyalpha.analysis import DataFeed, IndicatorCalculator, SignalGenerator
feed = DataFeed(DataFeedConfig(source="binance", timeframe="5m"))
data = feed.fetch("BTC")
ind = IndicatorCalculator(data)
ind.rsi(14)
ind.bollinger_bands(20, 2.0)
ind.macd(12, 26, 9)
ind.adx(14)
ind.atr(14)
ind.stochastic(14, 3, 3)
ind.obv()
sig = SignalGenerator(ind)
sig.rsi_above(50)
sig.price_above_sma(20)
sig.price_above_bb_upper()
sig.macd_bullish_crossover()
sig.summary() # all signals at onceData sources: scraping (default), binance, chainlink, custom, websocket.
Live Binance feeds (polyalpha.analysis): CVDTracker streams spot
aggTrades for cumulative volume delta (cvd, z, velocity, …), and
LiquidationTracker streams futures forceOrder events for one-sided
liquidation clusters (cluster()). Both run their own connection and
reconnect forever.
from polyalpha.analysis import CVDTracker, LiquidationTracker
cvd = CVDTracker(); cvd.start()
liq = LiquidationTracker(); liq.start()
cvd.z() # CVD z-score, or None
liq.cluster() # {"direction", "notional", "count"} or NoneShared Globals (polyalpha.Globals): one instance of every
continuously-running feed, shared by all strategies so adding one costs zero
extra connections. default_globals("BTC", cvd=True, liq=True) builds the
feeds; .start() / .stop() manage them all. Per-market scope is
MarketCtx / watch_market().
See examples/analysis.py and examples/price_change_signals.py.
Analyse markets and generate trading signals via OpenRouter.
client = polyalpha.Client(openrouter_api_key="sk-or-...")
analysis = client.ai.analyze_market(market_data)
analysis.sentiment # "bullish" | "bearish" | "neutral"
analysis.confidence # 0.0 – 1.0
analysis.reasoning # markdown explanation
signal = client.ai.generate_trading_signal(market_data)
signal.action # "BUY" | "SELL" | "HOLD"
signal.side # "UP" | "DOWN" | None
signal.confidence # 0.0 – 1.0AI analysis is available via client.ai — see docs/ai.md for usage.
Generate terminal summaries, interactive HTML dashboards, and PNG snapshots of paper-trading performance.
client.paper.report.show() # terminal (rich tables)
client.paper.report.html(open_browser=True) # interactive HTML
client.paper.report.save_png("report.png") # requires kaleido30+ metrics: Sharpe, Sortino, Calmar, Omega, Kelly criterion, VaR, CVaR, profit factor, win rate, average win/loss, max drawdown, recovery factor.
12 charts: equity curve, underwater drawdown, P&L per trade, win/loss distribution, monthly returns, rolling Sharpe, correlation matrix, P&L hourly heatmap.
See docs/reporting.md for the full reporting API.
SQLite-backed trade persistence with optional encryption.
client = polyalpha.Client(db_path="./trades.db")
db = client.paper.database
db.get_statistics() # aggregate stats (no args)
db.load_trades(filters={"asset": "btc"}) # filtered trades
db.load_trades_by_market("btc-updown-5m-1751234700") # trades for one market
db.export_json("trades.json")
db.export_csv("trades.csv")See docs/database.md for the full database API.
Time-window execution bot with configurable thresholds and auto-rollover. Supports advanced time windows: multiple disjoint periods, burst patterns, absolute time windows, conditional windows (indicator-based), and day/hour filtering.
from polyalpha import Sniper, SniperConfig, TimeWindow, ConditionalWindow, TimeFilter
# Simple time window (backward compatible)
Sniper(SniperConfig(
asset="BTC", timeframe="5m",
balance=500.0, window_seconds=30,
side="UP", order_size=25.0,
auto_rollover=True,
)).run()
# Advanced: Multiple time windows with conditions
Sniper(SniperConfig(
asset="BTC", timeframe="5m",
side="UP", entry_price=0.92, exit_price=0.88,
time_windows=[
TimeWindow(start_time="01:00", end_time="02:00"),
TimeWindow(start_time="02:30", end_time="03:00"),
],
conditional_windows=[
ConditionalWindow(indicator="btc_change", operator="lt", threshold=2.0, periods=5),
],
time_filter=TimeFilter(days=[0, 1, 2, 3, 4], hours=[9, 10, 11, 12, 13, 14, 15, 16, 17]),
amount=20.0,
)).run()timeframe is required (one of 5m, 15m, 1h, 4h, 24h — no silent 5m default). By default each bot buys only once per market (buy_once_per_market=True); set it to False on the config to allow multiple entries within the same market.
See examples/sniper.py, examples/sniper_minimal.py, examples/sniper_ta.py, and docs/bots.md.
Real-time P&L tracking with JSON/CSV export.
from polyalpha import Tracker
tracker = Tracker(client.paper)
tracker.sync()
tracker.summary()
tracker.export_json("trades.json")
tracker.export_csv("trades.csv")See docs/bot.md for Tracker usage.
Multi-wallet paper trading and secure wallet storage (AES-256, multi-sig, audit logging).
from polyalpha.trading.wallet import WalletManager, PaperWallet
manager = WalletManager()
manager.add_wallet(PaperWallet("trader-1", balance=1000.0))
client.paper.enable_multi_wallet(manager)See examples/multi_wallet_paper.py.
Typed exceptions for every failure mode:
from polyalpha import (
PolyalphaError, # base
MarketNotFound, # slug not found
MarketClosed, # window closed
StreamDisconnected, # WS retry exhausted
InsufficientBalance, # balance too low
OrderNotFound, # unknown order
OrderRejected, # CLOB rejection
OrderTimeout, # not filled
RiskLimitExceeded, # risk check failed
NetworkError, # HTTP/WS failure
)| Variable | Default | Description |
|---|---|---|
POLYALPHA_LOG_LEVEL |
WARNING |
DEBUG / INFO / WARNING / ERROR |
POLYALPHA_LOG_FILE |
— | File path (10 MB rotate) |
POLYALPHA_LOG_FORMAT |
text |
text or json |
Sensitive data (keys, addresses, tokens) is auto-redacted in both formats.
client = polyalpha.Client(
balance = 100.0, # paper USDC balance
timeout = 10, # HTTP timeout (s)
retries = 3, # HTTP retries
log_level = "WARNING",
rate_limit = None, # requests/s
paper_config = None, # PaperConfig instance
paper_config_from_env = False,
db_path = None, # SQLite path
openrouter_api_key = None, # AI features
private_key = None, # real trading key
rpc_url = None, # Polygon RPC
polymarket_api_key = None, # CLOB API key
real_config = None, # RealTradingConfig
)| File | What it shows |
|---|---|---|
| examples/stream.py | Price streaming with all event hooks |
| examples/paper.py | Paper trading — buy, sell, limit, summary |
| examples/advanced_orders.py | Trailing stop, OCO, take-profit |
| examples/conditions.py | Composable trading conditions |
| examples/bot_simple.py | Bot with on_tick strategy |
| examples/bot_hub.py | BotHub — multi-strategy from one connection |
| examples/sniper.py | Sniper time-window bot |
| examples/sniper_minimal.py | Minimal Sniper bot (~10 lines) |
| examples/sniper_ta.py | Sniper + technical analysis |
| examples/analysis.py | TA data feed, indicators, signals |
| examples/multi_wallet_paper.py | Multi-wallet paper trading |
| examples/risk_management.py | Risk limits and controls |
| examples/pairsum_arb.py | Arbitrage example |
| examples/price_change_signals.py | Price change detection signals |
| examples/chainlink_btc_scraper.py | Chainlink BTC data scraper |
| examples/multi_arb_bot.py | Multi-arbitrage bot |
| examples/telegram_notifications.py | Telegram notification integration |
src/polyalpha/
├── __init__.py Public API surface
├── client.py Client — single entry point
├── markets.py MarketClient — discovery
├── stream.py Stream — WebSocket price feed
├── bot.py Bot — lifecycle runner
├── bot_hub.py BotHub — multi-strategy hub
├── conditions.py Composable strategy conditions
│
├── core/ Constants, errors, market models, env
├── trading/ PaperEngine, RealTradingEngine, auto-redeem, retry
├── orderbook/ REST + WS book, manager, strategies, backtest
├── analysis/ DataFeed, 19 indicators, 30+ signals
├── ai/ OpenRouterClient, MarketAnalysis, TradingSignal
├── report/ ReportEngine, metrics (30+), charts (12), HTML
├── bots/ Sniper, Tracker
├── database/ SQLite, encryption, auth
├── wallet/ WalletSecurity, MultiSig, TransactionSigner, AuditLogger
└── utils/ Sensitive-data logging
MIT