{"id":42900790,"url":"https://github.com/guzus/dr-manhattan","last_synced_at":"2026-01-30T15:33:52.826Z","repository":{"id":330071229,"uuid":"1082935528","full_name":"guzus/dr-manhattan","owner":"guzus","description":"CCXT for prediction markets · #1 Open Source for Market-making, Trading, Data Analysis on Polymarket \u0026 Kalshi \u0026 Limitless \u0026 Opinion \u0026 Predictfun \u0026 etc","archived":false,"fork":false,"pushed_at":"2026-01-25T05:35:44.000Z","size":8498,"stargazers_count":112,"open_issues_count":17,"forks_count":16,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-25T05:54:20.269Z","etag":null,"topics":["arbitrage","kalshi","limitless","market-making","opinion","polymarket","prediction-markets"],"latest_commit_sha":null,"homepage":"https://drmanhattan.xyz","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/guzus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-25T02:52:48.000Z","updated_at":"2026-01-25T05:50:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/guzus/dr-manhattan","commit_stats":null,"previous_names":["guzus/dr-manhattan"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/guzus/dr-manhattan","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guzus%2Fdr-manhattan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guzus%2Fdr-manhattan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guzus%2Fdr-manhattan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guzus%2Fdr-manhattan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guzus","download_url":"https://codeload.github.com/guzus/dr-manhattan/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guzus%2Fdr-manhattan/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28914906,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T12:13:43.263Z","status":"ssl_error","status_checked_at":"2026-01-30T12:13:22.389Z","response_time":66,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arbitrage","kalshi","limitless","market-making","opinion","polymarket","prediction-markets"],"created_at":"2026-01-30T15:33:51.652Z","updated_at":"2026-01-30T15:33:52.819Z","avatar_url":"https://github.com/guzus.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dr-manhattan\n\nCCXT-style unified API for prediction markets. Simple, scalable, and easy to extend.\n\n[![](https://deepwiki.com/badge.svg)](https://deepwiki.com/guzus/dr-manhattan)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/polymarket.png\" alt=\"Polymarket\" width=\"50\"/\u003e\n  \u003cimg src=\"assets/kalshi.jpeg\" alt=\"Kalshi\" width=\"50\"/\u003e\n  \u003cimg src=\"assets/opinion.jpg\" alt=\"Opinion\" width=\"50\"/\u003e\n  \u003cimg src=\"assets/limitless.jpg\" alt=\"Limitless\" width=\"50\"/\u003e\n  \u003cimg src=\"assets/predict_fun.jpg\" alt=\"Predict.fun\" width=\"50\"/\u003e\n\u003c/p\u003e\n\n## Architecture\n\n`dr-manhattan` provides a unified interface to interact with multiple prediction market platforms, similar to how CCXT works for cryptocurrency exchanges.\n\n### Core Components\n\n```\ndr_manhattan/\n├── base/               # Core abstractions\n│   ├── exchange.py     # Abstract base class for exchanges\n│   ├── exchange_client.py  # High-level trading client\n│   ├── exchange_factory.py # Exchange instantiation\n│   ├── strategy.py     # Strategy base class\n│   ├── order_tracker.py    # Order event tracking\n│   ├── websocket.py    # WebSocket base class\n│   └── errors.py       # Exception hierarchy\n├── exchanges/          # Exchange implementations\n│   ├── polymarket.py\n│   ├── polymarket_ws.py\n│   ├── opinion.py\n│   ├── limitless.py\n│   ├── limitless_ws.py\n│   └── predictfun.py\n├── models/             # Data models\n│   ├── market.py\n│   ├── order.py\n│   ├── orderbook.py\n│   └── position.py\n├── strategies/         # Strategy implementations\n└── utils/              # Utilities\n```\n\n### Design Principles\n\n1. **Unified Interface**: All exchanges implement the same `Exchange` base class\n2. **Scalability**: Adding new exchanges is straightforward - just implement the abstract methods\n3. **Simplicity**: Clean abstractions with minimal dependencies\n4. **Type Safety**: Full type hints throughout\n\n### Key Features\n\n- Fetch markets and market data\n- Create and cancel orders\n- Query positions and balances\n- WebSocket support for real-time data\n- Strategy base class for building trading strategies\n- Order tracking and event logging\n- Standardized error handling\n- Exchange-agnostic code\n- **MCP server for Claude Desktop integration**\n\n## Installation\n\n```bash\nuv venv\nuv pip install -e .\n```\n\n## Usage\n\n### Basic Usage (Public API)\n\n```python\nimport dr_manhattan\n\n# Initialize exchange without authentication\npolymarket = dr_manhattan.Polymarket({'timeout': 30})\nopinion = dr_manhattan.Opinion({'timeout': 30})\nlimitless = dr_manhattan.Limitless({'timeout': 30})\npredictfun = dr_manhattan.PredictFun({'timeout': 30})\n\n# Fetch markets\nmarkets = polymarket.fetch_markets()\nfor market in markets:\n    print(f\"{market.question}: {market.prices}\")\n```\n\n### Advanced Usage (With Authentication)\n\n```python\nimport dr_manhattan\n\n# Polymarket\npolymarket = dr_manhattan.Polymarket({\n    'private_key': 'your_private_key',\n    'funder': 'your_funder_address',\n})\n\n# Opinion (BNB Chain)\nopinion = dr_manhattan.Opinion({\n    'api_key': 'your_api_key',\n    'private_key': 'your_private_key',\n    'multi_sig_addr': 'your_multi_sig_addr'\n})\n\n# Limitless\nlimitless = dr_manhattan.Limitless({\n    'private_key': 'your_private_key',\n    'timeout': 30\n})\n\n# Predict.fun (BNB Chain)\npredictfun = dr_manhattan.PredictFun({\n    'api_key': 'your_api_key',\n    'private_key': 'your_private_key',\n    'use_smart_wallet': True,\n    'smart_wallet_owner_private_key': 'your_owner_private_key',\n    'smart_wallet_address': 'your_smart_wallet_address'\n})\n\n# Create order\norder = polymarket.create_order(\n    market_id=\"market_123\",\n    outcome=\"Yes\",\n    side=dr_manhattan.OrderSide.BUY,\n    price=0.65,\n    size=100,\n    params={'token_id': 'token_id'}\n)\n\n# Fetch balance\nbalance = polymarket.fetch_balance()\nprint(f\"USDC: {balance['USDC']}\")\n```\n\n### Using the Strategy Base Class\n\n```python\nfrom dr_manhattan import Strategy\n\nclass MyStrategy(Strategy):\n    def on_tick(self):\n        self.log_status()\n        self.place_bbo_orders()\n\nstrategy = MyStrategy(exchange, market_id=\"123\")\nstrategy.run()\n```\n\n### Exchange Factory\n\n```python\nfrom dr_manhattan import create_exchange, list_exchanges\n\n# List available exchanges\nprint(list_exchanges())  # ['polymarket', 'limitless', 'opinion', 'predictfun']\n\n# Create exchange by name\nexchange = create_exchange('polymarket', {'timeout': 30})\n```\n\n### MCP Server\n\nTrade prediction markets directly from Claude using the Model Context Protocol (MCP).\n\n```bash\n# Install with MCP dependencies\nuv sync --extra mcp\n\n# Configure credentials\ncp .env.example .env\n# Edit .env with your POLYMARKET_PRIVATE_KEY and POLYMARKET_FUNDER\n```\n\n#### Claude Code\n\nAdd to `~/.claude/settings.json` or project `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"dr-manhattan\": {\n      \"command\": \"/path/to/dr-manhattan/.venv/bin/python\",\n      \"args\": [\"-m\", \"dr_manhattan.mcp.server\"],\n      \"cwd\": \"/path/to/dr-manhattan\"\n    }\n  }\n}\n```\n\nRestart Claude Code and verify with `/mcp`.\n\n#### Claude Desktop\n\nAdd to Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):\n\n```json\n{\n  \"mcpServers\": {\n    \"dr-manhattan\": {\n      \"command\": \"/path/to/dr-manhattan/.venv/bin/python\",\n      \"args\": [\"-m\", \"dr_manhattan.mcp.server\"],\n      \"cwd\": \"/path/to/dr-manhattan\"\n    }\n  }\n}\n```\n\nAfter restarting, you can:\n- \"Show my Polymarket balance\"\n- \"Find active prediction markets\"\n- \"Buy 10 USDC of Yes on market X at 0.55\"\n\nSee [examples/mcp_usage_example.md](examples/mcp_usage_example.md) for the complete setup guide.\n\n## Adding New Exchanges\n\nTo add a new exchange, create a class that inherits from `Exchange`:\n\n```python\nfrom dr_manhattan.base import Exchange\n\nclass NewExchange(Exchange):\n    @property\n    def id(self) -\u003e str:\n        return \"newexchange\"\n\n    @property\n    def name(self) -\u003e str:\n        return \"New Exchange\"\n\n    def fetch_markets(self, params=None):\n        # Implement API call\n        pass\n\n    # Implement other abstract methods...\n```\n\nRegister in `dr_manhattan/__init__.py`:\n\n```python\nfrom .exchanges.newexchange import NewExchange\n\nexchanges = {\n    \"polymarket\": Polymarket,\n    \"opinion\": Opinion,\n    \"limitless\": Limitless,\n    \"predictfun\": PredictFun,\n    \"newexchange\": NewExchange,\n}\n```\n\n## Data Models\n\n### Market\n- Question and outcomes\n- Prices and volume\n- Close time and status\n\n### Order\n- Market and outcome\n- Side (buy/sell), price, size\n- Status tracking\n\n### Position\n- Current holdings\n- PnL calculation\n- Average entry price\n\n### OrderBook\n- Bids and asks\n- Best bid/ask prices\n\n## Error Handling\n\nAll errors inherit from `DrManhattanError`:\n- `ExchangeError` - Exchange-specific errors\n- `NetworkError` - Connectivity issues\n- `RateLimitError` - Rate limit exceeded\n- `AuthenticationError` - Auth failures\n- `InsufficientFunds` - Not enough balance\n- `InvalidOrder` - Invalid order parameters\n- `MarketNotFound` - Market doesn't exist\n\n## Examples\n\nCheck out the [examples/](examples/) directory for working examples:\n\n- **mcp_usage_example.md** - Complete MCP server setup and usage guide for Claude Desktop\n- **list_all_markets.py** - List markets from any exchange\n- **spread_strategy.py** - Exchange-agnostic BBO market making strategy\n\nRun examples:\n\n```bash\n# List markets\nuv run python examples/list_all_markets.py polymarket\nuv run python examples/list_all_markets.py opinion\nuv run python examples/list_all_markets.py limitless\nuv run python examples/list_all_markets.py predictfun\n\n# Run spread strategy\nuv run python examples/spread_strategy.py --exchange polymarket --slug fed-decision\nuv run python examples/spread_strategy.py --exchange opinion --market-id 813\n```\n\nSee [examples/README.md](examples/README.md) for detailed documentation.\n\n## Contributing with Claude\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/claude.png\" alt=\"Claude\" width=\"100\"/\u003e\n\u003c/p\u003e\n\nWe use Claude Code to implement new features from trading strategy ideas:\n\n1. Spot a good strategy on Twitter/X\n2. Create a GitHub issue describing the strategy\n3. Add a label: `feature`, `bug`, or `chore`\n4. Mention `@claude` in the issue\n5. Claude creates a PR with the implementation\n\nBranch naming follows the label:\n- `feature` -\u003e `feat/issue-{number}`\n- `bug` -\u003e `fix/issue-{number}`\n- `chore` -\u003e `chore/issue-{number}`\n\nSee [.github/workflows/claude.yml](.github/workflows/claude.yml) for details.\n\n## Dependencies\n\n- Python \u003e= 3.11\n- requests \u003e= 2.31.0\n- websockets \u003e= 15.0.1\n- python-socketio \u003e= 5.11.0\n- eth-account \u003e= 0.11.0\n- py-clob-client \u003e= 0.28.0\n- opinion-clob-sdk \u003e= 0.4.3\n- pandas \u003e= 2.0.0\n\nDevelopment:\n- pytest\n- black\n- ruff\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguzus%2Fdr-manhattan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguzus%2Fdr-manhattan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguzus%2Fdr-manhattan/lists"}