BettingLab

Build a No-Vig Calculator in Google Sheets

Marcus Hale
Marcus Hale

If you've been betting for more than six months without a no-vig calculator, you've been flying blind. The vig — the sportsbook's margin baked into every line — is the single biggest structural edge working against you. Stripping it out tells you the book's actual opinion of the event, and that fair-odds baseline is what you compare everything else against.

This post walks you through building a no-vig calculator in Google Sheets from scratch: the math, the formulas, a live-odds pull via the MoneyLine API, and optional Kelly sizing bolted on at the end. No developer experience required. If you can type a formula into a cell, you can build this.


Why Vig Removal Matters Before You Size Any Bet

A -110 / -110 line on a two-way market looks balanced. But those two implied probabilities add up to 104.76%, not 100%. The extra 4.76% is the book's take. If you bet both sides at -110, you lose roughly $4.76 for every $100 in theoretical stakes over time.

The fair (no-vig) probability on each side of that -110 / -110 line is exactly 50%. But on a -130 / +108 line — common in MLB — the fair probability is not 56.5% and 48.1%. Those are the raw implied probabilities. After removing the vig, the fair probabilities shift, and the difference between raw and fair is where you spot the book's lean.

Skipping this step and just comparing your model's number to the raw implied probability is like measuring elevation with a ruler that's 5% too short. You'll consistently think hills are shorter than they are.


The Formulas: Sheet Layout and Math

Open a new Google Sheet. Set up these columns in row 1:

| A | B | C | D | E | F | G | |---|---|---|---|---|---|---| | Event | Side 1 American | Side 2 American | Side 1 Implied % | Side 2 Implied % | Overround | Side 1 No-Vig % | Side 2 No-Vig % |

(Add columns H and I for fair decimal odds, J for your model prob, K for EV — we'll get there.)

Step 1: American Odds → Implied Probability

In D2 (Side 1 implied probability):

=IF(B2<0, (-B2)/(-B2+100), 100/(B2+100))

In E2 (Side 2 implied probability):

=IF(C2<0, (-C2)/(-C2+100), 100/(C2+100))

These return decimals between 0 and 1. Format D2:E2 as percentages.

Step 2: Overround (the vig itself)

In F2:

=D2+E2

A perfectly sharp market with zero vig returns exactly 1.00. Anything above 1 is the book's edge as a fraction. At 1.0476 you're looking at a 4.76% overround — typical for a recreational book on a medium-volume game.

Step 3: Remove the Vig (Multiplicative Method)

The multiplicative method is the industry standard for two-outcome markets. It scales each raw implied probability down by the overround.

In G2 (Side 1 no-vig probability):

=D2/F2

In H2 (Side 2 no-vig probability):

=E2/F2

G2 + H2 should now equal exactly 1.00. If it doesn't, you made a formula error upstream.

Step 4: Fair Decimal Odds (for EV math)

In I2 (fair decimal odds for Side 1):

=1/G2

In J2 (fair decimal odds for Side 2):

=1/H2

Step 5: Expected Value Against Your Model

Add a column K2 for your model's probability on Side 1 (you enter this manually or pull it from elsewhere). Then in L2:

=((K2 * (I2 - 1)) - (1 - K2)) * 100

This is EV in cents per dollar wagered, scaled to 100. Positive means you have an edge. Negative means the book does.

If you want to skip the model column entirely and just use the no-vig probability as a sanity check against closing line, that's valid too — many sharp bettors use the no-vig as their "market consensus" baseline when they don't have a proprietary model.

Step 6: Kelly Criterion Sizing (optional but useful)

In M2, assuming K2 is your model probability and B2 is your American odds on Side 1:

=IF(B2>=0,
  (K2 * (B2/100) - (1 - K2)) / (B2/100),
  (K2 * (100/(-B2)) - (1 - K2)) / (100/(-B2))
)

This returns a fraction of bankroll. Most practitioners use a quarter-Kelly or half-Kelly in practice — multiply M2 by 0.25 or 0.5 to temper variance. See the EV betting primer for more on sizing philosophy.


Pulling Live Odds Into Sheets via Apps Script

Manual entry works for testing. But if you're tracking 20 games on a Saturday, you want live data flowing in automatically. Here's how to wire the MoneyLine API into your sheet using Google Apps Script.

In your sheet, go to Extensions → Apps Script, paste the following, then save and run fetchOdds:

const API_KEY = "YOUR_MLAPI_KEY"; // get yours at moneylineapp.com
const BASE_URL = "https://mlapi.bet";

function fetchOdds() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("NoVig");

  // Fetch today's events — adjust sport as needed
  const eventsUrl = `${BASE_URL}/v1/events?sport=baseball_mlb&status=upcoming`;
  const eventsResp = UrlFetchApp.fetch(eventsUrl, {
    headers: { "Authorization": `Bearer ${API_KEY}` }
  });
  const events = JSON.parse(eventsResp.getContentText()).data;

  let rowIndex = 2; // start writing from row 2

  events.forEach(event => {
    // Fetch two-way odds for each event
    const oddsUrl = `${BASE_URL}/v1/odds?event_id=${event.id}&market=h2h&bookmaker=draftkings`;
    const oddsResp = UrlFetchApp.fetch(oddsUrl, {
      headers: { "Authorization": `Bearer ${API_KEY}` }
    });
    const oddsData = JSON.parse(oddsResp.getContentText()).data;

    if (!oddsData || oddsData.length === 0) return;

    const outcomes = oddsData[0].outcomes; // array of {name, price}
    if (!outcomes || outcomes.length < 2) return;

    const side1American = outcomes[0].price; // e.g., -130
    const side2American = outcomes[1].price; // e.g., +110

    sheet.getRange(rowIndex, 1).setValue(event.name);       // A: Event
    sheet.getRange(rowIndex, 2).setValue(side1American);    // B: Side 1
    sheet.getRange(rowIndex, 3).setValue(side2American);    // C: Side 2
    // Columns D–M use the formulas you already entered in row 2
    // Copy them down programmatically:
    const formulaRow = sheet.getRange("D2:M2");
    formulaRow.copyTo(sheet.getRange(rowIndex, 4, 1, 10));

    rowIndex++;
  });

  Logger.log(`Wrote ${rowIndex - 2} events.`);
}

A few notes on the script:

For deeper integration options, check the MoneyLine API docs for rate limits, supported markets, and event filter parameters.


Extending the Sheet: Line Movement and Closing Line Value

Once your sheet is auto-refreshing, add a timestamp column (column N):

=NOW()

And a "CLV Delta" column that compares your opening no-vig probability (captured in column O at bet time) to the current no-vig probability in G:

=G2 - O2

If the market moves in your direction after you bet, you have positive closing line value — the strongest long-run indicator that you're on the right side of the market. Tracking this consistently is what separates disciplined bettors from gamblers who run hot for a month and confuse luck with edge.

This pairs naturally with the arbitrage work covered in the live arbitrage detection post — once you have fair odds, spotting cross-book arbs becomes mechanical.


Frequently Asked Questions

What's the difference between the additive and multiplicative method for removing vig?

The additive method subtracts an equal share of the overround from each side's implied probability. The multiplicative method divides each by the total overround. For two-outcome markets with roughly equal probabilities, the results are similar. For lopsided favorites (think -400 / +300), multiplicative is more accurate because it preserves the relative shape of the probability distribution rather than flattening it.

Does this work for three-way markets like soccer 1X2?

Yes, with minor formula adjustments. You'd have three implied probability cells (D, E, F) summing to the overround in G, then divide each by G to get three no-vig probabilities. The EV formula still works the same way — compare your model probability to the no-vig probability for each outcome.

How often should I refresh the odds feed?

For pre-game markets, every 15–30 minutes is plenty unless you're specifically hunting line moves around injury news. For live in-game betting, you'd want sub-minute refreshes — but Google Sheets isn't the right tool for that; you'd want a proper application stack.

My no-vig probabilities don't add to exactly 1.00 — what's wrong?

Usually a floating-point rounding issue. Wrap G2 and H2 in =ROUND(..., 6) and verify that =G2+H2 shows 1. If it doesn't, check that D2 and E2 are computing from the same raw American odds cells, not hardcoded values.

Can I use this sheet to compare no-vig odds across multiple books?

Absolutely — and that's where it gets powerful. Add columns for a second bookmaker's Side 1 and Side 2 odds, compute their no-vig probabilities, then flag rows where one book's no-vig probability is meaningfully different from another's. That gap is your research queue for arbitrage and EV plays.


Putting It Together

The sheet you've just built does five things most bettors never formalize: strips vig, surfaces fair probabilities, calculates EV against a model, sizes bets via Kelly, and tracks closing line value. None of those steps require code. The Apps Script layer adds live data so you're not typing odds by hand.

The formulas are simple. The discipline to use them on every bet — instead of just eyeballing a line — is what compounds over a season.

Start with the free tier at MoneyLine API, import today's MLB slate, and see how many lines look different once the vig is gone.

Build with the same data we use.

MoneyLine API powers BettingLab's edge calculations. Free tier, 1k credits/month.