If you've ever squinted at a -110/-110 line and wondered what the book actually thinks the true probability is — this post is for you. A no-vig fair odds calculator in Google Sheets is the single most useful thing a serious bettor can build in an afternoon. It strips the margin out of a two-sided market, tells you the implied fair probability for each side, and — with one more column — tells you whether the price you're seeing elsewhere is actually positive EV.
I'm going to show you the exact formulas, walk through the logic so you understand what you're calculating, and then wire it up to the MoneyLine API so the sheet pulls live odds automatically instead of you copy-pasting from a tab.
No developer experience required. You'll need Google Sheets and about 45 minutes.
Why Stripping the Vig Matters
Books don't set lines at true probability. They build in a margin — typically 4–8% on mainstream markets, sometimes north of 15% on props. When you see -110 on both sides of a spread, the implied probabilities sum to about 104.8%, not 100%. That 4.8% is the house edge baked into your bet before any other consideration.
To evaluate whether a bet has positive expected value, you need the fair (no-vig) probability — what the market would price each side at if the book made zero margin. Then you compare that fair probability against the decimal odds you're being offered elsewhere.
If fair probability > (1 / decimal odds), you have positive EV. If it's lower, you're donating.
This is the foundation of every edge calculation on /bet/ev. The no-vig step is not optional.
The Core No-Vig Formula
Step 1: Convert American Odds to Implied Probability
Positive American odds (e.g., +150):
Implied Prob = 100 / (odds + 100)
Negative American odds (e.g., -180):
Implied Prob = |odds| / (|odds| + 100)
In Sheets, with the American odds in cell B2:
=IF(B2>0, 100/(B2+100), ABS(B2)/(ABS(B2)+100))
Put this in C2 for Side A. Put an identical formula referencing B3 in C3 for Side B.
Step 2: Calculate Total Implied Probability (the Overround)
In D2:
=C2+C3
This is your overround. For a standard -110/-110 market it'll be ~1.0476. Anything above 1.0 is the vig.
Step 3: Normalize to Fair Probability
Divide each side's implied probability by the total:
=C2/D2
In E2 (fair prob for Side A). In E3:
=C3/D2
These two now sum to exactly 1.0. That's your no-vig market.
Step 4: Convert Fair Probability Back to Fair American Odds
You'll want to see the fair line as American odds for easy comparison. In F2:
=IF(E2>=0.5, -1*((E2/(1-E2))*100), (((1-E2)/E2)*100))
This gives you the fair line in American format. If a -110/-110 spread is the input, both sides come out around -104.5 — the "no-vig" price a sharp exchange like Novig or a peer-to-peer book might approach.
Building the Full Sheet
Here's the complete column layout. Row 1 is headers. Data starts in row 2.
| Col | Header | Formula (row 2) |
|-----|--------|-----------------|
| A | Event | (manual or API) |
| B | Side A Odds (American) | (manual or API) |
| C | Side B Odds (American) | (manual or API) |
| D | Implied Prob A | =IF(B2>0,100/(B2+100),ABS(B2)/(ABS(B2)+100)) |
| E | Implied Prob B | =IF(C2>0,100/(C2+100),ABS(C2)/(ABS(C2)+100)) |
| F | Overround | =D2+E2 |
| G | Fair Prob A | =D2/F2 |
| H | Fair Prob B | =E2/F2 |
| I | Fair Line A | =IF(G2>=0.5,-1*((G2/(1-G2))*100),((1-G2)/G2)*100) |
| J | Fair Line B | =IF(H2>=0.5,-1*((H2/(1-H2))*100),((1-H2)/H2)*100) |
Adding an EV Column
Say you're shopping a different book's price for Side A in column K (enter that book's American odds there). Column L calculates EV:
=((K2/100+1)*G2)-1
This uses decimal odds. But K2 is American, so you need to convert first. Combined formula in L2:
=IF(K2>0, ((K2/100+1)*G2)-1, ((100/ABS(K2)+1)*G2)-1)
Format column L as a percentage. Green conditional formatting at >0, red at <0. Now you have a full no-vig EV scanner in a single row.
Kelly Criterion Sizing
One more column while we're here. Kelly fraction in M2, assuming your bankroll is in a named range called Bankroll:
=IF(L2>0, (G2 - (1-G2)/IF(K2>0,K2/100,100/ABS(K2))), 0)
Dollar amount to bet:
=M2 * Bankroll
This tells you the theoretically optimal stake given your edge and fair probability. Most serious bettors use a fractional Kelly (typically 25–50%) to reduce variance. Just multiply M2 by 0.25 or 0.5 before applying to Bankroll. See the arbitrage reference at /bet/arbitrage for how Kelly interacts with guaranteed-profit plays.
Pulling Live Odds Automatically via Apps Script
Manually entering odds defeats the purpose. Here's how to wire the sheet to the MoneyLine API so it refreshes on demand.
Setup
- In your Google Sheet, go to Extensions → Apps Script.
- Paste the function below.
- Replace
YOUR_API_KEYwith your key from the MoneyLine dashboard. - Save and run
fetchOddsonce to grant permissions.
const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://mlapi.bet";
function fetchOdds() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("NoVig");
// Fetch today's MLB events with two-way moneyline odds
const url = `${BASE_URL}/v1/odds?sport=baseball_mlb&markets=h2h&bookmakers=draftkings,fanduel,betmgm&limit=20`;
const options = {
method: "get",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
muteHttpExceptions: true,
};
const response = UrlFetchApp.fetch(url, options);
const data = JSON.parse(response.getContentText());
if (!data || !data.data) {
Logger.log("No data returned.");
return;
}
// Clear existing data rows (keep header in row 1)
sheet.getRange("A2:C100").clearContent();
let row = 2;
data.data.forEach((event) => {
const eventName = `${event.home_team} vs ${event.away_team}`;
// Use first bookmaker's h2h market as the "sharp reference" line
const book = event.bookmakers && event.bookmakers[0];
if (!book) return;
const h2h = book.markets.find((m) => m.key === "h2h");
if (!h2h || h2h.outcomes.length < 2) return;
const homeOdds = h2h.outcomes.find((o) => o.name === event.home_team);
const awayOdds = h2h.outcomes.find((o) => o.name === event.away_team);
if (!homeOdds || !awayOdds) return;
sheet.getRange(row, 1).setValue(eventName);
sheet.getRange(row, 2).setValue(homeOdds.price); // American odds
sheet.getRange(row, 3).setValue(awayOdds.price); // American odds
row++;
});
Logger.log(`Loaded ${row - 2} events.`);
}
// Optional: trigger this to run every 10 minutes
function createTrigger() {
ScriptApp.newTrigger("fetchOdds")
.timeBased()
.everyMinutes(10)
.create();
}
After the script runs, columns A–C populate automatically. The formulas in D through M recalculate instantly — you now have a live no-vig calculator that refreshes every 10 minutes.
Pulling the Sharp Consensus Instead
If you want the no-vig line derived from sharp books specifically (Pinnacle, Novig, etc.) rather than a single book, change the bookmakers param:
/v1/odds?sport=baseball_mlb&markets=h2h&bookmakers=pinnacle,novig&limit=20
Averaging across two or three sharp books before stripping vig gives you a more stable fair-probability estimate. In that case, change the Apps Script to average the home odds across bookmakers before writing to the sheet — or write each book to its own column and average in Sheets with =AVERAGE(B2:D2).
The MoneyLine API comparison page at /build/compare/the-odds-api covers which books are available across different data providers if you need to cross-reference.
Calibrating Your Sheet Against Reality
A few things to watch for once the sheet is running:
Overround drift by sport. NFL sides typically run 4–5% overround at major books. NBA props can hit 10–12%. If your overround column is showing 1.02 on a prop, either the market is incredibly efficient or you're only seeing one side of a two-way quote.
Correlated legs. The no-vig formula assumes two independent outcomes that exhaust the probability space. For moneylines and spreads this is fine. For totals, be aware that a sharp total line has the same implied-prob math, but the fair-prob output doesn't account for correlation with the spread. Don't mix moneyline and total vig-stripping in the same formula without separating them.
Line timing. The fair probability you calculate at open isn't the same as at game time. Always timestamp your pulls. The Apps Script above doesn't log timestamps — add sheet.getRange(row, 14).setValue(new Date()) in the loop if you want to track line movement over time.
Frequently Asked Questions
What is a no-vig calculator and why do bettors use it? A no-vig calculator removes the sportsbook's margin (vig or juice) from a two-sided betting market to reveal the true implied probability each side. Bettors use it to find positive EV bets: if another book prices a side higher than the no-vig fair probability implies, you have an edge.
How do I calculate no-vig odds in Google Sheets?
Convert each side's American odds to implied probability with =IF(B2>0,100/(B2+100),ABS(B2)/(ABS(B2)+100)), sum both probabilities (the overround), then divide each by the overround. That gives you fair probability. Convert back to American odds with =IF(G2>=0.5,-1*((G2/(1-G2))*100),((1-G2)/G2)*100).
Can I pull live odds into Google Sheets without coding?
You need a small Google Apps Script function — about 40 lines of JavaScript — to call a sports odds API and write the results to your sheet. The script in this post is copy-paste ready and uses the MoneyLine API endpoint /v1/odds. No other developer setup is required.
What's the difference between implied probability and fair probability? Implied probability is what the American odds suggest directly — it overcounts to 100%+ because of the vig. Fair probability is implied probability normalized so both sides sum to exactly 100%, representing what the book actually believes the true probability to be after removing its edge.
How often should I refresh the odds in my sheet? For pre-game markets, every 10–15 minutes is sufficient for most sports. In the two hours before a major game, lines can move sharply; set your trigger to 5 minutes if you're actively betting that window. For live (in-game) markets, API polling under 60 seconds is more relevant but requires a different sheet architecture.
What to Build Next
Once this sheet is running, the natural extensions are:
- Line-movement tracker — log each refresh to a separate tab and chart how the fair line moves from open to game time. Sharp-side indicators often show up as one-sided drift even on "even" markets.
- Prop no-vig scanner — the same formula works on player props, but you'll want to pull
/v1/odds?markets=player_propsand handle three-way markets (over/under/push) with a three-way normalization. - Cross-book arbitrage flag — if the best price at any book beats the fair line by more than the minimum detectable edge, flag it in red. That's the mechanical foundation of arb detection covered in the /build/api documentation.
The sheet you've built today is not a toy. It's the same core calculation used in every professional EV scanner — just in a format you can inspect, audit, and customize without waiting for a vendor to add a feature.