If you have ever typed "no-vig fair odds calculator Google Sheets" into a search bar, you are already thinking about betting the right way. The vig — the juice the book bakes into every line — is the single biggest reason recreational bettors bleed money over time. Strip it out and you can see the book's true implied probability. Compare that to your own number, and suddenly you know whether a bet has positive expected value or not.
This walkthrough builds the whole thing: the math, the formulas, the sheet layout, and an Apps Script snippet that pulls live odds from the MoneyLine API so your calculator always has fresh data to work with.
The Math You Need to Know First
American odds to implied probability
A -110 line means you risk $110 to win $100. The raw implied probability is:
P = |odds| / (|odds| + 100) — for negative lines
P = 100 / (odds + 100) — for positive lines
For -110: 110 / 210 = 52.38%
For +100: 100 / 200 = 50.00%
Why the two sides don't add up to 100%
A standard two-sided market at -110 / -110 gives you 52.38% + 52.38% = 104.76%. That extra 4.76% is the vig, the book's margin. To get fair odds, you renormalize the two probabilities so they sum to exactly 100%.
The no-vig formula
Fair P₁ = Raw P₁ / (Raw P₁ + Raw P₂)
Fair P₂ = Raw P₂ / (Raw P₁ + Raw P₂)
Fair probability back to American odds:
If Fair P ≥ 0.5: American = -(Fair P / (1 - Fair P)) × 100
If Fair P < 0.5: American = ((1 - Fair P) / Fair P) × 100
That is all of it. Everything in the sheet below is just these formulas wrapped in cell references.
Building the Sheet: Layout and Formulas
Open a blank Google Sheet. Name the tab NoVig.
Column layout
| Col | Label | Notes | |-----|-------|-------| | A | Side | "Home" / "Away" or team names | | B | Book Line (American) | Raw odds from the book | | C | Raw Implied % | Calculated | | D | Overround | Sum of raw probabilities | | E | Fair Implied % | No-vig probability | | F | Fair American Odds | No-vig line | | G | Your Edge | Optional — enter your estimate in a separate column |
Row setup
- Row 1: headers
- Row 2: Side 1 (Away / underdog)
- Row 3: Side 2 (Home / favorite)
- Row 4: Totals / checks
Formula: Raw implied probability (C2)
=IF(B2<0, ABS(B2)/(ABS(B2)+100), 100/(B2+100))
Copy to C3.
Formula: Overround (D2 and D3, same value)
=C2+C3
Put this in D2. In D4 for a visual check:
=IF(ABS(D2-1)<0.001,"✓ Fair","Overround: "&TEXT((D2-1)*100,"0.00")&"%")
Formula: Fair implied probability (E2)
=C2/D2
Copy to E3. These two cells will now sum to exactly 1.
Formula: Fair American odds (F2)
=IF(E2>=0.5, -(E2/(1-E2))*100, ((1-E2)/E2)*100)
Copy to F3.
You will want to format column F as a number with zero decimals and manually add the + prefix for positive values. An easy way:
=IF(E2<0.5,"+"&TEXT(((1-E2)/E2)*100,"0"),TEXT(-(E2/(1-E2))*100,"0"))
This gives you "+105" or "-118" as a string, which is easier to read at a glance.
Optional: EV column (H2) if you have a bet size in G2
If G2 is your estimated fair probability and you want the EV of betting on Side 1 at the book line in B2:
=IF(B2>0,(G2*(B2/100))-((1-G2)*1),(G2*(100/ABS(B2)))-((1-G2)*1))
Positive value means the bet has positive expected value. You can read more about structuring that calculation on the EV betting reference page.
Pulling Live Odds Automatically with Apps Script
A static sheet is fine for one game. For a full slate you want live data piped in automatically. Here is a Google Apps Script function that calls the MoneyLine API /v1/odds endpoint and writes the results into your sheet.
Go to Extensions → Apps Script in your Google Sheet, paste this in, and save.
// MoneyLine API — no-vig odds fetcher
// Paste into Extensions → Apps Script
const API_KEY = "YOUR_MLAPI_KEY"; // swap in your key
const BASE_URL = "https://mlapi.bet";
function fetchMLBOdds() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("NoVig");
if (!sheet) {
SpreadsheetApp.getUi().alert("Create a tab named 'NoVig' first.");
return;
}
const url = `${BASE_URL}/v1/odds?sport=baseball_mlb&markets=h2h&oddsFormat=american`;
const options = {
method: "get",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Accept": "application/json"
},
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(url, options);
const code = response.getResponseCode();
if (code !== 200) {
Logger.log("API error: " + response.getContentText());
return;
}
const data = JSON.parse(response.getContentText());
const events = data.data || [];
// Clear old data below header row
if (sheet.getLastRow() > 1) {
sheet.getRange(2, 1, sheet.getLastRow() - 1, 8).clearContent();
}
let row = 2;
events.forEach(event => {
const home = event.home_team;
const away = event.away_team;
// Grab the first bookmaker's h2h market
const bk = event.bookmakers?.[0];
if (!bk) return;
const h2h = bk.markets?.find(m => m.key === "h2h");
if (!h2h) return;
const awayOutcome = h2h.outcomes?.find(o => o.name === away);
const homeOutcome = h2h.outcomes?.find(o => o.name === home);
if (!awayOutcome || !homeOutcome) return;
// Write away side
sheet.getRange(row, 1).setValue(away);
sheet.getRange(row, 2).setValue(awayOutcome.price);
// Write home side
sheet.getRange(row + 1, 1).setValue(home);
sheet.getRange(row + 1, 2).setValue(homeOutcome.price);
// Label event
sheet.getRange(row, 8).setValue(`${away} @ ${home} — ${bk.title}`);
row += 3; // blank row between games
});
Logger.log(`Wrote ${events.length} events.`);
}
// Hook up a timed trigger: Resources → Triggers → every 5 minutes
Once this runs, column B is populated with live American odds. Your formulas in columns C–F calculate automatically. Every five minutes (if you set a trigger) the whole sheet refreshes.
The free tier of the MoneyLine API gives you 1,000 credits per month — enough for a full MLB season of spot-checks without spending a dollar. Hit MoneyLine API to grab your key.
Reading the Output: What the Numbers Tell You
When fair odds are close to book odds
If the book posts -115 / -105 on a side and your fair line is -110 / -110, there is only a small edge being offered to the -105 side. Not every line is exploitable. This sheet tells you that quickly without any guesswork.
When fair odds diverge sharply from the book
A -200 book line that strips to -165 fair means the book is charging you a huge premium to bet the favorite. This is common on heavily bet sides. The book knows public money will hammer the chalk and prices it accordingly. Your calculator surfaces exactly how much you are overpaying.
Comparing books side by side
Add a second block of columns (B2–F3 for Book A, I2–N3 for Book B). Use the same formula structure. If Book A's fair line on the underdog is +145 and Book B is posting +155, Book B is the better bet without question — and you can see it in one glance.
This is the same underlying logic driving the arbitrage detection workflow — except here you are just tracking one side for value rather than locking both sides for guaranteed profit.
Extending the Sheet for Multiple Markets
The two-outcome (moneyline) case is the cleanest, but you can extend the same no-vig logic to point spreads and totals.
For a spread market the math is identical — both sides are usually close to -110 / -110, so the overround is around 4–5%. Strip it with the same C2/D2 formula.
For three-outcome markets (soccer win/draw/win), the formula generalizes:
Fair Pₙ = Raw Pₙ / (Raw P₁ + Raw P₂ + Raw P₃)
Just extend column C down a third row and update the D column sum range. The fair American odds formula in F works identically once you have the fair probability.
You can find a breakdown of how the MoneyLine API structures its odds endpoints — the markets array supports spreads, totals, and props, so the same Apps Script function can pull any of them with a one-line change to the markets query parameter.
FAQ
What does "no-vig" mean in sports betting?
No-vig means removing the sportsbook's built-in margin (the "vig" or "juice") from posted odds. The result is a fair implied probability — what the market actually thinks each side's true chances are, without the book's profit baked in.
How accurate is a no-vig calculator?
It is as accurate as the lines you feed it. Pinnacle and sharp books have tighter lines (lower vig, more accurate pricing) than recreational books like DraftKings or FanDuel. Running the same game through multiple books and averaging the fair probabilities gives you a better consensus estimate.
Can I use this sheet for prop bets?
Yes. The math is the same for any two-outcome prop. Plug in the over and under odds, and the formulas strip the vig the same way. Be careful with props that have a push outcome built in — those require a three-way no-vig calculation.
Why does my fair probability not match what I see on no-vig sites?
Different tools handle multi-book averaging differently. Some weight by sharpness of the book, some use a simple average. This sheet uses a single book's line. Feed it the sharpest available line (Pinnacle, Circa) and your fair probability will be much more reliable.
How many API credits does refreshing every 5 minutes use?
Each call to /v1/odds counts as one credit. At a 5-minute refresh interval over a 4-hour game window, you spend roughly 48 credits per active game day. The free tier's 1,000 credits covers about 20 full-slate days per month — enough for the whole MLB stretch run without upgrading.