How Many Puts to Hedge a Portfolio: Formula
How many puts to hedge a portfolio? The contract formula worked through at the same index level for SPX, XSP and SPY, with rounding and cost in dollars.
How many puts to hedge a portfolio comes down to one division: contracts = (portfolio value x portfolio beta) / (index level x 100). The 100 is the contract multiplier, and the index level sets how much market exposure a single put covers. The quotient almost never lands on a whole number, and what you do with the leftover fraction is most of the actual work.
What the hedging formula divides
Two terms need a plain definition first. Beta is how much a portfolio has historically moved for each 1% move in the index, so a beta of 1.05 describes a portfolio that has travelled about 5% further than the index in both directions. Notional is the dollar exposure one contract controls, which is the index level times the 100 multiplier.
Multiply portfolio value by beta and you get index-equivalent exposure, the dollar figure a hedge has to match. Divide that by one contract's notional and the contract count falls out. Getting the beta term right for a mixed book, including names that have no listed options of their own, is worked through in beta weighting a portfolio's delta.
How many puts do I need to hedge my portfolio?
Take a $180,000 portfolio with a beta of 1.05. Index-equivalent exposure is $189,000, and that one figure divides three ways below, once for each of the three listed products that track the same index.
| product | priced_from | reference_level | notional_per_contract_k | contracts_needed | exposure_covered_multiple |
|---|---|---|---|---|---|
| SPX put (cash settled) | Sep 28, 2026 | 7676.4 | 767.6 | 0.25 | 4.06 |
| SPY put (delivers shares) | Sep 28, 2026 | 767.64 | 76.8 | 2.46 | 0.41 |
| XSP put (cash settled) | Sep 28, 2026 | 767.64 | 76.8 | 2.46 | 0.41 |
The exact SQL behind every number
SELECT
p.product AS product,
s.asof_label AS priced_from,
round(s.px * p.index_units, 2) AS reference_level,
round(s.px * p.index_units * 100 / 1000, 1) AS notional_per_contract_k,
round(189000 / (s.px * p.index_units * 100), 2) AS contracts_needed,
round(s.px * p.index_units * 100 / 189000, 2) AS exposure_covered_multiple
FROM
(
SELECT 'SPX put (cash settled)' AS product, 10 AS index_units
UNION ALL
SELECT 'SPY put (delivers shares)' AS product, 1 AS index_units
UNION ALL
SELECT 'XSP put (cash settled)' AS product, 1 AS index_units
) AS p
CROSS JOIN
(
SELECT
argMax(toFloat64(close), date) AS px,
formatDateTime(max(date), '%b %e, %Y') AS asof_label
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= today() - 30
) AS s
ORDER BY notional_per_contract_k DESC, productAs of Sep 28, 2026, one SPX put covered about $767.6k of exposure at a reference level of 7676.4. The $189,000 target divides into 0.25 of that contract, and no exchange sells a fraction of a put. A single SPX put would cover 4.06 times the portfolio's index-equivalent exposure, which is a directional position rather than a hedge. That is why a $180,000 account cannot buy one SPX put and call the result protection.
The SPY put on the second row covers $76.8k, one tenth as much, and the same $189,000 calls for 2.46 of them. XSP, the mini contract sized off one tenth of the index, comes out at 2.46. Account size and the mini contract are covered in mini index options, and the contract-level differences between the index and the ETF are laid out in SPX versus SPY options.
One note on the reference level column: it scales the ETF's own close, ten times for the full-size index and one times for the mini. The exchange's index print sits a fraction of a percent from that figure, near enough for sizing and never a substitute for a live quote at the moment of the trade.
What rounding leaves unhedged
The fraction has to go somewhere. Round down and part of the portfolio has nothing behind it. Round up and you own protection on exposure the portfolio does not carry. The panel runs both directions across a range of account sizes at SPY and XSP granularity, the finest of the three.
| portfolio_size | exact_contracts | contracts_rounded_down | unhedged_usd_thousands | unhedged_pct | overhedge_pct |
|---|---|---|---|---|---|
| $60k | 0.82 | 0 | 63 | 105 | 22.94 |
| $120k | 1.64 | 1 | 49.2 | 41.03 | 22.94 |
| $180k | 2.46 | 2 | 35.5 | 19.71 | 22.94 |
| $300k | 4.1 | 4 | 7.9 | 2.65 | 22.94 |
| $500k | 6.84 | 6 | 64.4 | 12.88 | 2.47 |
| $700k | 9.57 | 9 | 44.1 | 6.3 | 4.66 |
| $900k | 12.31 | 12 | 23.8 | 2.65 | 5.88 |
The exact SQL behind every number
SELECT
portfolio_size,
round(exact_raw, 2) AS exact_contracts,
toUInt16(floor(exact_raw)) AS contracts_rounded_down,
round((beta_notional - floor(exact_raw) * contract_notional) / 1000, 1) AS unhedged_usd_thousands,
round(100 * (beta_notional - floor(exact_raw) * contract_notional) / portfolio, 2) AS unhedged_pct,
round(100 * (ceil(exact_raw) * contract_notional - beta_notional) / portfolio, 2) AS overhedge_pct
FROM
(
SELECT
v.portfolio AS portfolio,
concat('$', toString(intDiv(v.portfolio, 1000)), 'k') AS portfolio_size,
v.portfolio * 1.05 AS beta_notional,
s.px * 100 AS contract_notional,
v.portfolio * 1.05 / (s.px * 100) AS exact_raw
FROM
(
SELECT arrayJoin([60000, 120000, 180000, 300000, 500000, 700000, 900000]) AS portfolio
) AS v
CROSS JOIN
(
SELECT argMax(toFloat64(close), date) AS px
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= today() - 30
) AS s
)
ORDER BY exact_contractsOn the $180,000 line the exact count is 2.46 contracts. Rounding down to 2 leaves about $35.5k of index-equivalent exposure uncovered, 19.71% of the portfolio. Rounding up covers 22.94% more than the portfolio holds, and that excess behaves like a short index position while the market rises.
One contract's notional is fixed, so the same leftover fraction is a smaller share of a bigger account. At the $900k line the round-down residual works out to 2.65% of the portfolio. Whichever way the count is rounded, the residual is a decision rather than an accident, and it gets made again at every roll.
Two frictions that survive any rounding
Beta drift is the first. The beta in the formula is measured over some past window, and it moves as that window rolls forward. The panel below measures each name's beta against SPY's daily returns over the last twelve months, and again over the twelve months before that.
| ticker | beta_last_12m | beta_prior_12m | beta_change |
|---|---|---|---|
| NVDA | 1.89 | 1.84 | 0.05 |
| MSFT | 0.97 | 0.92 | 0.05 |
| AAPL | 0.68 | 1.24 | 0.56 |
| JNJ | -0.17 | 0.05 | 0.22 |
| KO | -0.25 | 0.08 | 0.33 |
| XOM | -0.55 | 0.52 | 1.07 |
The exact SQL behind every number
WITH closes AS
(
SELECT
ticker,
date,
max(toFloat64(close)) AS px
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('AAPL', 'JNJ', 'KO', 'MSFT', 'NVDA', 'SPY', 'XOM')
AND date >= today() - 730
AND date < today() - 2
GROUP BY ticker, date
),
rets AS
(
SELECT
ticker,
date,
px / prev_px - 1 AS ret
FROM
(
SELECT
ticker,
date,
px,
lagInFrame(px) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_px
FROM closes
)
WHERE prev_px > 0
)
SELECT
ticker,
beta_last_12m,
beta_prior_12m,
round(abs(beta_last_12m - beta_prior_12m), 2) AS beta_change
FROM
(
SELECT
s.ticker AS ticker,
round(covarPopIf(s.ret, m.ret, s.date >= today() - 365) / varPopIf(m.ret, s.date >= today() - 365), 2) AS beta_last_12m,
round(covarPopIf(s.ret, m.ret, s.date < today() - 365) / varPopIf(m.ret, s.date < today() - 365), 2) AS beta_prior_12m
FROM rets AS s
INNER JOIN
(
SELECT date, ret
FROM rets
WHERE ticker = 'SPY'
) AS m ON s.date = m.date
WHERE s.ticker != 'SPY'
GROUP BY s.ticker
HAVING countIf(s.date >= today() - 365) > 60
AND countIf(s.date < today() - 365) > 60
)
ORDER BY beta_last_12m DESCThe highest-beta name of the six, NVDA, measured 1.89 over the recent twelve months against 1.84 in the twelve before, a shift of 0.05. At the bottom of the same column, XOM measured -0.55, a fitted number that describes one stretch of daily returns and carries no promise about the next stretch. A hedge sized on last year's beta is sized on last year's portfolio behaviour, and rounding the contract count does nothing about that gap.
Basis risk is the second. The formula treats the portfolio as the index once scaled by beta, and no real portfolio is the index. Beta is one average number fitted to past returns, silent about the sessions when a concentrated book falls while the index holds flat. An index put pays on the index, whatever the portfolio did that day. Both frictions are measurement problems, and both outlive the contract count.
Cash settlement versus share delivery
One structural difference outranks every rounding question at expiry. Index options settle in cash: the in-the-money amount is paid, and no position in anything changes hands. ETF options deliver shares. An assigned SPY put leaves the holder short 100 shares per contract, a position that needs closing and that carries short-stock margin treatment until it is closed. An SPX or XSP put simply pays.
American-style ETF options can also be assigned before expiry, while the two index contracts here are European-style and exercise only at expiry, a distinction set out in American versus European options. The mechanics of the long put leg itself are covered in protective puts.
What does a portfolio hedge cost per year?
Premium as a percentage of the notional being protected is what makes strikes comparable, and a simple annualisation makes rolling comparable. The panel groups SPY puts with 20 to 60 days to expiry, across the six months ending at the latest session carried in the options data as of September 2026, into four bands by how far below spot they were struck.
| strike_distance | premium_pct_of_notional | annualised_pct |
|---|---|---|
| within 2% of spot | 1.36 | 13.7 |
| 2% to 5% below spot | 0.79 | 8.1 |
| 5% to 10% below spot | 0.39 | 4 |
| 10% to 20% below spot | 0.16 | 1.6 |
The exact SQL behind every number
WITH puts AS
(
SELECT
days_to_expiry AS dte,
toFloat64(strike_price) / toFloat64(underlying_close) AS moneyness,
toFloat64(option_close) / toFloat64(underlying_close) AS premium_share
FROM global_markets.options_greeks
WHERE underlying_symbol = 'SPY'
AND lower(toString(option_type)) LIKE 'p%'
AND days_to_expiry BETWEEN 20 AND 60
AND underlying_close > 0
AND option_close > 0
AND date >= (SELECT max(date) - 180 FROM global_markets.options_greeks WHERE underlying_symbol = 'SPY')
AND date <= (SELECT max(date) FROM global_markets.options_greeks WHERE underlying_symbol = 'SPY')
)
SELECT
strike_distance,
round(100 * avg(premium_share), 2) AS premium_pct_of_notional,
round(100 * avg(premium_share) * 365 / avg(dte), 1) AS annualised_pct
FROM
(
SELECT
premium_share,
dte,
moneyness,
multiIf(moneyness >= 0.98, 'within 2% of spot',
moneyness >= 0.95, '2% to 5% below spot',
moneyness >= 0.90, '5% to 10% below spot',
'10% to 20% below spot') AS strike_distance
FROM puts
WHERE moneyness >= 0.80
AND moneyness < 1.00
)
GROUP BY strike_distance
HAVING count() > 5
ORDER BY avg(moneyness) DESCA put struck within 2% of spot cost 1.36% of the notional it covered, which annualises to 13.7% a year at that price. Struck 10% to 20% below spot, the same measure is 0.16%, or 1.6% annualised, with a far larger first loss retained before the put pays anything. Those annual figures are straight multiplications rather than compounded returns, and the premium paid on any given day moves with the volatility priced into the contract at that moment.
Selling an upside call to offset part of the premium is the structure covered in collars, and the volatility input itself is set against beta in implied volatility versus beta.
FAQ
How many puts do I need to hedge a $100,000 portfolio?
Multiply $100,000 by the portfolio's beta, then divide by one contract's notional. At a beta of 1.0 that is $100,000 of index-equivalent exposure measured against the SPY contract notional in the first panel above. The result is a fraction, and the rounding panel shows what each direction of rounding leaves behind.
Can a small portfolio be hedged with SPX puts?
One SPX put covered 4.06 times the index-equivalent exposure of the $180,000 example above, so a single contract overshoots an account that size by a wide margin. XSP and SPY contracts are one tenth the size, a granularity that fits smaller accounts.
What is the difference between hedging with SPX and SPY puts?
Size and settlement. One SPX put carries ten times the notional of one SPY put, and it settles in cash at expiry. A SPY put delivers 100 shares on assignment, which leaves a short stock position to close.
Does the number of puts change as the market moves?
Yes. The index level is the divisor in the formula, so the same portfolio needs a different count after a large move, and the beta term shifts as its measurement window rolls forward. The panels above put numbers on the size of both effects.
Is a beta-weighted put hedge the same as delta hedging?
No. A beta-weighted put hedge matches a fixed quantity of index exposure at a chosen strike and expiry. A delta hedge is adjusted continuously as the option's delta changes, a process described in how delta hedging works.
Every panel here carries the exact query that produced it, expandable underneath the table. To run the same division against your own account size and beta, or to price the same hedge at a different strike distance, ask the question in plain English on the Strasmore terminal.