Polymarket NegRisk Arbitrage
Scan multi-outcome Polymarket markets for mathematical arbitrage. When the sum of all outcome prices falls below $1.00, buy all sides simultaneously via batc...
Description
name: polymarket-negrisk-arb description: Scan multi-outcome Polymarket markets for mathematical arbitrage. When the sum of all outcome prices falls below $1.00, buy all sides simultaneously via batch trade to lock in risk-free profit. No signals. No AI. Just math. metadata: author: "r2creatorstudios" version: "1.0.2" displayName: "Polymarket NegRisk Arbitrage" difficulty: "intermediate"
Polymarket NegRisk Arbitrage Trader
This is a template. The default signal is NegRisk price sum deviation from $1.00 — remix it with tighter thresholds, different min-profit floors, or additional liquidity filters. The skill handles all the plumbing (market discovery, grouping, batch execution, safeguards). Your agent provides the edge by tuning when and how aggressively to enter.
Scan multi-outcome markets for mathematical arbitrage opportunities. When the sum of all outcome prices deviates from $1.00, buy the mispriced side across all buckets simultaneously using Simmer's batch trade endpoint.
No signals. No AI. Just math.
Strategy
Polymarket NegRisk markets have multiple mutually exclusive outcomes (e.g., election candidates, tweet count ranges). Exactly one outcome resolves YES = $1.00.
The Math:
In an efficient market:
sum(all YES prices) = $1.00
sum(all NO prices) = $1.00
When markets are inefficient:
sum(YES) < $0.95 → Buy ALL YES → guaranteed $1.00 payout, cost < $0.95 → profit
sum(NO) < $0.95 → Buy ALL NO → guaranteed $1.00 payout, cost < $0.95 → profit
Example:
Election market — 4 candidates:
Candidate A: YES = $0.45
Candidate B: YES = $0.22
Candidate C: YES = $0.18
Candidate D: YES = $0.08
Sum = $0.93 (< $0.95 threshold)
→ Buy ALL YES for $0.93 total
→ One candidate wins → collect $1.00
→ Profit: $0.07 (7.5% return, risk-free)
When to Use This Skill
- Multi-outcome Polymarket events (elections, tweet counts, sports brackets)
- When market makers are slow to rebalance after news
- High-volatility periods where prices shift quickly
- Events with many outcomes (more outcomes = more pricing errors)
Setup
pip install simmer-sdk
export SIMMER_API_KEY="your-key-here"
Quick Start
# Scan for opportunities (dry run, no trades)
python negrisk_arb.py
# Execute real trades
python negrisk_arb.py --live
# Only show YES arbitrage
python negrisk_arb.py --side yes
# Only show NO arbitrage
python negrisk_arb.py --side no
# Set minimum profit threshold
python negrisk_arb.py --min-profit 0.05
# JSON output
python negrisk_arb.py --json
# Quiet mode for cron
python negrisk_arb.py --live --quiet
# Show stats
python negrisk_arb.py --stats
# Show config
python negrisk_arb.py --config
# Update config
python negrisk_arb.py --set max_position_usd=10.00
Configuration
| Setting | Env Variable | Default | Description |
|---|---|---|---|
| max_yes_sum | SIMMER_NEGRISK_MAX_YES_SUM | 0.95 | Max sum of YES prices to trigger buy |
| max_no_sum | SIMMER_NEGRISK_MAX_NO_SUM | 0.95 | Max sum of NO prices to trigger buy |
| min_profit_pct | SIMMER_NEGRISK_MIN_PROFIT | 0.03 | Min profit % after fees (3%) |
| max_position_usd | SIMMER_NEGRISK_MAX_POSITION | 10.00 | Max USD per outcome bucket |
| max_total_usd | SIMMER_NEGRISK_MAX_TOTAL | 50.00 | Max total USD per event |
| max_trades_per_run | SIMMER_NEGRISK_MAX_TRADES | 2 | Max arbitrage events per cycle |
| daily_budget | SIMMER_NEGRISK_DAILY_BUDGET | 50.00 | Daily spend limit |
| min_outcomes | SIMMER_NEGRISK_MIN_OUTCOMES | 3 | Min outcomes per event (skip binary) |
| max_outcomes | SIMMER_NEGRISK_MAX_OUTCOMES | 15 | Max outcomes (too many = illiquid) |
| slippage_max_pct | SIMMER_NEGRISK_SLIPPAGE | 0.05 | Max slippage tolerance (5%) |
| fee_filter | SIMMER_NEGRISK_FEE_FILTER | true | Skip markets with fees |
| require_simultaneous | SIMMER_NEGRISK_SIMULTANEOUS | true | Use batch trades for simultaneous execution |
How It Works
Each cycle the script:
- Fetch active markets — GET /api/sdk/markets (all active, sorted by opportunity)
- Group by event — Group markets sharing the same Polymarket event
- Calculate sums — Sum YES prices and NO prices for each event group
- Filter opportunities — Find events where sum < threshold
- Validate edge — Check fee rates, slippage estimates, min profit after costs
- Execute batch — POST /api/sdk/trades/batch with all buckets simultaneously
- Track positions — Tag all trades with source: "sdk:negrisk-arb"
Safeguards
- Fee check — Skips any event where any outcome has taker fees
- Slippage check — Estimates slippage via context API, skips if too high
- Simultaneous execution — Uses batch endpoint to minimize timing risk
- Position check — Skips events where you already hold positions
- Daily budget — Hard stop when daily limit is reached
- Min outcomes — Skips binary markets (YES + NO always = $1.00 by design)
- Liquidity check — Skips outcomes with very low volume (< $100 24h)
Fee-Accurate Profit Calculation
yes_cost = sum of all YES prices in cluster
payout = $1.00 (exactly one resolves YES)
fee_cost = sum of (price × fee_rate) for each outcome
net_profit = payout - yes_cost - fee_cost
profit_pct = net_profit / yes_cost
Only trades when profit_pct >= min_profit_pct.
Simultaneous Execution (Critical)
Standard sequential trades are risky:
Buy outcome A → price moves → Buy outcome B → sum now > $1 → no longer profitable
This skill uses Simmer's batch endpoint:
POST /api/sdk/trades/batch
{
"trades": [
{"market_id": "uuid-A", "side": "yes", "amount": 5.0},
{"market_id": "uuid-B", "side": "yes", "amount": 5.0},
{"market_id": "uuid-C", "side": "yes", "amount": 5.0}
],
"venue": "polymarket",
"source": "sdk:negrisk-arb"
}
All trades execute in parallel — minimizes timing risk.
Example Output
🔢 NegRisk Arbitrage Scanner
==================================================
⚙️ Configuration:
Max YES sum: $0.95
Max NO sum: $0.95
Min profit: 3.0%
Max position: $10.00/bucket
Daily budget: $50.00
🔍 Scanning 847 active markets...
Grouped into 203 multi-outcome events
Evaluating 203 events for arbitrage...
🎯 Opportunities Found: 2
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Event: "Who wins the 2026 German election?"
Side: YES arbitrage
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CDU/CSU: $0.38
SPD: $0.27
Greens: $0.15
AfD: $0.09
FDP: $0.04
──────────────
Sum: $0.93 (< $0.95 threshold) ✅
Profit calculation:
Cost: $0.93
Payout: $1.00
Net: +$0.07 (7.5%) ✅
Fees: $0.00 (zero-fee market) ✅
Slippage: ~1.2% (within limit) ✅
Executing batch trade...
✅ CDU/CSU YES — 13.2 shares @ $0.38
✅ SPD YES — 18.5 shares @ $0.27
✅ Greens YES — 33.3 shares @ $0.15
✅ AfD YES — 55.6 shares @ $0.09
✅ FDP YES — 125.0 shares @ $0.04
Total spent: $4.65
Expected gain: $0.35 (7.5%)
📊 Summary:
Events scanned: 203
Opportunities: 2
Trades executed: 8 (batch)
Total invested: $9.30
Expected profit: $0.70
Win Rate Tracking
The skill tracks every arbitrage in negrisk_ledger.json:
- Entry prices and total cost
- Winning outcome after resolution
- Actual profit vs expected
- Slippage impact
Run --stats after 20+ events to see real performance vs theoretical edge.
Troubleshooting
"No arbitrage opportunities found"
- Markets may be efficiently priced right now
- Try lowering
min_profit_pctto 0.02 - Check during high-volatility periods (election night, major events)
"All events skipped for fees"
- Only zero-fee markets are traded
- Set
fee_filter=falseto override (not recommended)
"Batch trade partially filled"
- Some outcomes may have thin liquidity
- Reduce
max_position_usdto reduce market impact - Increase
slippage_max_pctslightly
"Sum check passed but trade rejected"
- Prices moved between scan and execution
- Normal in fast-moving markets
- Skill will retry on next cycle
"Event has too many outcomes"
- Increase
max_outcomessetting - Or skip — very fragmented markets often have liquidity issues
API Endpoints Used
GET /api/sdk/markets— Market list with prices and divergenceGET /api/sdk/context/{market_id}— Fee rates and slippage estimatesPOST /api/sdk/trades/batch— Simultaneous multi-outcome executionGET /api/sdk/positions— Current portfolio positionsGET /api/sdk/portfolio— Balance and daily spend tracking
Cron / Automaton Setup
"automaton": {
"managed": true,
"entrypoint": "negrisk_arb.py --live --quiet",
"cron": "0 */2 * * *"
}
Runs every 2 hours. Arbitrage windows can be short — more frequent scanning catches more opportunities.
Or via OpenClaw native cron:
openclaw cron add \
--name "NegRisk Arbitrage" \
--cron "0 */2 * * *" \
--session isolated \
--message "Run NegRisk arbitrage scan: cd /path/to/skill && python negrisk_arb.py --live --quiet. Show summary." \
--announce
Important Notes
- This is mathematical arbitrage, not prediction — you don't need to know who wins
- Works best on events with 4+ outcomes (more outcomes = more pricing errors)
- Elon Tweet markets are a special case of this strategy (you're already doing it!)
- Opportunities are rare but high-confidence when found
- Always verify the batch filled completely before assuming profit is locked
Reviews (0)
No reviews yet. Be the first to review!
Comments (0)
No comments yet. Be the first to share your thoughts!