Skip to main content

polyalpha

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 .

Quick start

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()

Market discovery

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 markets

Assets: BTC, ETH, SOL, XRP, DOGE, HYPE, BNB
Timeframes: 5m, 15m, 1h, 4h, 24h


Price streaming

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.down

See examples/stream.py.


Paper trading

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.


Calculations library

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-based

Data source accessors

Source-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 method

Source availability:

  • Chainlink: Price calculations only (no volume data)
  • Binance: Price + volume calculations
  • Coinbase: Price + volume calculations (future)

See src/polyalpha/calculations/ for implementation details.


Paper config & presets

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)

Built-in presets

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

Bots

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-rollover

Modes

Three 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))

TickContext

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 position

Composable conditions

Use 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.

See examples/bot_simple.py.

BotHub — Multi-Strategy Hub

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.


Real trading

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.balance

Real 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.


Auto-redeem

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.


Order book

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, BacktestEngine

Strategies: MomentumStrategy, SpreadStrategy (market making), ImbalanceStrategy.

See docs/orderbook.md for the full order book API.


Technical analysis

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 once

Data 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 None

Shared 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.


AI-powered signals

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.0

AI analysis is available via client.ai — see docs/ai.md for usage.


Reporting

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 kaleido

30+ 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.


Database

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.


Sniper bot

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.


Tracker

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.


Wallet management

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.


Errors

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
)

Logging

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.


Configuration

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
)

Examples index

| 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 |


Project layout

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

License

MIT

Download files

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

Source Distribution

polyalpha-2.3.1.tar.gz (347.5 kB view details)

Uploaded Source

Built Distribution

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

polyalpha-2.3.1-py3-none-any.whl (392.0 kB view details)

Uploaded Python 3

File details

Details for the file polyalpha-2.3.1.tar.gz.

File metadata

  • Download URL: polyalpha-2.3.1.tar.gz
  • Upload date:
  • Size: 347.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for polyalpha-2.3.1.tar.gz
Algorithm Hash digest
SHA256 594ffed46227ba506f7c25856363d1c7adc4203ae6d58082aa5c67de4c445ddd
MD5 07152c22c9c42f49d64a9c5e4cc4509f
BLAKE2b-256 1cd1b63cbcb500941ad29e9e5470354aac74d3e01bec720d779c515ff0f8ff74

See more details on using hashes here.

File details

Details for the file polyalpha-2.3.1-py3-none-any.whl.

File metadata

  • Download URL: polyalpha-2.3.1-py3-none-any.whl
  • Upload date:
  • Size: 392.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for polyalpha-2.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ab6d69db288aaee841edf64651b358ff6798bc375669df0b1826584f0aeee6cc
MD5 aad82df308dd35e803fbd5aa0e6af89c
BLAKE2b-256 ced4903c213a9f1ed9d31bee2cce43dc221e0a421daa9b2e8f5be15fc9053cff

See more details on using hashes here.

Release history Release notifications | RSS feed

2.4.0

2 files

This release

2.3.1 This release

2 files

2.3.0

2 files

0.2.29

2 files

0.2.28

2 files

0.2.27

2 files

0.2.26

2 files

0.2.25

2 files

0.2.23

2 files

0.2.22

2 files

0.2.21

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page