Event Trader Python SDK
Official Python SDK for the Event Trader prediction markets platform.
Features
- Prediction Markets: Create and trade on perpetual prediction markets
- Trading: Place orders, manage positions, stream orderbooks
- Incentives: Bot management, rewards, leaderboards, airdrops
- Games: Streaks, duels, tournaments, boosts
- Wallet: Multi-wallet support, SIWE auth, portfolio tracking
- DeFi: DEX aggregation, IL calculation, MEV protection
- Exchanges: Unified CEX interface (Binance, Coinbase, Kraken, etc.)
- CLOB Exchange: Hybrid orderbook trading (CLOB + AMM), batch orders
- Launchpad: Non-custodial token launches on Circle Arc and Robinhood Chain (unsigned txs, you sign)
- Sync Client:
SyncEventTraderwrapper for non-async codebases - HMAC Signing: Request integrity via HMAC-SHA256 for low-latency trading
Installation
pip install cymetica-eventtrader
For Web3 functionality:
pip install cymetica-eventtrader[web3]
Quick Start
import asyncio
from event_trader import EventTrader
async def main():
# Initialize with API key
async with EventTrader(api_key="evt_...") as client:
# List active markets
markets = await client.markets.list(status="active")
for market in markets:
print(f"{market.question} - {market.status}")
# Get order book
orderbook = await client.markets.orderbook(markets[0].id, "BTC")
print(f"Best bid: {orderbook.best_bid}, Best ask: {orderbook.best_ask}")
# Place an order
order = await client.trading.place_order(
market_id=markets[0].id,
asset="BTC",
side="buy",
price=0.65,
quantity=100,
)
print(f"Order placed: {order.id}")
asyncio.run(main())
Synchronous Client
from event_trader import SyncEventTrader
# Synchronous usage — no asyncio needed
client = SyncEventTrader(api_key="evt_...")
# All methods are synchronous
markets = client.markets.list(status="active")
order = client.trading.place_order(market_id="0x...", asset="BTC", side="buy", price=0.65, quantity=100)
# Factory methods
client = SyncEventTrader.production("evt_...")
client = SyncEventTrader.development("evt_...")
# Context manager
with SyncEventTrader(api_key="evt_...") as client:
markets = client.markets.list()
Authentication
API Key
client = EventTrader(api_key="evt_...")
Email/Password
client = await EventTrader.from_credentials(
email="user@example.com",
password="password",
)
Wallet (SIWE)
async def sign_message(message: str) -> str:
# Sign with your wallet
return wallet.sign_message(message)
client = await EventTrader.from_wallet(
wallet_address="0x...",
sign_callback=sign_message,
)
HMAC Signing
# For low-latency trading with request integrity
client = EventTrader(
api_key="evt_...",
api_secret="your_secret", # Enables HMAC-SHA256 signing
)
# All requests automatically signed with X-Signature header
Services
Markets
# List markets
markets = await client.markets.list(status="active", limit=50)
# Get market details
market = await client.markets.get("0x...")
# Get order book
orderbook = await client.markets.orderbook("0x...", "BTC")
# Get featured market
featured = await client.markets.featured()
Trading
# Place order
order = await client.trading.place_order(
market_id="0x...",
asset="BTC",
side="buy",
price=0.65,
quantity=100,
)
# Cancel order
await client.trading.cancel_order(order.id)
# Get open orders
orders = await client.trading.open_orders()
# Get trade history
trades = await client.trading.history(market_id="0x...")
Incentives (Bot Management)
# Register a bot
bot = await client.incentives.register_bot(
name="MyArbitrageBot",
wallet_address="0x...",
strategy_type="arbitrage",
)
# Record trading volume
await client.incentives.record_volume(
bot_id=bot.id,
market_id="0x...",
volume_usd=5000,
)
# Check tier status
tier = await client.incentives.tier_status(bot.id)
print(f"Tier: {tier.current_tier}, Reward Multiplier: {tier.reward_multiplier}x")
# Get earnings
earnings = await client.incentives.earnings(bot.id)
# Get leaderboard
leaderboard = await client.incentives.leaderboard(period="weekly")
Games (Gamification)
# Get gamer profile
profile = await client.games.profile(user_id)
print(f"Level: {profile.level}, XP: {profile.xp}")
# Track win streak
streak = await client.games.record_streak(user_id, "win", market_id)
# Create a duel
duel = await client.games.create_duel(
market_id="0x...",
stake_amount=100,
)
# Join tournament
entry = await client.games.join_tournament(tournament_id, user_id)
# Activate boost
boost = await client.games.activate_boost(user_id, "xp_boost")
Wallet
# Get portfolio
portfolio = await client.wallet.portfolio(
"0x742d35Cc6634C0532925a3b844Bc9e7595f3E6",
chain="polygon",
)
# Get gas recommendations
gas = await client.wallet.gas_recommendations(chain="polygon")
# Get supported chains
chains = await client.wallet.supported_chains()
# SIWE authentication flow
session = await client.wallet.siwe_authenticate(
address="0x...",
sign_callback=sign_message,
)
DeFi
# Get swap quote
quote = await client.defi.swap_quote(
token_in="0xWETH...",
token_out="0xUSDC...",
amount_in="1000000000000000000", # 1 ETH
chain="ethereum",
)
# Calculate impermanent loss
il = await client.defi.calculate_il(
pool_address="0x...",
token_a="WETH",
token_b="USDC",
initial_price="2000",
current_price="2500",
initial_value_usd="10000",
)
# Get optimal V3 range
range_result = await client.defi.optimal_range(
current_price="2500",
volatility="0.8",
)
# Assess MEV risk
mev = await client.defi.assess_mev_risk(
token_in="0x...",
token_out="0x...",
amount_in="10000000000000000000",
amount_in_usd="25000",
slippage_bps=100,
)
Aggregator (Cross-Platform)
# Get markets across platforms
markets = await client.aggregator.markets(
platforms=["polymarket", "kalshi"],
category="politics",
)
# Find arbitrage opportunities
arbs = await client.aggregator.arbitrage_opportunities(
min_spread_bps=20,
min_profit=1.0,
)
# Route order optimally
plan = await client.aggregator.route_order(
market_id="0x...",
outcome_id="Yes",
side="buy",
size=100,
strategy="best_price",
)
Exchanges (CEX Integration)
# Get ticker from Binance
ticker = await client.exchanges.ticker("binance", "BTC/USDT")
# Compare prices across exchanges
comparison = await client.exchanges.compare_tickers(
"BTC/USDT",
exchanges=["binance", "coinbase", "kraken"],
)
# Place limit order
order = await client.exchanges.place_limit_order(
"binance",
symbol="BTC/USDT",
side="buy",
amount=0.001,
price=50000,
)
# Get account balance
balance = await client.exchanges.balance("binance")
CLOB Exchange
# Get hybrid orderbook (CLOB + AMM)
book = await client.clob.orderbook("vaix", depth=30)
# Place a limit order
order = await client.clob.place_order("vaix", side="buy", quantity="1000", price="0.003")
# Batch orders (up to 50)
results = await client.clob.batch_place_orders("vaix", [
{"side": "buy", "quantity": "500", "price": "0.003"},
{"side": "sell", "quantity": "500", "price": "0.004"},
])
# Cancel all orders
await client.clob.cancel_all("vaix")
# Get open orders and trade history
orders = await client.clob.open_orders("vaix")
trades = await client.clob.my_trades("vaix", limit=50)
# Get market stats
stats = await client.clob.stats("vaix")
AI Index Baskets (Trend Cards)
Tokenized, ETF-like on-chain index funds. Each AIB is its own mainnet ERC-20
share token (AIB-<SYM>, e.g. AIB-AA208630); shares mint against on-chain
basket backing at NAV and are withdrawable on-chain.
# Discover live Trend Cards
cards = await client.aib.list_trend_cards()
# Definition, live NAV, issuance quote, real-time iNAV
info = await client.aib.get("AIB-AA208630")
nav = await client.aib.nav("AIB-AA208630")
quote = await client.aib.quote("AIB-AA208630") # ask=mint@NAV+spread, bid=redeem@NAV-fee
inav = await client.aib.inav("AIB-AA208630") # + premium/discount vs market price
# Buy shares (pay USDC, mint at NAV+spread) and check your holdings
order = await client.aib.buy("AIB-AA208630", "100") # spend 100 USDC
mine = await client.aib.holdings() # non-zero AIB share balances
# Sell to in-platform USDC ...
await client.aib.sell("AIB-AA208630", 50)
# ... or redeem for an ON-CHAIN USDC payout to your own address
await client.aib.redeem("AIB-AA208630", 50, destination_address="0xYourAddress")
# Secondary market: trade shares on the CLOB with the AIB-<SYM> symbol
book = await client.clob.orderbook("AIB-AA208630")
Launchpad (Circle Arc + Robinhood Chain)
Non-custodial token launchpad: the SDK builds unsigned transactions, your wallet signs. Arc (chain 5042; 5042002 = testnet): $0 creation, zero platform fees, 100% of locked-liquidity fees to the creator. Robinhood Chain (4663): $0 creation, 0.25% curve fee with 80% to the creator.
async with EventTrader() as client: # reads need no auth
cfg = await client.launchpad.config() # live chains, factories, fees_by_chain
hot = await client.launchpad.list_tokens(sort="volume", limit=5, chain_id=5042)
q = await client.launchpad.trade_quote(hot[0]["address"], side="buy", amount=1.0)
prep = await client.launchpad.prepare_launch(
"My Token", "MYT", description="…", website="https://example.com",
chain_id=5042, # Arc mainnet; omit for Robinhood Chain
)
tx = prep["unsigned_transaction"] # {chain_id, to, value_wei, data, gas_hint}
# sign + broadcast `tx` with your own wallet; the token and curve
# addresses are in the receipt's LaunchCreated event.
Docs: https://cymetica.com/launchpad/arc/sdk · https://cymetica.com/launchpad/robinhood/sdk.
A dependency-light, synchronous single-file variant ships in this same package as a
second top-level module — from eventtrader_launchpad import EventTraderLaunchpad
(needs only requests; web3 only for sign_and_send).
Streaming
# Stream order book updates
async for update in client.streaming.orderbook("0x...", "BTC"):
print(f"Spread: {update.spread}")
# Private WebSocket (user orders and fills)
async for update in client.streaming.private(token="your_jwt"):
if update.channel == "userOrders":
print(f"Order update: {update.data}")
elif update.channel == "userFills":
print(f"Fill: {update.data}")
CLOB Streaming (Settlement Notifications)
from event_trader.streaming.clob import CLOBStream
stream = CLOBStream(config, channels=["userFills", "balanceUpdate"], token="jwt_token")
# Settlement status notifications — get alerted to delays
def on_settlement(data):
status = data.get("settlement_status")
if status == "settled":
print(f"Settled on-chain: {data['explorer_url']}")
elif status == "delayed":
print(f"Settlement delayed ({data['delay_seconds']}s) — ETA: {data['estimated_completion']}")
elif status == "failed":
print(f"Settlement failed — funds will be refunded automatically")
stream.on_settlement(on_settlement)
stream.on_fill(lambda data: print(f"Fill: {data}"))
stream.on_balance(lambda data: print(f"Balance changed"))
async for event in stream:
pass # Callbacks fire automatically
Settlement Status Flow
Orders settle in the background after matching. The WebSocket settlement_update event
reports progress:
| Status | Meaning | Fields |
|---|---|---|
settled |
On-chain swap confirmed | tx_hash, explorer_url, chain |
delayed |
Settlement taking longer than expected | delay_seconds, retry_count, estimated_completion |
failed |
Settlement failed after retries | reason (internal — use generic message for users) |
Typical settlement time: 10-30 seconds. Maximum: 90 seconds per attempt, up to 3 retries.
Error Handling
from event_trader import (
EventTraderError,
AuthenticationError,
RateLimitError,
NotFoundError,
InsufficientFundsError,
OrderError,
)
try:
order = await client.trading.place_order(...)
except InsufficientFundsError:
print("Not enough balance")
except RateLimitError as e:
print(f"Rate limited, retry after {e.retry_after}s")
except NotFoundError:
print("Market not found")
except OrderError as e:
print(f"Order failed: {e}")
except EventTraderError as e:
print(f"SDK error: {e}")
Configuration
client = EventTrader(
api_key="evt_...",
base_url="https://cymetica.com",
timeout=30.0,
max_retries=3,
debug=True,
)
Examples
See the examples/ directory for complete examples:
basic_trading.py- Basic trading workflowstreaming_orderbook.py- Real-time orderbook streamingmarket_maker_bot.py- Simple market makerbot_incentives.py- Bot registration and rewardsgamification.py- Games and gamification featuresdefi_integration.py- DeFi/DEX integrationexchange_trading.py- CEX tradingclob_trading.py- CLOB exchange trading
License
MIT
Metadata
Release files for cymetica-eventtrader 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cymetica_eventtrader-0.3.0.tar.gz | 104.5 kB | Without provenance | Details for cymetica_eventtrader-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cymetica_eventtrader-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for cymetica_eventtrader-0.3.0-py3-none-any.whl |
Total release size: 231.9 kB
Release files / cymetica_eventtrader-0.3.0.tar.gz
| Download URL | cymetica_eventtrader-0.3.0.tar.gz |
|---|---|
| Size | 104.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6cc5ed530cffbfc885d000027e756318d5c5a44ed2d591344c8027d92bd48cfa
|
|
BLAKE2b-256 checksum How to use checksums |
86bdbdb357567e10120fdb0c1e2c1b666d6db1f9c4c71a31f3bc649570f55609
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / cymetica_eventtrader-0.3.0-py3-none-any.whl
| Download URL | cymetica_eventtrader-0.3.0-py3-none-any.whl |
|---|---|
| Size | 127.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
03275495275fa673d82b26c31230dc8c2b71622dd3c5bd3ba1483c8216c09eeb
|
|
BLAKE2b-256 checksum How to use checksums |
21f602f26b78e2a178dd7ddc40b51fd552ed1e2900be97679416ec78f7ef4a61
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for cymetica-eventtrader 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.