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: sports-betting3description: |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`