Skip to content
← All articles
Article

Predicting Stock Prices with Monte Carlo Simulations

Listen to the audio story

A range, not a price · 2:01 · AI-written script, synthetic voices

Transcript

Ava: If someone tells you Apple will close at one exact price next year, don't believe them. Antoine's take: trading is about ranges, not one magic number.

Andrew: So how do you get a range?

Ava: Monte Carlo simulation. He took Apple's daily closing prices and estimated the average drift and volatility of the log returns, using only data before 2023. Then he simulated many possible price paths forward.

Andrew: And then you check it against what really happened.

Ava: Exactly. 2023 was the hold-out year. Did the real prices fall inside the band between the fifth and ninety-fifth percentile of the simulated paths?

Andrew: How does the simulation work, in plain words?

Ava: Each day, draw a random shock from a normal distribution, scale it by the volatility, add the drift, and multiply the price by the exponential of that. There's a small correction, called the Itô correction, so the simulated average doesn't climb faster than history justifies.

Andrew: Give me a number.

Ava: For Apple, the mean simulated price after three hundred and sixty-four days was two hundred and six dollars and sixty-three cents. The real close on the twenty-ninth of December, 2023 was one ninety-two fifty-three. A gap of fourteen dollars ten, or about seven percent.

Andrew: Not bad, but not magic.

Ava: And a later run on Microsoft with 2024 closes missed by about fourteen percent. That's the reminder: a band built on past volatility says nothing about a company being re-rated.

Andrew: What does he say the model can't do?

Ava: Volatility isn't constant, there are no jumps like earnings gaps, and it ignores diversification. He also separates this from MCMC, which fits a distribution first. This one is the forward-simulation step.

Andrew: So the takeaway?

Ava: Monte Carlo measures how wide the model's risk is. Backtesting measures what a trading rule would have earned. Keep those questions apart. The full write-up has the code and the fan charts.

Predicting Stock Prices with Monte Carlo Simulations
Table of contents

Trading is about ranges, not one magic price. I used forward Monte Carlo on Apple daily closes: estimate log-return drift and volatility before 2023, simulate many paths, then check whether 2023 hold-out prices fell inside a 5th–95th percentile band.

1. Forward Monte Carlo vs MCMC

ToolQuestion it answers
Forward Monte Carlo (this post)“How wide could prices swing under a simple GBM-style model?”
MCMC (e.g. Landauskas & Valakevičius KDE sampling)“What distribution fits observed prices before simulating?”

You can combine them: fit with MCMC, explore scenarios with forward paths. This article implements the forward step in Python; AlgoETS/MarkokChainMonteCarlo[1] explores MCMC-oriented experiments.

2. Setup

Libraries: pandas, numpy, httpx, matplotlib, scipy, rich, optional backtesting / pandas_ta for related charts. Historical prices via Financial Modeling Prep API helpers in the original notebook.

3. Train / hold-out split

Pull full history for AAPL, split at 2023-01-01:

  • Train — estimate mean/variance of log returns.
  • Hold-out — compare simulated bands to realized closes.

Train vs hold-out price series

The same split for AAPL, GOOGL and MSFT shows how differently the three names moved after January 2023:

AAPL, GOOGL and MSFT before and after 2023

4. The simulation core

Estimate log returns on train window → daily drift and volatility → draw Gaussian shocks → propagate price with exp(drift + vol * Z).

def monte_carlo_simulation(data, days, iterations):
    if isinstance(data, pd.Series):
        data = data.to_numpy()
    if not isinstance(data, np.ndarray):
        raise TypeError("Data must be a numpy array or pandas Series")

    log_returns = np.log(data[1:] / data[:-1])
    mean = np.mean(log_returns)
    variance = np.var(log_returns)
    drift = mean - (0.5 * variance)
    daily_volatility = np.std(log_returns)

    future_prices = np.zeros((days, iterations))
    current_price = data[-1]
    for t in range(days):
        shocks = drift + daily_volatility * norm.ppf(np.random.rand(iterations))
        future_prices[t] = current_price * np.exp(shocks)
        current_price = future_prices[t]
    return future_prices

norm.ppf(np.random.rand(iterations)) turns uniform draws into standard normal shocks, so each row of future_prices is one trading day across every simulated path. The - 0.5 * variance term is the Itô correction: without it, the mean of exp(shock) would drift upward faster than the historical returns justify.

Simulated price paths from the training window

Data download helpers and plotting loops: Medium original[2].

5. Reading the output

  • Fan of gray paths — scenario diversity.
  • Median and mean paths — central tendency (not identical under skew).
  • 5th–95th band — risk-style interval for “where might price land.”
  • Hold-out dot — did reality sit inside the band at the aligned horizon?

Percentile band and simulated paths

For AAPL, the mean simulated price after 364 days was $206.63 against a real close of $192.53 on 2023-12-29: a gap of $14.10, or 7.32 %.

Mean simulated price against the real 2023-12-29 close

A later run for AAPL and MSFT, with the 2024 closes as the check, gives wider fans. The MSFT mean missed by about 14 %, which is a reminder that a band built on past volatility says nothing about a re-rating.

AAPL forecast fan

MSFT forecast fan

Terminal distribution gives quantile prices and simple return percentiles vs last train close — useful for “how wrong is the model?” not “buy signal.”

6. When not to use GBM Monte Carlo alone

LimitationReality
Constant volMarkets cluster volatility
No jumpsEarnings gaps exist
Single nameDiversification ignored
Not a strategy testPair with backtesting posts

7. Takeaway

Monte Carlo answers model risk width on a hold-out window; backtesting answers rule PnL. Keep the questions separate.

9. Reference


Originally published on Medium[2]. Notebook code: see repo and Medium for full listings.

References

  1. AlgoETS. (). MarkokChainMonteCarlo. [Software repository] github.com.
  2. Medium original. (). [Article] medium.com.
  3. Modelling of Stock Prices by MCMC. (). [Web page] ojs.mruni.eu.
  4. Investopedia — Monte Carlo basics. (). [Web page] www.investopedia.com.

References use this article’s publication date.