Betting Analysis
Before writing queries, consult references/api-reference.md for odds formats, command parameters, and key concepts.
Quick Start
sports-skills betting convert_odds --odds=-150 --from_format=american
sports-skills betting devig --odds=-150,+130 --format=american
sports-skills betting find_edge --fair_prob=0.58 --market_prob=0.52
sports-skills betting evaluate_bet --book_odds=-150,+130 --market_prob=0.52
sports-skills betting find_arbitrage --market_probs=0.48,0.49
sports-skills betting parlay_analysis --legs=0.58,0.62,0.55 --parlay_odds=600
sports-skills betting line_movement --open_odds=-140 --close_odds=-160
Python SDK:
from sports_skills import betting
betting.convert_odds(odds=-150, from_format="american")
betting.devig(odds="-150,+130", format="american")
betting.find_edge(fair_prob=0.58, market_prob=0.52)
betting.find_arbitrage(market_probs="0.48,0.49")
betting.parlay_analysis(legs="0.58,0.62,0.55", parlay_odds=600)
betting.line_movement(open_odds=-140, close_odds=-160)
CRITICAL: Before Any Analysis
CRITICAL: Before calling any analysis command, verify:
- Odds format is correctly identified (american, decimal, or probability).
- ESPN odds are de-vigged with
devig before computing edge vs prediction market prices.
- This module computes — it does not fetch. Obtain odds from sport-specific skills or polymarket/kalshi first.
Workflows
Compare ESPN vs Polymarket/Kalshi
- Get ESPN moneyline odds (e.g., from
nba get_scoreboard): Home: -150, Away: +130
- Get Polymarket/Kalshi price for the same outcome (e.g., home at
0.52)
- De-vig:
devig --odds=-150,+130 --format=american → Fair: Home 57.9%, Away 42.1%
- Compare:
find_edge --fair_prob=0.579 --market_prob=0.52 → Edge: 5.9%, EV: 11.3%
- Or all in one step:
evaluate_bet --book_odds=-150,+130 --market_prob=0.52
Arbitrage Detection
- Get best price per outcome from different sources (Polymarket home at 0.48, Kalshi away at 0.49)
find_arbitrage --market_probs=0.48,0.49 --labels=home,away
- Total implied 0.97 (< 1.0) → arbitrage found, guaranteed ROI: 3.09%
Parlay Evaluation
- De-vig each leg: Leg 1 → 0.58, Leg 2 → 0.55, Leg 3 → 0.50
parlay_analysis --legs=0.58,0.55,0.50 --parlay_odds=600
- Returns combined fair probability, edge, and Kelly fraction
Line Movement Analysis
- Get ESPN open and close lines: Open -140, Close -160
line_movement --open_odds=-140 --close_odds=-160
- Returns probability shift, direction, and classification (sharp_action, steam_move, etc.)
Examples
Example 1: Edge check using ESPN and Polymarket prices
User says: "Is there edge on the Lakers game? ESPN has them at -150 and Polymarket has them at 52 cents"
Actions:
- Call
devig(odds="-150,+130", format="american") → fair home probability ~58%
- Call
find_edge(fair_prob=0.58, market_prob=0.52) → edge ~6%, positive EV
- Call
kelly_criterion(fair_prob=0.58, market_prob=0.52) → optimal bet fraction
Result: Present edge percentage, EV per dollar, and recommended bet size as % of bankroll
Example 2: Arbitrage opportunity detection
User says: "Can I arb this? Polymarket has home at 48 cents and Kalshi has away at 49 cents"
Actions:
- Call
find_arbitrage(market_probs="0.48,0.49", labels="home,away")
- Check
arbitrage_found in result
Result: If arbitrage: present allocation percentages and guaranteed ROI. If not: present overround and explain no guaranteed profit
Example 3: Parlay evaluation
User says: "Is this 3-leg parlay at +600 worth it?"
Actions:
- De-vig each leg to get fair probabilities (e.g., 0.58, 0.62, 0.55)
- Call
parlay_analysis(legs="0.58,0.62,0.55", parlay_odds=600)
Result: Present combined fair probability, edge, EV, +EV or -EV verdict, and Kelly fraction
Example 4: Line movement interpretation
User says: "The line moved from -140 to -160, what does that mean?"
Actions:
- Call
line_movement(open_odds=-140, close_odds=-160)
Result: Present probability shift, direction, magnitude, and classification (sharp action, steam move, etc.)
Example 5: De-vig a standard spread
User says: "What are the true odds for this spread? Both sides are -110"
Actions:
- Call
devig(odds="-110,-110", format="american")
Result: Present each side as 50% fair probability, vig is ~4.5%
Example 6: Odds format conversion
User says: "Convert -200 to implied probability"
Actions:
- Call
convert_odds(odds=-200, from_format="american")
Result: Present 66.7% implied probability and 1.50 decimal odds
Commands that DO NOT exist — never call these
get_odds — does not exist. This module analyzes odds; it does not fetch them. Use nba-data/nfl-data/etc. for ESPN odds, or polymarket/kalshi for prediction market prices.
calculate_ev — does not exist. Use find_edge or evaluate_bet instead.
compare_markets — does not exist. Use the markets skill for cross-platform comparison.
If a command is not listed in references/api-reference.md, it does not exist.
Troubleshooting
Error: ValueError: unknown format when calling convert_odds
Cause: The from_format parameter is not one of american, decimal, or probability
Solution: Use exactly american, decimal, or probability as the format string
Error: find_edge returns negative EV when a positive edge is expected
Cause: Fair probability and market probability may be reversed, or de-vigging was skipped
Solution: Run devig on sportsbook odds first, then pass the de-vigged fair_prob to find_edge
Error: find_arbitrage shows no arbitrage even when prices seem low
Cause: Prices may sum to more than 1.0 when all outcomes are correctly included
Solution: Verify you are using the correct probabilities for all outcomes; check total_implied in the result
Error: Kelly fraction is very high (greater than 0.5)
Cause: Edge estimate is very large — often from a miscalculated fair probability
Solution: Use half-Kelly or quarter-Kelly for conservative sizing. Re-verify fair probability via devig
1---2name: betting3description: Betting analysis — odds conversion, de-vigging, edge detection, Kelly criterion, arbitrage detection, parlay analysis, and line movement. Pure computation, no API calls. Works with odds from any source: ESPN (American odds), Polymarket (decimal probabilities), Kalshi (integer probabilities). Use when: user asks about bet sizing, expected value, edge analysis, Kelly criterion, arbitrage, parlays, line movement, odds conversion, or comparing odds across sources. Also use when you have odds from ESPN and a prediction market price and want to evaluate whether a bet has positive expected value. Don't use when: user asks for live odds or market data — use polymarket, kalshi, or the sport-specific skill to fetch odds first, then use this skill to analyze them.4license: MIT5---6
7# Betting Analysis
8
9Before writing queries, consult `references/api-reference.md` for odds formats, command parameters, and key concepts.
10
11## Quick Start
12
13```bash
14sports-skills betting convert_odds --odds=-150 --from_format=american
15sports-skills betting devig --odds=-150,+130 --format=american
16sports-skills betting find_edge --fair_prob=0.58 --market_prob=0.52
17sports-skills betting evaluate_bet --book_odds=-150,+130 --market_prob=0.52
18sports-skills betting find_arbitrage --market_probs=0.48,0.49
19sports-skills betting parlay_analysis --legs=0.58,0.62,0.55 --parlay_odds=600
20sports-skills betting line_movement --open_odds=-140 --close_odds=-160
21```
22
23Python SDK:
24```python
25from sports_skills import betting
26
27betting.convert_odds(odds=-150, from_format="american")
28betting.devig(odds="-150,+130", format="american")
29betting.find_edge(fair_prob=0.58, market_prob=0.52)
30betting.find_arbitrage(market_probs="0.48,0.49")
31betting.parlay_analysis(legs="0.58,0.62,0.55", parlay_odds=600)
32betting.line_movement(open_odds=-140, close_odds=-160)
33```
34
35## CRITICAL: Before Any Analysis
36
37CRITICAL: Before calling any analysis command, verify:
38- Odds format is correctly identified (american, decimal, or probability).
39- ESPN odds are de-vigged with `devig` before computing edge vs prediction market prices.
40- This module computes — it does not fetch. Obtain odds from sport-specific skills or polymarket/kalshi first.
41
42## Workflows
43
44### Compare ESPN vs Polymarket/Kalshi
45
461. Get ESPN moneyline odds (e.g., from `nba get_scoreboard`): Home: `-150`, Away: `+130`
472. Get Polymarket/Kalshi price for the same outcome (e.g., home at `0.52`)
483. De-vig: `devig --odds=-150,+130 --format=american` → Fair: Home 57.9%, Away 42.1%
494. Compare: `find_edge --fair_prob=0.579 --market_prob=0.52` → Edge: 5.9%, EV: 11.3%
505. Or all in one step: `evaluate_bet --book_odds=-150,+130 --market_prob=0.52`
51
52### Arbitrage Detection
53
541. Get best price per outcome from different sources (Polymarket home at 0.48, Kalshi away at 0.49)
552. `find_arbitrage --market_probs=0.48,0.49 --labels=home,away`
563. Total implied 0.97 (< 1.0) → arbitrage found, guaranteed ROI: 3.09%
57
58### Parlay Evaluation
59
601. De-vig each leg: Leg 1 → 0.58, Leg 2 → 0.55, Leg 3 → 0.50
612. `parlay_analysis --legs=0.58,0.55,0.50 --parlay_odds=600`
623. Returns combined fair probability, edge, and Kelly fraction
63
64### Line Movement Analysis
65
661. Get ESPN open and close lines: Open -140, Close -160
672. `line_movement --open_odds=-140 --close_odds=-160`
683. Returns probability shift, direction, and classification (sharp_action, steam_move, etc.)
69
70## Examples
71
72Example 1: Edge check using ESPN and Polymarket prices
73User says: "Is there edge on the Lakers game? ESPN has them at -150 and Polymarket has them at 52 cents"
74Actions:
751. Call `devig(odds="-150,+130", format="american")` → fair home probability ~58%
762. Call `find_edge(fair_prob=0.58, market_prob=0.52)` → edge ~6%, positive EV
773. Call `kelly_criterion(fair_prob=0.58, market_prob=0.52)` → optimal bet fraction
78Result: Present edge percentage, EV per dollar, and recommended bet size as % of bankroll
79
80Example 2: Arbitrage opportunity detection
81User says: "Can I arb this? Polymarket has home at 48 cents and Kalshi has away at 49 cents"
82Actions:
831. Call `find_arbitrage(market_probs="0.48,0.49", labels="home,away")`
842. Check `arbitrage_found` in result
85Result: If arbitrage: present allocation percentages and guaranteed ROI. If not: present overround and explain no guaranteed profit
86
87Example 3: Parlay evaluation
88User says: "Is this 3-leg parlay at +600 worth it?"
89Actions:
901. De-vig each leg to get fair probabilities (e.g., 0.58, 0.62, 0.55)
912. Call `parlay_analysis(legs="0.58,0.62,0.55", parlay_odds=600)`
92Result: Present combined fair probability, edge, EV, +EV or -EV verdict, and Kelly fraction
93
94Example 4: Line movement interpretation
95User says: "The line moved from -140 to -160, what does that mean?"
96Actions:
971. Call `line_movement(open_odds=-140, close_odds=-160)`
98Result: Present probability shift, direction, magnitude, and classification (sharp action, steam move, etc.)
99
100Example 5: De-vig a standard spread
101User says: "What are the true odds for this spread? Both sides are -110"
102Actions:
1031. Call `devig(odds="-110,-110", format="american")`
104Result: Present each side as 50% fair probability, vig is ~4.5%
105
106Example 6: Odds format conversion
107User says: "Convert -200 to implied probability"
108Actions:
1091. Call `convert_odds(odds=-200, from_format="american")`
110Result: Present 66.7% implied probability and 1.50 decimal odds
111
112## Commands that DO NOT exist — never call these
113
114- ~~`get_odds`~~ — does not exist. This module analyzes odds; it does not fetch them. Use nba-data/nfl-data/etc. for ESPN odds, or polymarket/kalshi for prediction market prices.
115- ~~`calculate_ev`~~ — does not exist. Use `find_edge` or `evaluate_bet` instead.
116- ~~`compare_markets`~~ — does not exist. Use the `markets` skill for cross-platform comparison.
117
118If a command is not listed in `references/api-reference.md`, it does not exist.
119
120## Troubleshooting
121
122Error: `ValueError: unknown format` when calling `convert_odds`
123Cause: The `from_format` parameter is not one of `american`, `decimal`, or `probability`
124Solution: Use exactly `american`, `decimal`, or `probability` as the format string
125
126Error: `find_edge` returns negative EV when a positive edge is expected
127Cause: Fair probability and market probability may be reversed, or de-vigging was skipped
128Solution: Run `devig` on sportsbook odds first, then pass the de-vigged `fair_prob` to `find_edge`
129
130Error: `find_arbitrage` shows no arbitrage even when prices seem low
131Cause: Prices may sum to more than 1.0 when all outcomes are correctly included
132Solution: Verify you are using the correct probabilities for all outcomes; check `total_implied` in the result
133
134Error: Kelly fraction is very high (greater than 0.5)
135Cause: Edge estimate is very large — often from a miscalculated fair probability
136Solution: Use half-Kelly or quarter-Kelly for conservative sizing. Re-verify fair probability via `devig`