A Walk Through Randomness- Forecasting Stock Price With Geometric Brownian Motion through Excel & Python
Vaidyanathan Ravichandran
Professor of Practice (Finance) - Business Schools , Bangalore
Brownian Motion (BM):
History:
In 1827, Robert Brown, a botanist reported that grains of pollen suspended in a liquid moved randomly from one place to other. The random (Zig - Zag path) motion of pollen suspended in a liquid is called Brownian motion. In fact we can observe the dust particles in water moving in random directions. This discovery puzzled scientists for a long time. There were a lot of explanations for pollen or dust to move in random directions but none of these explanations were found adequate.
After a systematic study, Wiener and Gouy proposed that Brownian motion is due to the bombardment of suspended particles by molecules of the surrounding fluid. But during the 19th century people did not accept that every matter is made up of small atoms or molecules. In the year 1905, Einstein gave the systematic theory of Brownian motion based on kinetic theory and he deduced the average size of molecules.
Albert Einstein (1905): Albert Einstein provided a mathematical description of Brownian motion, explaining it as the result of the random collisions of particles with molecules of the fluid they are suspended in. His work laid the groundwork for the mathematical modeling of random processes.
Mathematical Formalization: Norbert Wiener (1923): Wiener rigorously formulated the mathematical theory of Brownian motion, leading to the creation of what is now known as the Wiener process. This stochastic process is a cornerstone of continuous-time stochastic models, including GBM.
Development of Geometric Brownian Motion:
Louis Bachelier (1900): In his doctoral thesis, "Théorie de la spéculation," Louis Bachelier introduced the idea of modeling stock prices as a random walk. Although his model did not account for the exponential nature of stock prices, it was a pioneering work in financial mathematics.
Paul Samuelson (1965): Paul Samuelson is credited with the development of the GBM model for stock prices. He proposed that stock prices follow a log-normal distribution, implying that the logarithm of stock prices follows a Brownian motion with drift. This addressed the need to model stock prices as non-negative and to capture the exponential growth of financial assets.
Black-Scholes Model: Fischer Black, Myron Scholes, and Robert Merton (1973): Building on Samuelson’s work, Fischer Black, Myron Scholes, and Robert Merton used GBM to develop the Black-Scholes model for pricing European options. Their groundbreaking work provided a closed-form solution for option pricing and demonstrated the practical application of GBM in financial markets. The Black-Scholes model earned Merton and Scholes the Nobel Prize in Economic Sciences in 1997 (Black had passed away in 1995).
What is Stochastic Process?
A stochastic process is a mathematical object used to model systems or phenomena that evolve over-time in a way that incorporates randomness. It is essentially a collection of random variables indexed by time or space, representing the evolution of some system that is subject to uncertainty.
Examples of Stochastic Processes:
Brownian Motion (Wiener Process): A continuous-time stochastic process with continuous paths that exhibits Gaussian increments and is used to model random motion, such as the movement of particles suspended in fluid.
Poisson Process: A counting process that models the occurrence of events happening independently over time, commonly used in queuing theory and telecommunications.
Markov Process: A stochastic process that has the Markov property, meaning the future state depends only on the present state and not on the past states. Examples include Markov chains (discrete-time) and continuous-time Markov processes.
Geometric Brownian Motion (GBM): A continuous-time process where the logarithm of the variable follows a Brownian motion with drift. It is widely used to model stock prices in finance and option prices.
Applications of Stochastic Process:
·????? Finance: Modelling asset prices, interest rates, and derivative pricing.
·????? Queueing Theory: Analysing waiting lines and service systems.
·????? Physics: Describing particle movements and diffusion processes.
·????? Biology: Modelling population dynamics and gene frequency changes.
·????? Economics: Representing economic variables and business cycles.
In essence, a stochastic process provides a framework to model and analyze systems that evolve with inherent randomness, enabling predictions and understanding of such systems in various fields.
Random Walks:
Applications and Extensions of GBM:
Geometric Brownian Motion (GBM)
Geometric Brownian Motion (GBM) is a mathematical model used to describe the random fluctuations of a variable over time. It's particularly important in finance for modeling stock prices.
Connection to BM: GBM is inspired by Brownian motion but with a crucial difference. GBM deals with positive values only, making it suitable for modeling stock prices that can't go negative.
It essentially models the logarithm of the underlying variable (like stock price) following a standard Brownian motion process. This means the price changes are random but proportional to the current price itself.
Applications: GBM is a cornerstone of financial modeling. It's the foundation for the Black-Scholes model, a widely used method for option pricing. It helps assess risk associated with stock price movements by simulating potential future price ranges.
Other Applications: GBM can also model population growth, biological processes, and even engineering systems with random fluctuations.
Properties:
1.??? Continuous-time process: GBM evolves continuously over time.
2.??? Stochastic process: It involves random elements, making predictions probabilistic.
3.??? Drift and Volatility: The model incorporates two key parameters:
GBM and Financial Risk:
By simulating GBM paths, financiers can estimate the potential range of future stock prices. This helps assess the Value at Risk (VaR), a metric for potential losses over a specific time horizon.
GBM allows for calculating option prices, which are essentially financial contracts that give the right, but not the obligation, to buy or sell a stock at a certain price by a certain time.
Difference between Geometric Brownian Motion and Monte Carlo Simulation
Monte Carlo simulation is a computational technique that uses random sampling to solve mathematical problems by running simulations many times over to calculate the probability distribution of possible outcomes.
We will discuss more on Monte-Carlo Simulation in a subsequent newsletter.
Characteristics of Monte Carlo simulation:
It is a general method applicable to various types of models and problems, not limited to financial markets. It can model complex systems and processes with uncertainty by simulating multiple possible scenarios. Monte Carlo simulation can incorporate time-varying parameters and allows for the incorporation of various types of random variables and distributions.
Usage: In finance, Monte Carlo simulation is used to model the uncertainty of asset prices, portfolio returns, and other financial variables. It is also used in risk analysis and optimization.
Key Differences Between GBM vs Montecarlo
Model vs. Simulation: GBM is a specific model used to describe the evolution of a stock price over time, while Monte Carlo simulation is a method used to generate possible future scenarios or outcomes based on a model (which could include GBM or other models).
Stochastic Nature: GBM assumes a specific stochastic process for the stock price, whereas Monte Carlo simulation can incorporate a variety of stochastic processes and random variables.
Application: GBM is primarily used for modelling stock prices and option pricing, whereas Monte Carlo simulation is a broader technique used across various fields including finance, engineering, and physics.
领英推荐
Implementation of GBM in Python – Simple example
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
def gbm_sim(S0, mu, sigma, T, n_steps):
dt = T / n_steps
dW = np.random.normal(size=n_steps)
ln_S = np.log(S0) + (mu - sigma**2/2) * T + sigma * np.sqrt(dt) * dW
S = np.exp(ln_S)
return S
# Example usage
S0 = 100 # Initial price
mu = 0.05 # Drift
sigma = 0.2 # Volatility
T = 1 # Time horizon
n_steps = 100
simulated_prices = gbm_sim(S0, mu, sigma, T, n_steps)
# Plot the simulated price path
plt.plot(np.linspace(0, T, n_steps+1), np.concatenate((np.array([S0]), simulated_prices)))
plt.xlabel("Time")
plt.ylabel("Stock Price")
plt.title("Simulated Geometric Brownian Motion Path")
plt.show()
Monte Carlo Simulation Example:
def monte_carlo_gbm(S0, mu, sigma, T, num_simulations, dt=1/252):
N = int(T / dt)
simulations = np.zeros((num_simulations, N))
for i in range(num_simulations):
simulations[i, :] = simulate_gbm(S0, mu, sigma, T, dt)
return simulations
# Parameters
num_simulations = 1000 # number of simulated paths
# Perform Monte Carlo simulation
mc_simulations = monte_carlo_gbm(S0, mu, sigma, T, num_simulations)
# Plot a few simulated paths
plt.figure(figsize=(10, 6))
for i in range(min(num_simulations, 10)):
plt.plot(mc_simulations[i, :], lw=0.5)
plt.title('Monte Carlo Simulation of GBM')
plt.xlabel('Time Steps')
plt.ylabel('Stock Price')
plt.show()
# Calculate statistics of the simulated paths at the final time step
final_prices = mc_simulations[:, -1]
mean_final_price = np.mean(final_prices)
std_final_price = np.std(final_prices)
print(f"Mean Final Price: {mean_final_price}")
print(f"Standard Deviation of Final Price: {std_final_price}")
# Plot the distribution of final prices
plt.figure(figsize=(10, 6))
plt.hist(final_prices, bins=50, density=True, alpha=0.75)
plt.title('Distribution of Final Stock Prices (Monte Carlo Simulation)')
plt.xlabel('Final Stock Price')
plt.ylabel('Density')
plt.show()
Output: Monte-Carlo Simulation
Mean Final Price: 105.07220597350072
Standard Deviation of Final Price: 21.99080828606861
?Approach for Simulation of Stock Prices Using Geometric Brownian Motion
“A geometric Brownian motion (GBM) (also known as exponential Brownian motion) is a continuous-time stochastic process in which the logarithm of the randomly varying quantity follows a Brownian motion (also called a Wiener process) with drift” ?It is an important example of stochastic processes satisfying a stochastic differential equation (SDE)
A stochastic process St is said to follow a GBM if it satisfies the following stochastic differential equation (SDE):
For an arbitrary initial value S0 (Current asset price),
Define Parameters
?Mathematically, the Wiener process can be defined as: ??(??)~??(0,??) where ??(0,??) denotes a normal distribution with mean 0 and variance ??.
?Steps for simulation of Stock Prices using GBM in Excel:
Steps:
1/ Download stock price data (say for daily prices ) for a chosen period (say 5 years) you may use stock history function in Excel
2/Calculate log returns of stock prices
3/ Calculate (Mu) returns of the stock prices: Exp(Average(Log returns))-1
?4/ Calculate standard deviation (Sigma)
?5/ Use the below GBM : SDE equation, Populate columns as below:
Diffusion (Weiner process): Sigma * Normsinv(Rand()) * t
?Graphically show the simulated Prices & Returns (next 21 days chosen)
Finally using the simulated prices : max, min, mean, stdev, create a normal distribution -> Use Normdist(X,Mean,Stdev,False) as below
Application -Stock price simulation using Python code for a chosen stock price and chosen historical data for Mean, standard deviation calculation
Derive the stock prices – simulation for the next 21 days and show the distribution using the simulated data
Run the below code in google.cholab , choose any listed stock ,Choose any period , start date, end date ,wait for the output
?
import yfinance as yf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import norm
def get_nifty_tickers():
tickers = [
'ADANIENT.NS', 'ADANIPORTS.NS', 'APOLLOHOSP.NS', 'ASIANPAINT.NS', 'AXISBANK.NS',
'BAJAJ-AUTO.NS', 'BAJFINANCE.NS', 'BAJAJFINSV.NS', 'BPCL.NS', 'BHARTIARTL.NS',
'BRITANNIA.NS', 'CIPLA.NS', 'COALINDIA.NS', 'DIVISLAB.NS', 'DRREDDY.NS',
'EICHERMOT.NS', 'GRASIM.NS', 'HCLTECH.NS', 'HDFCBANK.NS', 'HDFCLIFE.NS',
'HEROMOTOCO.NS', 'HINDALCO.NS', 'HINDUNILVR.NS', 'ICICIBANK.NS', 'ITC.NS',
'INDUSINDBK.NS', 'INFY.NS', 'JSWSTEEL.NS', 'KOTAKBANK.NS', 'LTIM.NS',
'LT.NS', 'M&M.NS', 'MARUTI.NS', 'NTPC.NS', 'NESTLEIND.NS',
'ONGC.NS', 'POWERGRID.NS', 'RELIANCE.NS', 'SBILIFE.NS', 'SHRIRAMFIN.NS',
'SBIN.NS', 'SUNPHARMA.NS', 'TCS.NS', 'TATACONSUM.NS', 'TATAMOTORS.NS',
'TATASTEEL.NS', 'TECHM.NS', 'TITAN.NS', 'ULTRACEMCO.NS', 'WIPRO.NS',
'^NSEI', '^NSEBANK', '^NSMIDCP150'
]
return tickers
def fetch_stock_data(ticker, start_date, end_date):
stock_data = yf.download(ticker, start=start_date, end=end_date)
return stock_data
def calculate_drift_and_volatility(stock_data):
log_returns = np.log(stock_data['Adj Close'] / stock_data['Adj Close'].shift(1))
drift = log_returns.mean() * 252 # Annualized drift
variance = log_returns.var() * 252 # Annualized variance
stdev = log_returns.std() * np.sqrt(252) # Annualized standard deviation
return drift, stdev
def simulate_gbm(S0, drift, stdev, T, dt=1/252):
num_steps = int(T / dt)
time = np.linspace(0, T, num_steps)
W = np.random.standard_normal(size=num_steps)
W = np.cumsum(W) * np.sqrt(dt) # Wiener process
X = (drift - 0.5 * stdev**2) * time + stdev * W
S = S0 * np.exp(X)
return S
def main():
# List Nifty 50 stocks and indices and ask user to select one
tickers = get_nifty_tickers()
for i, ticker in enumerate(tickers):
print(f"{i + 1}. {ticker}")
user_choice = int(input("Choose a stock by entering its number: ")) - 1
ticker = tickers[user_choice]
# Get start and end date from the user
start_date = input("Enter the start date (YYYY-MM-DD): ")
end_date = input("Enter the end date (YYYY-MM-DD): ")
# Fetch stock data
stock_data = fetch_stock_data(ticker, start_date, end_date)
S0 = stock_data['Adj Close'][-1]
# Calculate drift and volatility
drift, stdev = calculate_drift_and_volatility(stock_data)
# Forecast for the next 21 days
forecast_days = 21
T = forecast_days / 252 # 252 trading days in a year
simulated_prices = simulate_gbm(S0, drift, stdev, T)
# Calculate statistics
avg_price = np.mean(simulated_prices)
stdev_price = np.std(simulated_prices)
min_price = np.min(simulated_prices)
max_price = np.max(simulated_prices)
print(f"Average Price: {avg_price}")
print(f"Standard Deviation: {stdev_price}")
print(f"Min Price: {min_price}")
print(f"Max Price: {max_price}")
# Plot the simulated prices
plt.figure(figsize=(10, 6))
plt.plot(simulated_prices, label=f'Simulated Prices for {ticker}')
plt.title(f'Geometric Brownian Motion Simulation for {ticker}')
plt.xlabel('Days')
plt.ylabel('Price')
plt.legend()
plt.show()
# Generate and plot normal distribution
x = np.linspace(min_price, max_price, 100)
y = norm.pdf(x, avg_price, stdev_price)
plt.figure(figsize=(10, 6))
plt.plot(x, y, label='Normal Distribution')
plt.title(f'Normal Distribution of Forecasted Prices for {ticker}')
plt.xlabel('Price')
plt.ylabel('Probability Density')
plt.legend()
plt.show()
if __name__ == "__main__":
main()
Choose a stock by entering its number: 51 Enter the start date (YYYY-MM-DD): 2014-01-01 Enter the end date (YYYY-MM-DD): 2024-05-24 Average Price: 24794.65901317353 Standard Deviation: 821.6963103748861 Min Price: 23459.146119621535 Max Price: 26359.8538407232
?
?
?
Designation : Assistant Professor Interest area : Accounts, Finance, International Finance, and Derivatives
9 个月Sir, your explanation of another effective method for stock predictions is beautifully done. Thank you!
Senior Data Scientist at S&P Global | BITS Pilani
9 个月Very valuable concepts in simple to understand flow.