Polymarket NegRisk Arbitrage
by @r2crypto
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...
clawhub install polymarket-negrisk-arbπ About This Skill
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
Setup
pip install simmer-sdk
export SIMMER_API_KEY="your-key-here"
Quick Start
# Scan for opportunities (dry run, no trades)
python negrisk_arb.pyExecute real trades
python negrisk_arb.py --liveOnly show YES arbitrage
python negrisk_arb.py --side yesOnly show NO arbitrage
python negrisk_arb.py --side noSet minimum profit threshold
python negrisk_arb.py --min-profit 0.05JSON output
python negrisk_arb.py --jsonQuiet mode for cron
python negrisk_arb.py --live --quietShow stats
python negrisk_arb.py --statsShow config
python negrisk_arb.py --configUpdate 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:
1. Fetch active markets β GET /api/sdk/markets (all active, sorted by opportunity) 2. Group by event β Group markets sharing the same Polymarket event 3. Calculate sums β Sum YES prices and NO prices for each event group 4. Filter opportunities β Find events where sum < threshold 5. Validate edge β Check fee rates, slippage estimates, min profit after costs 6. Execute batch β POST /api/sdk/trades/batch with all buckets simultaneously 7. Track positions β Tag all trades with source: "sdk:negrisk-arb"
Safeguards
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:
Run --stats after 20+ events to see real performance vs theoretical edge.
Troubleshooting
"No arbitrage opportunities found"
min_profit_pct to 0.02"All events skipped for fees"
fee_filter=false to override (not recommended)"Batch trade partially filled"
max_position_usd to reduce market impactslippage_max_pct slightly"Sum check passed but trade rejected"
"Event has too many outcomes"
max_outcomes settingAPI 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 trackingCron / 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
π‘ Examples
# Scan for opportunities (dry run, no trades)
python negrisk_arb.pyExecute real trades
python negrisk_arb.py --liveOnly show YES arbitrage
python negrisk_arb.py --side yesOnly show NO arbitrage
python negrisk_arb.py --side noSet minimum profit threshold
python negrisk_arb.py --min-profit 0.05JSON output
python negrisk_arb.py --jsonQuiet mode for cron
python negrisk_arb.py --live --quietShow stats
python negrisk_arb.py --statsShow config
python negrisk_arb.py --configUpdate 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 |
π Tips & Best Practices
"No arbitrage opportunities found"
min_profit_pct to 0.02"All events skipped for fees"
fee_filter=false to override (not recommended)"Batch trade partially filled"
max_position_usd to reduce market impactslippage_max_pct slightly"Sum check passed but trade rejected"
"Event has too many outcomes"
max_outcomes setting