dr-manhattan
CCXT-style unified API for prediction markets. Simple, scalable, and easy to extend.
Architecture
dr-manhattan provides a unified interface to interact with multiple prediction market platforms, similar to how CCXT works for cryptocurrency exchanges.
Core Components
dr_manhattan/
├── base/ # Core abstractions
│ ├── exchange.py # Abstract base class
│ └── errors.py # Exception hierarchy
├── exchanges/ # Exchange implementations
│ ├── polymarket.py
│ └── limitless.py
├── models/ # Data models
│ ├── market.py
│ ├── order.py
│ └── position.py
└── utils/ # Utilities (future)
Design Principles
- Unified Interface: All exchanges implement the same
Exchangebase class - Scalability: Adding new exchanges is straightforward - just implement the abstract methods
- Simplicity: Clean abstractions with minimal dependencies
- Type Safety: Full type hints throughout
Key Features
- Fetch markets and market data
- Create and cancel orders
- Query positions and balances
- Standardized error handling
- Exchange-agnostic code
Installation
uv venv
uv pip install -e .
Usage
Basic Usage (Public API)
import dr_manhattan
# Initialize exchange without authentication
polymarket = dr_manhattan.Polymarket({'timeout': 30})
limitless = dr_manhattan.Limitless({'timeout': 30})
# Fetch markets
markets = polymarket.fetch_markets()
for market in markets:
print(f"{market.question}: {market.prices}")
Advanced Usage (With Authentication)
The implementations use symbolic links to integrate with existing market maker implementations:
import dr_manhattan
# Polymarket with poly-mm integration
polymarket = dr_manhattan.Polymarket({
'private_key': 'your_private_key',
'condition_id': 'condition_id',
'yes_token_id': 'yes_token',
'no_token_id': 'no_token',
'dry_run': False
})
# Limitless with limitless-mm integration
limitless = dr_manhattan.Limitless({
'private_key': 'your_private_key',
'timeout': 30
})
# Create order
order = polymarket.create_order(
market_id="market_123",
outcome="Yes",
side=dr_manhattan.OrderSide.BUY,
price=0.65,
size=100,
params={'token_id': 'token_id'}
)
# Fetch balance
balance = polymarket.fetch_balance()
print(f"USDC: {balance['USDC']}")
Unified API Pattern
import dr_manhattan
# Works with any exchange
for exchange_id in dr_manhattan.exchanges:
exchange = dr_manhattan.exchanges[exchange_id]()
print(f"{exchange.name}: {exchange.id}")
Adding New Exchanges
To add a new exchange, create a class that inherits from Exchange:
from dr_manhattan.base import Exchange
class NewExchange(Exchange):
@property
def id(self) -> str:
return "newexchange"
@property
def name(self) -> str:
return "New Exchange"
def fetch_markets(self, params=None):
# Implement API call
pass
# Implement other abstract methods...
Register in dr_manhattan/__init__.py:
from .exchanges.newexchange import NewExchange
exchanges = {
"polymarket": Polymarket,
"limitless": Limitless,
"newexchange": NewExchange,
}
Using Symbolic Links
The implementations leverage existing market maker codebases through symbolic links:
- poly-mm: Full Polymarket market maker implementation
- limitless-mm: Full Limitless market maker implementation
When initialized with authentication credentials, the exchange classes use these implementations directly, providing access to production-ready trading functionality.
Data Models
Market
- Question and outcomes
- Prices and volume
- Close time and status
Order
- Market and outcome
- Side (buy/sell), price, size
- Status tracking
Position
- Current holdings
- PnL calculation
- Average entry price
Error Handling
All errors inherit from DrManhattanError:
ExchangeError- Exchange-specific errorsNetworkError- Connectivity issuesAuthenticationError- Auth failuresInvalidOrder- Invalid order parametersMarketNotFound- Market doesn't exist
Examples
Check out the examples/ directory for working examples:
- spread_strategy.py - Arbitrage trading strategy for binary markets
- simple_test.py - Basic market data fetching
- test_strategy.py - Strategy testing framework
Run an example:
uv run python examples/spread_strategy.py
See examples/README.md for detailed documentation.
Dependencies
- Python >= 3.10
- requests >= 2.31.0
Development:
- pytest
- black
- ruff
Metadata
Release files for dr-manhattan 0.0.1
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 | |
|---|---|---|---|---|
| dr_manhattan-0.0.1.tar.gz | 216.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dr_manhattan-0.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 264.0 kB
Release files / dr_manhattan-0.0.1.tar.gz
| Download URL | dr_manhattan-0.0.1.tar.gz |
|---|---|
| Size | 216.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c3ee4b3c11cf43038fe29212fcc9689fa517adf961e503a0877f6ff293528422
|
|
BLAKE2b-256 checksum How to use checksums |
b6369035e637e6706f12b4b79cb43fb91965cdd0933c337634716d72c0d6afd5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / dr_manhattan-0.0.1-py3-none-any.whl
| Download URL | dr_manhattan-0.0.1-py3-none-any.whl |
|---|---|
| Size | 47.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d32b942f5fbb70f3b906c66f9a899e620744d7c9591e207e2fc441f3ab0b34d8
|
|
BLAKE2b-256 checksum How to use checksums |
e12ef3593e80215f994623c1f24b6aeaf25ad01ff8b602f15ed53e0079eea264
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Security for dr-manhattan 0.0.1
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.