Python SDK for the Coindubo Prediction Market API.
Project description
coindubo
Python SDK for the Coindubo Prediction Market API.
Trade BTC binary-outcome prediction markets programmatically. Zero runtime dependencies. Python 3.9+.
Install
pip install coindubo
Quickstart
Get an API key from your Coindubo Profile & API Keys page, then:
from coindubo import Client
client = Client(api_key="sk_...")
# Wait for the next market to open and place an order on it
active = client.markets.wait_for_active()
ack = client.orders.place(
market_id=active.market.id,
side="UP", # "UP" (yes) or "DOWN" (no)
direction="BUY", # "BUY" (open position) or "SELL" (close position)
price=0.40, # 0.01–0.99
quantity=10,
)
print("placed", ack.order_id)
# Watch fills as they come in
def on_fill(order):
print("filled:", order.id, "at avg", order.price)
client.orders.watch_fills([ack.order_id], on_fill=on_fill, deadline_s=60.0)
What's in the SDK
The Client exposes four domain APIs and the underlying transports.
client.markets — market data and the wait_for_active primitive
| Method | Purpose |
|---|---|
list(date=None, status=None) |
List markets, optionally filtered |
get(market_id) |
Fetch a market by id |
get_by_slug(slug) |
Fetch a market by slug |
active() |
The market currently open for trading (or NotFoundError) |
nearby(slug, before=5, after=5) |
Markets surrounding a slug |
orderbook(market_id) |
Snapshot of UP/DOWN bids and asks |
candles(start=None, end=None) |
OHLCV BTC candles |
price_history() |
Last ~5 minutes of BTC ticks |
wait_for_active(poll_interval=3.0) |
Poll until a market opens |
client.orders — placement, cancellation, fill tracking
| Method | Purpose |
|---|---|
place(market_id, side, direction, price, quantity) |
Place one limit order |
place_batch(orders: List[OrderRequest]) |
Place many orders in sequence |
list(status=None) |
List the user's orders |
cancel(order_id) |
Cancel an open order |
watch_fills(order_ids, on_fill, poll_interval=1.0, deadline_s=60.0) |
Block until orders reach a terminal state, calling on_fill(order) per fill |
client.portfolio — wallet, positions, trades, snapshots
| Method | Purpose |
|---|---|
wallet() |
Balance and used margin |
ledger(limit=50, offset=0) |
Paginated wallet ledger |
positions(settled=None) |
Open or settled positions |
trades(limit=50, offset=0) |
Paginated trade history |
market_trades(market_id, limit=50, offset=0) |
Trades for one market |
snapshot(market_slug=None) |
Wallet + positions + open orders + recent trades + nearby markets, in a single call |
client.stream — typed WebSocket subscriptions
Each method registers a callback. Returns a handle whose .close() unsubscribes.
| Method | Event type |
|---|---|
orderbook(market_id, on_message) |
OrderbookUpdate |
trades(market_id, on_message) |
TradeEvent |
prices(on_message) |
PriceTickEvent |
markets(on_message) |
MarketEvent |
positions(on_message) |
PositionUpdate |
The underlying WebSocket reconnects automatically with exponential backoff (1s base, 30s cap) and re-subscribes to all active channels on reconnect.
Errors
Every SDK failure raises a subclass of CoinduboError:
from coindubo import (
CoinduboError, # base
AuthError, # 401 / 403
RateLimitError, # 429 — has .retry_after_ms
ValidationError, # 400
NotFoundError, # 404
ServerError, # 5xx
WebSocketError, # WS handshake / framing issue
BatchPlacementError, # OrdersAPI.place_batch partial failure
)
try:
client.orders.place(...)
except RateLimitError as e:
time.sleep(e.retry_after_ms / 1000.0)
except CoinduboError:
# catch-all
raise
BatchPlacementError carries placed: List[OrderAck], failure: Exception,
and failed_index: int so callers can cancel orphaned orders if a mid-batch
order placement fails.
Configuration
client = Client(
api_key="sk_...",
base_url="https://api.coindubo.com/api/v1", # default
timeout=30.0, # per-request HTTP timeout in seconds
max_retries=3, # for transient 429 / 5xx
ws_url=None, # override the derived WS URL
ws_path="/ws", # override only the WS path
)
ws_url (when given) wins over ws_path. Both are useful for staging
deployments where the WebSocket lives at a non-default address.
Examples
See the examples/ directory in the source repo:
accumulate.py— symmetric ladder on each new marketmomentum.py— directional orders based on BTC momentumgrid.py— buy ladder + counter-sell on fillsorderbook_watch.py— live orderbook stream
Each example is < 50 lines.
Threading model
The SDK is sync-only. Concurrency is via threads:
client.http.*calls are blocking.client.stream.*uses a single background daemon thread to read from the WebSocket. User callbacks fire on that thread; do not block in them.- Multiple threads can call
client.http.*concurrently —urllib's opener is thread-safe.
Support
Bugs / questions: bot@coindubo.com
License
MIT
Project details
Release history Release notifications | RSS feed
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 coindubo-0.1.0.tar.gz.
File metadata
- Download URL: coindubo-0.1.0.tar.gz
- Upload date:
- Size: 23.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4188c425529e07321e7b7c77901ac3347b8d1a5092bf89f1de5e42163356924
|
|
| MD5 |
37cb4defa6ab48aaa3636af3bf90f231
|
|
| BLAKE2b-256 |
3937563d208440f05d2e695bb327a8663643854d3d6d7211e0fbf357a8a61fd6
|
File details
Details for the file coindubo-0.1.0-py3-none-any.whl.
File metadata
- Download URL: coindubo-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2982eed7298161bda4cd398b556e18afb5ec27b7066358e046f4b9af707f03da
|
|
| MD5 |
dfa43c1926a069280e212c8efabd8b1c
|
|
| BLAKE2b-256 |
be7c69e39c3a124251ebeb8b0e692514a25694de8463759f2af2b1578a17758d
|