-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGBM.py
72 lines (51 loc) · 2.31 KB
/
GBM.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# Import modules
import yfinance as yf
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from datetime import datetime as dt
import datetime as dt1
import pandas_market_calendars as mcal
import astropy as ast
from astropy.modeling import models, fitting
# Uses parameter data to return historical drift and volatility coefficients for GBM
def initialGBMGuess(parameterData):
# Stores the daily log returns
logReturns = (np.log(parameterData.pct_change()+1))
sigma=(logReturns.std()).iloc[0]
mu=(logReturns.mean()).iloc[0]
return [mu, sigma]
# Estimates the parameters using maximum likelihood estimation (MLE)
def calculateGBMParameters(parameterList, parameterData):
logLikelihood=[]
logReturns = (np.log(parameterData.pct_change()+1))
residuals = logReturns - parameterList[0]
for i in range(1,len(parameterData)):
# Joint PDF of asset prices and volatility (Log-Likelihood)
jointPdf = 1/(np.sqrt(2*np.pi)*parameterList[1])*np.exp(-1/2*((residuals.iloc[i][0]/parameterList[1])**2))
# Penalize for parameter sets that give errors (ln(negative))
if jointPdf <= 0:
logLikelihood.append(-1000)
else:
logLikelihood.append(np.log(jointPdf))
return -sum(logLikelihood) # Maximizing logLikelihood is the same as minimizing -logLikelihood
# Conducts the Monte-Carlo Simulation
def gbmSimulation(parameterList, M, forecastData, forecastDays):
mu = parameterList[0]
sigma = parameterList[1]
# Sets initial stock adjusted price
S0=forecastData['Adj Close'].iloc[0]
# Number of Steps
n = forecastDays
# Daily discretized time step
T = n
# Calculates each time step
dt = T/n
# GBM model with normally distributed Wiener Process. Simulation is done using Arrays, which is more efficient than using a loop.
St = np.exp((mu* dt) + sigma * np.random.normal(0, np.sqrt(dt), size=(M,n)).T)
St = np.vstack([np.ones(M), St])
# This will calculate the cumulative return at each time step, for each simulation. Multiplying through by S0 will change the St matrix from returns to stock prices.
St = St.cumprod(axis=0)
St = S0*St
a=St[-1,:]-St[-2,:]
return n, T, M, S0, St