Back To Top

August 14, 2025

Price Forecasting with GBM and IV

Deriving Future Price Confidence Intervals with Log-normal Paths using IV, Shrinkage-adjusted Drift, and EWMA Returns

With just historical returns and option-implied volatility, you can model realistic price bands using Geometric Brownian Motion.

GBM lets us generate forward-looking price scenarios that reflect both time-varying uncertainty and the compounding nature of asset returns.

Here, we’ll build a probabilistic forecast model for SPY which integrates market-based volatility with adaptive drift to simulate confidence intervals.

The complete Python notebook for the analysis is provided below.

Price Forecasting with GBM and IV

1. GBM for Price Forecasting

Geometric Brownian Motion balances simplicity with theoretical soundness when modeling future price distributions.

GBM assumes that asset prices follow a log-normal process, meaning the logarithm of the price evolves as a Wiener process with drift.

This is a foundational assumption in option pricing theory, most notably the Black-Scholes model.

In the context of forecasting, it allows us to generate forward price scenarios that incorporate both compounding returns and increasing uncertainty over time.

Price Forecasting with GBM and IV
  • St​ is the asset price at time t
  • μ is the drift term (expected return)
  • σ is the volatility (standard deviation of returns)
  • Wt​ is a Wiener process (standard Brownian motion)

Solving this stochastic differential equation gives the following form for simulating future prices:

Price Forecasting with GBM and IV

Here, S0​ is the current price, and Z∼N(0,1) is a standard normal random variable.

The model has two key inputs: 1. Drift (μ): expected rate of return (average directional movement). 2. Volatility (σ): reflects the expected variability or risk.

In practice, we’ll estimate the drift using a smoothed version of historical returns and combine it with the risk-free rate using a shrinkage approach.

For volatility, we’ll use ATM implied volatility from SPY options as a market-implied measure of future uncertainty, rather than relying on historical variance.

Since implied volatility often overestimates future realized volatility, the resulting forecasts tend to be wider, more conservative and risk aware.

2. Price Data and Parameters

To build a forward-looking price forecast, we need two things: historical data to estimate drift, and parameter settings that control the simulation.

We’ll use daily closing prices for SPY. Data is pulled from Yahoo Finance from January 1, 2020, to June 15, 2025.

This 5 year window provides a sufficiently rich sample to compute stable return estimates, but still keep the model responsive to recent trends.

The functionality of each parameter is defined below.

				
					import numpy as np
import pandas as pd
import yfinance as yf
from scipy.stats import norm
import matplotlib.pyplot as plt

# Parameters
TICKER = 'SPY'               # Ticker symbol for the asset (can be changed to any tradable equity or ETF)
START = '2020-01-01'         # Start date for historical price data
END = '2025-06-15'           # End date for historical price data
INTERVAL = '1d'              # Price data frequency; use '1d' for daily returns (works best for GBM modeling)

LEN = 100                    # Span for EWMA drift estimation; higher = smoother trend, lower = more sensitivity to recent changes
SMOOTH_LEN = 20              # Placeholder for optional smoothing (not used); can be repurposed for volatility smoothing
FORECAST_LEN = 100           # Number of trading days to forecast; longer = wider bands, more uncertainty in projections
CONF_LEVELS = [68, 80, 90]   # Confidence intervals; increasing these adds wider bounds to capture more extreme outcomes
SHRINK_WEIGHT = 0.8          # Blend weight for EWMA drift vs. risk-free rate; closer to 1 = follow market trend, closer to 0 = conservative baseline
RISK_FREE_RATE = 0.04        # Annualized risk-free rate; used as a stabilizer for drift and anchor when returns are volatile or unreliable
				
			

From the price series, we calculate daily log returns, defined as:

Price Forecasting with GBM and IV

Log returns are additive over time and align with the continuous compounding assumption used in GBM.

				
					# Download historical data
df = yf.download(
    TICKER, start=START, end=END,
    interval=INTERVAL,
    auto_adjust=True, progress=False, threads=False
)
if isinstance(df.columns, pd.MultiIndex):
    df.columns = df.columns.get_level_values(0)

# Log returns
daily_ret = np.log(df['Close'] / df['Close'].shift(1)).dropna()
				
			

3. Estimating Drift Using EWMA and Shrinkage

In the GBM model, the drift term μ represents the directional component of price evolution, i.e. the part that determines whether prices tend to rise, fall, or stay flat over time.

A simple estimate of drift would be the average of historical log returns. But this has two problems:

  • It treats old returns as equally important as recent ones.
  • It’s noisy and unstable over short lookback periods.

Instead, we use an Exponentially Weighted Moving Average of log returns.

This gives more weight to recent data while and still capture longer-term trends. The EWMA drift is computed recursively using:

Price Forecasting with GBM and IV

Where:

  • rt−1​ is the most recent log return
  • μEWMA,t−1​ is the previous EWMA estimate
  • α=2/(span+1) is the smoothing factor derived from the span

The span parameter controls sensitivity.

A larger span produces a smoother, more stable trend. A smaller span reacts faster to recent market moves but can overfit short-term noise.

Even so, relying solely on past returns can be risky, especially when markets mean-revert or shift regimes.

To stabilize our estimate, we apply shrinkage toward the daily risk-free rate, calculated as:

Price Forecasting with GBM and IV

We combine the two using a shrinkage weight w:

Price Forecasting with GBM and IV

This lets us balance responsiveness with robustness.

When w=1, we fully trust historical returns. When w=0, we default to the neutral baseline.

A value like w=0.8 leans toward adaptive behavior and still stay grounded.

Prev Post

Mapping Price Interest with Logistic Filters

Next Post

16 Volatility-Options Facts

post-bars
Mail Icon

Newsletter

Get Every Weekly Update & Insights

[mc4wp_form id=]

Leave a Comment