polly-gamba
v1.0.10
Published
Coinbase price signal → Claude brain → Polymarket CLOB execution
Readme
polly-gamba
Signal propagation arbitrage: Coinbase price move → Polymarket bet, before the humans do.
┌─────────────────┐ signal ┌───────────────────┐ match ┌──────────────────┐
│ Coinbase WS │ ──────────→ │ Signal Router │ ─────────→ │ Polymarket CLOB │
│ BTC/ETH ticker │ │ (Claude brain) │ │ Order execution │
└─────────────────┘ └───────────────────┘ └──────────────────┘
↑ ↑ ↑
0.5% move in keyword + heuristic dry-run by default
60s window market matching (set API key for live)Why this works
Human reaction time from seeing a BTC pump on Coinbase to placing a Polymarket bet: 5–30 minutes.
That's the edge. We don't front-run algos — we front-run people. Crypto price signal → find correlated prediction markets → place before the crowd arrives.
News doesn't matter. Price signal does.
Architecture
| Component | File | Purpose |
|---|---|---|
| Coinbase WS | src/signals/coinbase-ws.ts | Real-time BTC/ETH ticker, threshold detection |
| Gamma API | src/markets/gamma.ts | Fetch active Polymarket markets, 10-min cache |
| CLOB API | src/markets/clob.ts | Orderbook reads, price queries, order placement |
| MCP Server | src/mcp/server.ts | Polymarket tools for Claude Code integration |
| Main loop | src/index.ts | Orchestration, latency tracking, dry-run |
Quick start
npm install
# Run the signal → match → execute pipeline (dry-run mode)
npx ts-node src/index.ts
# Run as MCP server (for Claude Code)
npx ts-node src/mcp/server.ts
# Run smoke tests
npm testSignal detection
coinbase-ws.ts connects to Coinbase Advanced Trade WebSocket (no auth required):
- Subscribes to
tickerchannel forBTC-USDandETH-USD - Maintains a 60-second rolling price window
- Fires a
PriceSignalwhen price moves ≥ 0.5% within the window
interface PriceSignal {
asset: 'BTC' | 'ETH'
direction: 'up' | 'down'
pct_change: number // e.g. 0.0213 for +2.13%
price: number // current USD price
window_secs: number // actual window duration
signal_ts: number // Date.now() at detection
}Market matching
On signal, the system:
- Fetches active Polymarket markets (Gamma API, cached 10 min)
- Filters for volume > $10k, liquidity > $1k
- Keyword-matches market questions against the signal asset
- Logs matched markets + latency breakdown
MCP Tools (Claude integration)
Add to ~/.claude/claude_desktop_config.json:
{
"mcpServers": {
"polymarket": {
"command": "npx",
"args": ["ts-node", "/path/to/polly-gamba/src/mcp/server.ts"]
}
}
}Available tools:
list_markets— fetch active markets with optional keyword filterget_orderbook— CLOB orderbook for a tokenget_market_price— buy/sell price (0–1 = probability)assess_signal— find markets affected by a price signalplace_order— place order (dry-run default)
Latency tracking
Every signal logs:
signal_ts → when the price move was detected
match_ts → when market matching completed
execute_ts → when dry-run/order was loggedTarget: signal → execute in < 500ms.
Config
| Env var | Required | Description |
|---|---|---|
| POLYMARKET_API_KEY | No (for now) | CLOB API key for live order placement |
Dry-run mode
All order placement is dry-run by default — logs WOULD PLACE ORDER: ... without touching the CLOB. Set dry_run: false and POLYMARKET_API_KEY for live execution.
Next steps
- CLOB auth — implement EIP-712 L1 + L2 API key header signing
- Position sizing — Kelly criterion on signal strength × market liquidity
- Redis signal bus — decouple signal detection from execution
- Backtesting — replay historical Coinbase ticks against historical Polymarket prices
- Claude reasoning — pipe signals through Claude for semantic market scoring
Build
npm run build # tsc → dist/
npm test # smoke tests (live API, read-only)