Build an OpenClaw skill that scans sportsbooks and prediction markets for guaranteed-profit arbitrage. One SKILL.md file, three API sources, and your agent alerts you when the math guarantees a win.

Why Your Agent Needs an Arb Finder

Arbitrage opportunities in sports betting exist because different platforms price the same event independently. A sportsbook might offer the Yankees at +140 while Polymarket implies 40% (equivalent to +150) on the same outcome. When the combined implied probability across all outcomes drops below 100%, profit is guaranteed regardless of who wins.

The problem is speed. Arb windows close in minutes — sometimes seconds. A human manually checking DraftKings, then Polymarket, then Kalshi, then doing the math, is too slow. By the time you calculate the stake distribution, the line has moved.

This is where an autonomous agent earns its keep. The arb-finder skill teaches your OpenClaw agent to scan all three source types simultaneously, identify sub-100% implied probability combinations, compute the exact stakes for equal-profit distribution, and surface the opportunity before it disappears.

This is a Layer 3 (Trading) skill in the Agent Betting Stack. It sits directly above the odds-scanner skill and feeds into the kelly-sizer for position sizing.

What You’re Building

The arb-finder skill teaches your OpenClaw agent four operations:

  1. Scan sportsbook arbs — Find two-way and multi-way arbs within traditional bookmakers
  2. Cross-market arb scan — Compare sportsbook odds against Polymarket and Kalshi prices for the same event
  3. Calculate optimal stakes — Given an arb opportunity and total bankroll, compute exact stake per leg for equal profit
  4. List active arb windows — Show all currently open arbs sorted by profit margin

The skill uses curl, jq, and python3 (standard library only) — no pip packages, no Docker.

Prerequisites

  • OpenClaw installed and running — Any channel (WhatsApp, Telegram, Discord, WebChat)
  • odds-scanner skill installed — See the odds-scanner guide
  • The Odds API key — Free at the-odds-api.com (500 requests/month)
  • curl, jq, and python3 — Pre-installed on macOS and most Linux distributions

The Math Behind Arbitrage Detection

An arbitrage exists when the sum of implied probabilities across all outcomes is less than 1. For American odds, the implied probability formula is:

  • Negative odds (favorites): IP = |odds| / (|odds| + 100)
  • Positive odds (underdogs): IP = 100 / (odds + 100)

For a two-outcome market with best available odds of +150 and -130:

IP_away = 100 / (150 + 100) = 0.400
IP_home = 130 / (130 + 100) = 0.565
Total   = 0.965

Total < 1.0, so an arb exists. The profit margin is 1 - 0.965 = 3.5%.

Stake distribution for equal profit:

Given total bankroll B and implied probabilities IP_1, IP_2:

Stake_1 = B × (IP_1 / (IP_1 + IP_2))
Stake_2 = B × (IP_2 / (IP_1 + IP_2))
Guaranteed profit = B × (1 - (IP_1 + IP_2)) / (IP_1 + IP_2)

For B = $1000, the stakes are $414.51 and $585.49 for a guaranteed profit of $36.27 regardless of outcome.

The Complete SKILL.md

Create the skill directory:

mkdir -p ~/.openclaw/skills/arb-finder

Create ~/.openclaw/skills/arb-finder/SKILL.md with this content:

---
name: arb-finder
description: "Detect guaranteed-profit arbitrage opportunities across sportsbooks and prediction markets. Compares odds from 20+ bookmakers, Polymarket, and Kalshi. Calculates optimal stake distribution. Use when asked about arbs, arbitrage, guaranteed profit, or cross-market pricing."
metadata:
  openclaw:
    emoji: "🔀"
    requires:
      bins: ["curl", "jq", "python3"]
    credentials:
      - id: "odds-api-key"
        name: "The Odds API Key"
        description: "Free API key from https://the-odds-api.com/"
        env: "ODDS_API_KEY"
---

# Arbitrage Finder

Detect cross-market arbitrage opportunities across sportsbooks and prediction markets.

# When to Use

Use this skill when the user asks about:
- Finding arbitrage or arb opportunities
- Guaranteed profit bets
- Cross-market pricing discrepancies
- Comparing sportsbook odds vs prediction market prices
- Calculating optimal stake distribution for an arb
- Whether a specific event has an arb available

# Operations

### 1. Scan Sportsbook Arbs

Scan a sport for two-way moneyline arbs across bookmakers. Replace SPORT_KEY with the appropriate key (e.g., basketball_nba, americanfootball_nfl):

```bash
curl -s "https://api.the-odds-api.com/v4/sports/SPORT_KEY/odds?apiKey=$ODDS_API_KEY&regions=us&markets=h2h&oddsFormat=american" \

  | jq '[.[] | {

    game: "\(.away_team) @ \(.home_team)",
    start: .commence_time,
    away_team: .away_team,
    home_team: .home_team,
    best_away: (.bookmakers | map({book: .title, odds: ((.markets[] | select(.key=="h2h")).outcomes[] | select(.name == .away_team) | .price)}) | sort_by(-.odds) | first),
    best_home: (.bookmakers | map({book: .title, odds: ((.markets[] | select(.key=="h2h")).outcomes[] | select(.name == .home_team) | .price)}) | sort_by(-.odds) | first)
  } | . + {
    ip_away: (if .best_away.odds > 0 then 100/(.best_away.odds+100) else (-.best_away.odds)/(-.best_away.odds+100) end),
    ip_home: (if .best_home.odds > 0 then 100/(.best_home.odds+100) else (-.best_home.odds)/(-.best_home.odds+100) end)
  } | . + {
    total_ip: (.ip_away + .ip_home),
    is_arb: ((.ip_away + .ip_home) < 1)
  } | select(.is_arb == true) | {
    game, start,
    away: {team: .away_team, odds: .best_away.odds, book: .best_away.book},
    home: {team: .home_team, odds: .best_home.odds, book: .best_home.book},
    margin: ((1 - .total_ip) * 100 | . * 100 | round / 100 | tostring + "%")
  }]'
```

### 2. Cross-Market Arb Scan — Sportsbooks vs Polymarket

Compare sportsbook moneylines against Polymarket event prices. First fetch Polymarket events, then compare:

Fetch Polymarket active sports/politics events:

```bash
curl -s "https://gamma-api.polymarket.com/events?closed=false&limit=50&order=volume24hr&ascending=false" \

  | jq '[.[] | {

    id: .id,
    title: .title,
    markets: [.markets[] | {
      question: .question,
      outcomes: .outcomes,
      outcomePrices: .outcomePrices,
      volume24hr: .volume24hr
    }]
  }]'
```

For a specific Polymarket market, get the current prices and convert to implied odds:

```bash
curl -s "https://gamma-api.polymarket.com/markets?id=MARKET_ID" \

  | jq '.[0] | {

    question: .question,
    outcomes: [.outcomes as $o | .outcomePrices | split(",") | to_entries[] | {
      outcome: ($o | split(",") | .[.key]),
      price: (. .value | tonumber),
      implied_pct: ((. .value | tonumber) * 100 | round | tostring + "%"),
      american_equiv: (if (.value | tonumber) >= 0.5
        then (-((.value | tonumber) / (1 - (.value | tonumber)) * 100) | round)
        else (((1 - (.value | tonumber)) / (.value | tonumber) * 100) | round)
        end)
    }]
  }'
```

To check for a cross-market arb, compare the Polymarket implied probability for one side against the sportsbook odds for the other side. If the sum of the best available implied probabilities across platforms is below 100%, an arb exists.

### 3. Scan Kalshi Event Contracts

Fetch Kalshi markets for comparison:

```bash
curl -s "https://api.elections.kalshi.com/trade-api/v2/events?status=open&limit=50&with_nested_markets=true" \

  | jq '[.events[] | {

    title: .title,
    category: .category,
    markets: [.markets[]? | {
      ticker: .ticker,
      title: .title,
      yes_price: .yes_ask,
      no_price: .no_ask,
      volume: .volume,
      yes_implied: ((.yes_ask // 0) * 100 | round | tostring + "%"),
      no_implied: ((.no_ask // 0) * 100 | round | tostring + "%")
    }]
  }]'
```

Kalshi contract prices are already probabilities (e.g., $0.65 = 65% implied). Convert to American odds for comparison:

```bash
python3 -c "
price = 0.65  # Replace with actual Kalshi contract price
if price >= 0.5:
    american = -(price / (1 - price)) * 100
else:
    american = ((1 - price) / price) * 100
print(f'Kalshi price: \${price:.2f}')
print(f'Implied prob: {price*100:.1f}%')
print(f'American odds: {american:+.0f}')
"
```

### 4. Calculate Optimal Stake Distribution

Given an arb opportunity, calculate exact stakes for equal profit across all legs:

```bash
python3 -c "
import sys, json

## Input: best odds per outcome and total bankroll
odds_1 = 150    # American odds for outcome 1 (e.g., +150)
odds_2 = -130   # American odds for outcome 2 (e.g., -130)
bankroll = 1000  # Total amount to deploy

## Convert American odds to implied probability
def american_to_ip(odds):
    if odds > 0:
        return 100 / (odds + 100)
    else:
        return abs(odds) / (abs(odds) + 100)

## Convert American odds to decimal
def american_to_decimal(odds):
    if odds > 0:
        return (odds / 100) + 1
    else:
        return (100 / abs(odds)) + 1

ip1 = american_to_ip(odds_1)
ip2 = american_to_ip(odds_2)
total_ip = ip1 + ip2

if total_ip >= 1:
    print('NO ARB: Total implied probability >= 100%')
    print(f'Total IP: {total_ip*100:.2f}%')
    sys.exit(0)

dec1 = american_to_decimal(odds_1)
dec2 = american_to_decimal(odds_2)

## Equal-profit stake distribution
stake1 = bankroll / (1 + dec1 / dec2)
stake2 = bankroll - stake1

payout1 = stake1 * dec1
payout2 = stake2 * dec2
profit = payout1 - bankroll

margin = (1 - total_ip) * 100

print(f'=== ARB FOUND ===')
print(f'Margin: {margin:.2f}%')
print(f'Outcome 1: odds {odds_1:+d} → stake \${stake1:.2f} → payout \${payout1:.2f}')
print(f'Outcome 2: odds {odds_2:+d} → stake \${stake2:.2f} → payout \${payout2:.2f}')
print(f'Total staked: \${bankroll:.2f}')
print(f'Guaranteed profit: \${profit:.2f} ({profit/bankroll*100:.2f}%)')
"
```

Replace the `odds_1`, `odds_2`, and `bankroll` values with the actual arb opportunity found in Operations 1-3. For three-way markets (e.g., soccer), extend the calculation to three outcomes.

# Output Rules

1. Always show the event, both sides, and which platform/book has the best price per side
2. Display the arb margin as a percentage (e.g., "3.5% margin")
3. For stake calculations, show exact dollar amounts and guaranteed profit
4. Sort arb opportunities by margin (highest first)
5. If no arbs are found, report the closest near-arb (lowest total implied probability)
6. Always note that arb windows are time-sensitive and lines may have moved
7. Report remaining Odds API quota after sportsbook scans

# Error Handling

- If ODDS_API_KEY is not set, tell the user to get a free key at https://the-odds-api.com/
- If Polymarket API returns empty, the event may not be listed on Polymarket
- If Kalshi API returns empty, check that the event category is available on Kalshi
- If no arbs found, report the tightest market (lowest combined IP) as a near-arb
- If rate limited on any API, report which source hit the limit and suggest waiting

Set Your API Key

export ODDS_API_KEY=your_key_here

Polymarket’s Gamma API and Kalshi’s public market data endpoint require no authentication for read-only queries.

Test It

Restart OpenClaw (or wait for hot-reload), then try these prompts:

PromptExpected Behavior
“Find arbs in NBA”Scans all NBA moneylines across sportsbooks for sub-100% implied probability combinations
“Any cross-market arbitrage on Polymarket vs books?”Compares Polymarket event prices against sportsbook odds for matching events
“Calculate arb stakes: +150 and -130, $1000 bankroll”Outputs exact stake per leg and guaranteed profit
“Arbitrage opportunities right now”Scans all active sports for sportsbook arbs, then checks prediction markets
“Is there an arb on the Super Bowl?”Checks NFL championship odds across all three source types

How It Works Under the Hood

When you ask “find arbs in NBA,” the execution flow is:

User message → OpenClaw Gateway
  → LLM reads system prompt + active skills
  → LLM matches "find arbs" to arb-finder skill
  → LLM runs Operation 1: curl + jq pipeline against The Odds API
  → jq filters compute implied probability per outcome per bookmaker
  → jq selects combinations where total IP < 1.0
  → If arbs found: LLM runs Operation 4 to calculate stakes
  → LLM formats output: event, books, odds, margin, recommended stakes

For cross-market scans, the agent runs Operations 1, 2, and 3 in sequence, then manually compares events that appear on multiple platforms. The agent matches events by team names and dates — this is where LLM reasoning adds value over a static script, since event naming differs across platforms.

Extending the Skill

Add Cron-Based Arb Alerts

Set up a recurring scan that alerts you when an arb appears above a configurable margin threshold:

{
  "cron": "*/15 * * * *",
  "prompt": "Scan NBA and NFL for arbs. If any opportunity has a margin above 1.5%, alert me on Telegram with the game, books, odds, and recommended stakes for a $500 bankroll."
}

Running every 15 minutes is aggressive — adjust based on your Odds API quota. At 4 scans/hour × 2 sports = 192 requests/day, this burns through a free tier in about 2.5 days. Consider a paid tier ($12/month) for production arb scanning.

Chain with Other Skills

The arb-finder is most powerful when composed with other Agent Betting Stack skills:

  • odds-scanner — Provides the raw sportsbook data that arb-finder consumes. Install this first.
  • odds-converter — Normalizes odds formats when comparing American (sportsbooks) vs implied probability (Polymarket) vs contract price (Kalshi)
  • kelly-sizer — Once an arb is confirmed, Kelly can optimize position sizing beyond equal-profit distribution
  • bankroll-manager — Logs arb bets and tracks P&L across platforms, enforces max exposure limits
  • clv-tracker — Validates that your arb entries were genuinely profitable by comparing to closing lines

Near-Arb Monitoring

Not every scan produces a pure arb. Configure your agent to track near-arbs (total IP between 100% and 101%) — these often convert to true arbs as lines move closer to game time.

Full Skill Series

This guide is part of the AgentBets OpenClaw Skills series. We’re building a complete library of betting-specific OpenClaw skills that map to the four layers of the Agent Betting Stack:

  • Layer 1 — Identity: Agent reputation tracking via Moltbook
  • Layer 2 — Wallet: Bankroll management, balance checking across platforms
  • Layer 3 — Trading: Odds scanning, Polymarket monitoring, Kalshi tracking, arbitrage detection (this guide)
  • Layer 4 — Intelligence: EV calculation, Kelly sizing, CLV tracking, news sentiment

Each skill is a standalone SKILL.md you can install independently or compose into a full autonomous betting pipeline.

What’s Next