Build a No-Vig Fair Value Calculator in Google Sheets
If you've ever wanted to know what a line is actually worth — stripped of the bookmaker's cut — a no-vig fair value calculator in Google Sheets is the single most useful tool you can build in an afternoon. No code degree required. You need a browser, a Google account, and about 45 minutes.
This guide walks you through the math, the formulas, every cell reference, and finally how to wire in live odds from the MoneyLine API so the sheet refreshes automatically instead of you typing numbers by hand.
Let's go.
Why No-Vig Math Matters
Sportsbooks don't price lines at 50/50. They shade both sides so the implied probabilities sum to more than 100% — that excess is the vig (juice, margin, overround — same thing). A standard -110/-110 market carries roughly 4.5% vig. That's the house's guaranteed edge before a single bet resolves.
When you remove the vig, you get the no-vig probability: the book's honest assessment of each outcome, uncontaminated by margin. That number is the foundation of everything else — EV calculation, Kelly sizing, line shopping. Skip it and you're flying blind.
There are two standard methods:
- Multiplicative — scales each implied probability down proportionally. This is the default; it's what sharp shops use.
- Additive — subtracts the vig equally from each side. Simpler but less accurate when lines are lopsided.
We'll build the multiplicative version because it's correct for asymmetric markets (think -200/+170).
The Core Formulas: Converting Odds and Removing Vig
Step 1 — American Odds to Implied Probability
Paste your American odds in column B. Put these in column C:
=IF(B2<0, ABS(B2)/(ABS(B2)+100), 100/(B2+100))
This handles both negative and positive American odds in a single formula. No helper columns needed.
Step 2 — Sum of Implied Probabilities (The Overround)
In a separate cell (say D2), sum the implied probabilities of both sides:
=C2+C3
That number will be something like 1.045 for a -110/-110 game. The excess above 1.0 is the vig margin.
Step 3 — No-Vig Probabilities
For each side, divide its implied probability by the overround:
=C2/$D$2
Copy that down to C3. Now C2 and C3 will sum to exactly 1.0. That's your no-vig market.
Step 4 — Fair Value Odds (Back to American)
You have a clean probability. Convert it back to American odds so you can compare against the line you're being offered:
=IF(C2>=0.5, -(C2/(1-C2))*100, ((1-C2)/C2)*100)
Round it if you want cleaner output:
=ROUND(IF(C2>=0.5, -(C2/(1-C2))*100, ((1-C2)/C2)*100), 0)
Step 5 — Expected Value
Now the payoff. Given a no-vig probability p and the actual line you're betting at (decimal odds d):
=C2*(D2-1)-(1-C2)
Where D2 is the decimal odds of the offered line. Convert American to decimal first:
=IF(B2<0, 1+(100/ABS(B2)), 1+(B2/100))
Positive EV means the book is pricing that side worse than its own market implies. That's where you want to bet.
Full Sheet Layout
Here's a clean structure you can paste into a blank Google Sheet:
| Cell | Label | Value/Formula |
|------|-------|---------------|
| A1 | Side | Team A |
| A2 | Side | Team B |
| B1 | American Odds | (enter manually, e.g. -120) |
| B2 | American Odds | (enter manually, e.g. +105) |
| C1 | Implied Prob | =IF(B1<0,ABS(B1)/(ABS(B1)+100),100/(B1+100)) |
| C2 | Implied Prob | =IF(B2<0,ABS(B2)/(ABS(B2)+100),100/(B2+100)) |
| D1 | Overround | =C1+C2 |
| E1 | No-Vig Prob | =C1/D$1 |
| E2 | No-Vig Prob | =C2/D$1 |
| F1 | Fair Value (Amer) | =ROUND(IF(E1>=0.5,-(E1/(1-E1))*100,((1-E1)/E1)*100),0) |
| F2 | Fair Value (Amer) | =ROUND(IF(E2>=0.5,-(E2/(1-E2))*100,((1-E2)/E2)*100),0) |
| G1 | Decimal Odds | =IF(B1<0,1+(100/ABS(B1)),1+(B1/100)) |
| G2 | Decimal Odds | =IF(B2<0,1+(100/ABS(B2)),1+(B2/100)) |
| H1 | EV % | =ROUND((E1*(G1-1)-(1-E1))*100,2) |
| H2 | EV % | =ROUND((E2*(G2-1)-(1-E2))*100,2) |
Conditional format H1:H2 — green fill when value > 0, red when negative. Now you can see at a glance which side has edge.
Adding Kelly Criterion Sizing
While you're here, add a Kelly column. Full Kelly is too aggressive for most bettors — half Kelly is the practical default:
=MAX(0, ((E1*(G1-1)-(1-E1))/(G1-1))*0.5)
Multiply by your bankroll in a reference cell to get a dollar recommendation. This ties directly into the EV concepts covered in our betting edge guide.
Pulling Live Odds Into the Sheet via Apps Script
Manual entry is fine for one game. For a full slate, you want the sheet to pull live odds automatically. Here's how to wire it to the MoneyLine API.
In Google Sheets: Extensions → Apps Script. Paste this function:
function getMoneylineOdds(eventId) {
const API_KEY = "YOUR_API_KEY_HERE";
const url = `https://mlapi.bet/v1/odds?event_id=${eventId}&markets=h2h&bookmakers=draftkings,fanduel,betmgm`;
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.odds || data.odds.length === 0) return [["No data"]];
const rows = [];
data.odds.forEach(book => {
book.markets.forEach(market => {
market.outcomes.forEach(outcome => {
rows.push([book.bookmaker, outcome.name, outcome.price]);
});
});
});
return rows;
}
Save it. Now in any cell you can call:
=getMoneylineOdds("EVENT_ID_HERE")
The function returns a table of bookmaker | team | American odds. Pipe column C (American odds) into your no-vig formulas above.
To get event IDs, hit the /v1/events endpoint first — it returns the current slate with IDs, sport, commence time, and teams. You can build a second sheet tab that lists today's events and reference it dynamically.
Want to see the full API surface? Check the MoneyLine API endpoint reference — it covers events, odds, edge scores, and player props in one place.
Refreshing on a Schedule
In Apps Script, go to Triggers (clock icon) → Add Trigger:
- Function: your fetch function
- Event source: Time-driven
- Type: Every 5 minutes (or every hour if you're on the free tier managing credits)
The MoneyLine API's free tier gives you 1,000 credits/month. Each /v1/odds call costs 1 credit. At 5-minute intervals over a 3-hour game window, that's 36 calls per event — budget accordingly or set the trigger to every 15 minutes for non-live markets.
Making It Useful: A Few Practical Upgrades
Best-Line Finder Across Books
If your Apps Script pulls odds from multiple bookmakers, add a column that highlights the best available American price for each side:
=MAXIFS(C:C, B:B, "Team A")
Compare that max against your fair value. If maxLine > fairValueLine, you have a positive-EV opportunity worth considering. This is the manual equivalent of what the arbitrage scanner does automatically.
Line Movement Tracking
Add a timestamp column every time the sheet refreshes. Store historical snapshots in a secondary tab using appendRow() in Apps Script:
function logSnapshot() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const source = ss.getSheetByName("Odds");
const log = ss.getSheetByName("Log");
const timestamp = new Date();
const teamA = source.getRange("B1").getValue();
const teamB = source.getRange("B2").getValue();
log.appendRow([timestamp, teamA, teamB]);
}
Call logSnapshot() inside your refresh trigger. Over time you'll have a timestamped record of how lines moved — which is its own signal about where sharp money is landing.
Three-Way Markets (Soccer)
For win/draw/win markets, the overround formula extends naturally:
=C1+C2+C3
And each no-vig probability:
=C1/$D$1
Where D1 now sums three implied probs. The rest of the sheet works identically.
FAQ
What's the difference between no-vig odds and closing line value?
No-vig odds remove the bookmaker's margin to show the "true" implied probability. Closing line value (CLV) measures whether the line you bet at was better than where the market settled at close. They're related — you need no-vig math to calculate CLV accurately — but they answer different questions.
How accurate is the multiplicative no-vig method?
More accurate than additive for lopsided lines. The multiplicative method assumes the book's margin is proportional to each side's implied probability — which matches how sharp books actually price. For heavy favorites (-300 and up), even multiplicative has limits; some analysts use the "margin weights of probabilities" (MWP) method, but the difference is usually under 1%.
How many API credits does a full MLB slate consume?
A 15-game slate pulling odds from 5 bookmakers once every 15 minutes for 4 hours = 15 × 16 = 240 calls. On the free tier (1k credits/month), that covers roughly 4 full slate days before you hit the limit. Upgrade or narrow your bookmaker selection to stretch it further.
Can I use this sheet for player props?
Yes — the math is identical. The MoneyLine API's /v1/odds endpoint supports player prop markets. The only difference is that props often have three-way pricing (over/under/push), so use the three-outcome overround formula above.
Do I need to know how to code to build this?
No. The spreadsheet formulas require zero coding. The Apps Script portion (for live data) is copy-paste JavaScript — you just replace YOUR_API_KEY_HERE with your actual key from the MoneyLine dashboard and drop in an event ID. If you can set up a Gmail filter, you can set up this trigger.
Where to Go From Here
You now have a sheet that strips vig, calculates fair value, sizes bets with half Kelly, and optionally pulls live odds on a timer. That's the core infrastructure that separates recreational bettors from people who actually track their edge.
The next logical step is automating the line-shopping layer — scanning multiple books against the no-vig baseline and flagging anything with positive EV. That's exactly what the MoneyLine API's edge endpoint does server-side, but building it yourself in Sheets first gives you intuition for what the numbers mean before you hand the decision to an algorithm.