Volatility Trading and Arbitrage Strategies › Trading the VIX
Quantitative FinanceAll chapters Volatility Trading and Arbitrage Strategies › Trading the VIXOne section · Sections in this chapter11 / 15 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
The CBOE Volatility Index (VIX) provides a benchmark for S&P 500 implied volatility. VIX derivatives, such as futures and options, allow you to take positions on volatility expectations and hedge volatility risk.
VIX Calculation
The VIX is calculated from a portfolio of S&P 500 index options using a methodology similar to variance swap pricing. It represents the 30-day expected volatility implied by option prices:
where:
- : variance used to calculate VIX ()
- : time to expiration
- : interval between strike prices
- : strike price of the -th option
- : risk-free interest rate
- : midpoint of the bid-ask spread for option at strike
- : forward index level derived from option prices
- : first strike below the forward price
The VIX calculation methodology is directly related to the variance swap replication formula we examined earlier. Both approaches use a portfolio of out-of-the-money options weighted by the inverse square of the strike to capture expected variance. The key difference is that the VIX uses a specific set of S&P 500 options with near-term and next-term expirations, interpolated to provide a constant 30-day horizon.
The formula consists of two main parts:
- Option Summation: aggregates the prices of out-of-the-money options, weighted by , to replicate the variance payoff.
- Forward Adjustment: corrects for the discrete difference between the forward price and the cutoff strike .
The forward adjustment term is necessary because the formula uses a discrete set of option strikes rather than a continuous spectrum. Since the transition between puts and calls occurs at rather than exactly at the forward price , this adjustment corrects for the small pricing error that would otherwise result.
VIX Futures Term Structure
VIX futures prices reflect expectations of future VIX levels plus a risk premium. The typical term structure shapes are:
- Contango: Normal market conditions. Longer-dated futures trade above spot VIX because investors demand premium for bearing volatility risk.
- Backwardation: Market stress periods. Spot VIX spikes above futures as realized volatility jumps and mean reversion is expected.
The intuition for contango is similar to the volatility risk premium. Investors who are long equity portfolios want protection against volatility spikes, and they are willing to pay a premium for this protection. VIX futures sellers, who bear the risk of volatility spikes, demand compensation in the form of futures prices that are higher than expected future spot VIX levels. This premium manifests as an upward-sloping term structure.
During market stress, the relationship inverts. When volatility spikes, the spot VIX jumps immediately to reflect current fear and hedging demand. However, futures prices rise less because the market expects volatility to eventually mean-revert to more normal levels. This creates backwardation, with spot VIX above futures prices.
# Simulate VIX futures term structure
maturities = np.array([1, 2, 3, 4, 5, 6]) # Months to expiration
spot_vix = 18
# Contango scenario (normal markets)
vix_contango = spot_vix + 2 * np.sqrt(maturities)
# Backwardation scenario (market stress)
spot_vix_stress = 35
vix_backwardation = spot_vix_stress - 3 * np.sqrt(maturities)
vix_backwardation = np.maximum(vix_backwardation, 20) # Floor
The term structure typically exhibits contango, where longer-dated futures trade at a premium to spot, which reflects the cost of protection. During market stress, the curve flips to backwardation, with spot prices surging above futures as demand for immediate hedging spikes.
Roll Yield and VIX Products
The persistent contango in VIX futures creates a negative roll yield for long positions. As futures converge to spot at expiration, long positions in contango lose value from roll. This explains why long VIX ETFs like VXX have lost over 99% of their value since inception, despite VIX remaining in a range.
This decay is devastating for long-term holders. Consider a VIX ETF that maintains exposure to the front-month VIX futures contract. When the contract approaches expiration, the ETF must roll its position to the next month's contract. If the curve is in contango, this means selling the expiring contract at a lower price and buying the next month's contract at a higher price. This roll transaction locks in a loss, and if contango persists, these losses accumulate month after month, steadily eroding the ETF's value.
def simulate_vix_etf(
spot_vix_series, futures_premium_pct=0.05, days_between_rolls=21
):
"""
Simulate VIX ETF returns including roll cost.
Parameters:
- spot_vix_series: Daily spot VIX values
- futures_premium_pct: Average futures premium over spot (5% = contango)
- days_between_rolls: Number of days between roll events
"""
n_days = len(spot_vix_series)
etf_value = 100 # Start at $100
etf_values = [etf_value]
for i in range(1, n_days):
# Daily return from VIX movement
vix_return = (
spot_vix_series[i] - spot_vix_series[i - 1]
) / spot_vix_series[i - 1]
# Daily roll cost (spread over roll period)
daily_roll_cost = futures_premium_pct / days_between_rolls
# ETF return = VIX return - roll cost
etf_return = vix_return - daily_roll_cost
etf_value *= 1 + etf_return
etf_values.append(etf_value)
return np.array(etf_values)
# Simulate 2 years of VIX (mean-reverting process)
np.random.seed(42)
n_days = 504
kappa = 0.1 # Mean reversion speed
theta = 20 # Long-term mean
sigma_vix = 0.8 # VIX volatility
spot_vix = [20]
for _ in range(n_days - 1):
dW = np.random.normal(0, 1)
new_vix = (
spot_vix[-1]
+ kappa * (theta - spot_vix[-1])
+ sigma_vix * np.sqrt(spot_vix[-1]) * dW
)
spot_vix.append(max(new_vix, 10))
spot_vix = np.array(spot_vix)
# Simulate ETF tracking VIX with roll cost
etf_values = simulate_vix_etf(spot_vix)
total_return = (etf_values[-1] / etf_values[0] - 1) * 100
annualized_return = (
(etf_values[-1] / etf_values[0]) ** (252 / n_days) - 1
) * 100
VIX Range: 10.0 - 45.6 VIX Start/End: 20.0 / 17.7 Long VIX ETF Performance: Total Return: -73.9% Annualized Return: -48.9%
The lesson is clear: long volatility positions using VIX products require precise timing. They are hedging instruments, not investments.