Skip to content

Commit fa50579

Browse files
committed
update
1 parent 5763484 commit fa50579

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+19910
-456
lines changed

Bollinger bands yahoo finance.ipynb

+163
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import pandas_datareader as pdr
2+
from pandas_datareader import data, wb
3+
from datetime import date
4+
import numpy as np
5+
import pandas as pd
6+
from scipy import log,exp,sqrt,stats
7+
8+
def blackscholes_call(S,E,T,rf,sigma):
9+
#first we have to calculate d1 and d2 parameters
10+
d1=(log(S/E)+(rf+sigma*sigma/2.0)*T)/(sigma*sqrt(T))
11+
d2 = d1-sigma*sqrt(T)
12+
print(d1)
13+
print(d2)
14+
#we need N(x) normal distribution function
15+
return S*stats.norm.cdf(d1)-E*exp(-rf*T)*stats.norm.cdf(d2)
16+
17+
def blackscholes_put(S,E,T,rf,sigma):
18+
#first we have to calculate d1 and d2 parameters
19+
d1=(log(S/E)+(rf+sigma*sigma/2.0)*T)/(sigma*sqrt(T))
20+
d2 = d1-sigma*sqrt(T)
21+
#we need N(x) normal distribution function
22+
return -S*stats.norm.cdf(-d1)+E*exp(-rf*T)*stats.norm.cdf(-d2)
23+
24+
if __name__ == "__main__":
25+
26+
S0=100 #underlying stock price at t=0
27+
E=100 #strike price
28+
T = 1 #expiry 1=1year=365days
29+
rf = 0.05 #risk-free rate
30+
sigma=0.2 #volatility of the underlying stock
31+
32+
print("Call option price according to Black-Scholes model: ",blackscholes_call(S0,E,T,rf,sigma))
33+
print("Put option price according to Black-Scholes model: ",blackscholes_put(S0,E,T,rf,sigma))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import numpy as np
2+
import math
3+
import time
4+
5+
class OptionPricing:
6+
7+
def __init__(self,S0,E,T,rf,sigma,iterations):
8+
self.S0 = S0
9+
self.E = E
10+
self.T = T
11+
self.rf = rf
12+
self.sigma = sigma
13+
self.iterations = iterations
14+
15+
def call_option_simulation(self):
16+
17+
#we have 2 columns: first with 0s the second column will store the payoff
18+
#we need the first column of 0s: payoff function is max(0,S-E) for call option
19+
option_data = np.zeros([self.iterations, 2])
20+
21+
#dimensions: 1 dimensional array with as many items as the itrations
22+
rand = np.random.normal(0, 1, [1, self.iterations])
23+
24+
#equation for the S(t) stock price
25+
stock_price = self.S0*np.exp(self.T*(self.rf - 0.5*self.sigma**2)+self.sigma*np.sqrt(self.T)*rand)
26+
27+
#we need S-E because we have to calculate the max(S-E,0)
28+
option_data[:,1] = stock_price - self.E
29+
30+
#average for the Monte-Carlo method
31+
#np.amax() returns the max(0,S-E) according to the formula
32+
average = np.sum(np.amax(option_data, axis=1))/float(self.iterations)
33+
34+
#have to use the exp(-rT) discount factor
35+
return np.exp(-1.0*self.rf*self.T)*average
36+
37+
def put_option_simulation(self):
38+
39+
#we have 2 columns: first with 0s the second column will store the payoff
40+
#we need the first column of 0s: payoff function is max(0,E-S) for put option
41+
option_data = np.zeros([self.iterations, 2])
42+
43+
#dimensions: 1 dimensional array with as many items as the itrations
44+
rand = np.random.normal(0, 1, [1, self.iterations])
45+
46+
#equation for the S(t) stock price
47+
stock_price = self.S0*np.exp(self.T*(self.rf - 0.5*self.sigma**2)+self.sigma*np.sqrt(self.T)*rand)
48+
49+
#we need E-S because we have to calculate the max(E-S,0)
50+
option_data[:,1] = self.E - stock_price
51+
52+
#average for the Monte-Carlo method
53+
#np.amax() returns the max(0,E-S) according to the formula
54+
average = np.sum(np.amax(option_data, axis=1))/float(self.iterations)
55+
56+
#have to use the exp(-rT) discount factor
57+
return np.exp(-1.0*self.rf*self.T)*average
58+
59+
if __name__ == "__main__":
60+
61+
S0=100 #underlying stock price at t=0
62+
E=100 #strike price
63+
T = 1 #expiry
64+
rf = 0.05 #risk-free rate
65+
sigma=0.2 #volatility of the underlying stock
66+
iterations = 1000000 #number of iterations in the Monte-Carlo simulation
67+
68+
model = OptionPricing(S0,E,T,rf,sigma,iterations)
69+
print("Call option price with Monte-Carlo approach: ", model.call_option_simulation())
70+
print("Put option price with Monte-Carlo approach: ", model.put_option_simulation())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from math import exp
2+
3+
def zero_bond_price(par_value,market_rate,n):
4+
return par_value/(1+market_rate)**n
5+
6+
def bond_price(par_value,coupon, market_rate,n):
7+
c = par_value*coupon
8+
return c/market_rate*(1-(1/(1+market_rate)**n))+par_value/(1+market_rate)**n
9+
10+
if __name__ == "__main__":
11+
12+
par_value=1000 #par value of the bond
13+
coupon=0.05 #bond yield - coupon
14+
n=3 #years
15+
market_rate=0.04 #market rate of return
16+
17+
print("Price of the zero-coupon bond: $%0.2f" % zero_bond_price(par_value,market_rate,n))
18+
print("Price of the coupon bond: $%0.2f" % bond_price(par_value,coupon,market_rate,n))
19+
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import pandas_datareader as pdr
2+
from pandas_datareader import data, wb
3+
from datetime import date
4+
import numpy as np
5+
import matplotlib.pyplot as plt
6+
import pandas as pd
7+
8+
risk_free_rate = 0.05
9+
10+
def capm(start_date, end_date, ticker1, ticker2):
11+
12+
#get the data from Yahoo Finance
13+
stock1 = pdr.get_data_yahoo(ticker1, start_date, end_date)
14+
stock2 = pdr.get_data_yahoo(ticker2, start_date, end_date)
15+
16+
#we prefer monthly returns instead of daily returns
17+
return_stock1 = stock1.resample('M').last()
18+
return_stock2 = stock2.resample('M').last()
19+
20+
#creating a dataFrame from the data - Adjusted Closing Price is used as usual
21+
data = pd.DataFrame({'s_adjclose' : return_stock1['Adj Close'], 'm_adjclose' : return_stock2['Adj Close']}, index=return_stock1.index)
22+
#natural logarithm of the returns
23+
data[['s_returns', 'm_returns']] = np.log(data[['s_adjclose','m_adjclose']]/data[['s_adjclose','m_adjclose']].shift(1))
24+
#no need for NaN/missing values values so let's get rid of them
25+
data = data.dropna()
26+
27+
#covariance matrix: the diagonal items are the vairances - off diagonals are the covariances
28+
#the matrix is symmetric: cov[0,1] = cov[1,0] !!!
29+
covmat = np.cov(data["s_returns"], data["m_returns"])
30+
print(covmat)
31+
32+
#calculating beta according to the formula
33+
beta = covmat[0,1]/covmat[1,1]
34+
print("Beta from formula:", beta)
35+
36+
#using linear regression to fit a line to the data [stock_returns, market_returns] - slope is the beta
37+
beta,alpha = np.polyfit(data["m_returns"], data['s_returns'], deg=1)
38+
print("Beta from regression:", beta)
39+
40+
#plot
41+
fig,axis = plt.subplots(1,figsize=(20,10))
42+
axis.scatter(data["m_returns"], data['s_returns'], label="Data points")
43+
axis.plot(data["m_returns"], beta*data["m_returns"] + alpha, color='red', label="CAPM Line")
44+
plt.title('Capital Asset Pricing Model, finding alphas and betas')
45+
plt.xlabel('Market return $R_m$', fontsize=18)
46+
plt.ylabel('Stock return $R_a$')
47+
plt.text(0.08, 0.05, r'$R_a = \beta * R_m + \alpha$', fontsize=18)
48+
plt.legend()
49+
plt.grid(True)
50+
plt.show()
51+
52+
#calculate the expected return according to the CAPM formula
53+
expected_return = risk_free_rate + beta*(data["m_returns"].mean()*12-risk_free_rate)
54+
print("Expected return:", expected_return)
55+
56+
if __name__ == "__main__":
57+
#using historical data 2010-2017: the market is the S&P500 !!!
58+
capm('2010-01-01', '2017-01-01','IBM', '^GSPC')
59+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import numpy as np
2+
import pandas_datareader.data as web
3+
import matplotlib.pyplot as plt
4+
5+
stocks = ['AAPL']
6+
7+
start_date='01/01/2001'
8+
end_date='01/01/2017'
9+
10+
data = web.DataReader(stocks, data_source='yahoo', start=start_date, end=end_date)['Adj Close']
11+
12+
daily_returns = (data/data.shift(1))-1
13+
14+
daily_returns.hist(bins=100)
15+
plt.show()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
from __future__ import print_function
2+
3+
import datetime
4+
import numpy as np
5+
import pandas as pd
6+
import sklearn
7+
import pandas_datareader.data as web
8+
from sklearn.ensemble import RandomForestClassifier
9+
from sklearn.linear_model import LogisticRegression
10+
from sklearn.metrics import confusion_matrix
11+
from sklearn.svm import LinearSVC, SVC
12+
13+
14+
def create_lagged_series(symbol, start_date, end_date, lags=5):
15+
"""
16+
This creates a pandas DataFrame that stores the
17+
percentage returns of the adjusted closing value of
18+
a stock obtained from Yahoo Finance, along with a
19+
number of lagged returns from the prior trading days
20+
(lags defaults to 5 days). Trading volume, as well as
21+
the Direction from the previous day, are also included.
22+
"""
23+
24+
# Obtain stock information from Yahoo Finance
25+
ts = web.DataReader(
26+
symbol, "yahoo",
27+
start_date-datetime.timedelta(days=365),
28+
end_date
29+
)
30+
31+
# Create the new lagged DataFrame
32+
tslag = pd.DataFrame(index=ts.index)
33+
tslag["Today"] = ts["Adj Close"]
34+
tslag["Volume"] = ts["Volume"]
35+
36+
# Create the shifted lag series of prior trading period close values
37+
for i in range(0, lags):
38+
tslag["Lag%s" % str(i+1)] = ts["Adj Close"].shift(i+1)
39+
40+
# Create the returns DataFrame
41+
tsret = pd.DataFrame(index=tslag.index)
42+
tsret["Volume"] = tslag["Volume"]
43+
tsret["Today"] = tslag["Today"].pct_change()*100.0
44+
45+
# If any of the values of percentage returns equal zero, set them to
46+
# a small number (stops issues with QDA model in scikit-learn)
47+
for i,x in enumerate(tsret["Today"]):
48+
if (abs(x) < 0.0001):
49+
tsret["Today"][i] = 0.0001
50+
51+
# Create the lagged percentage returns columns
52+
for i in range(0, lags):
53+
tsret["Lag%s" % str(i+1)] = \
54+
tslag["Lag%s" % str(i+1)].pct_change()*100.0
55+
56+
# Create the "Direction" column (+1 or -1) indicating an up/down day
57+
tsret["Direction"] = np.sign(tsret["Today"])
58+
tsret = tsret[tsret.index >= start_date]
59+
60+
print(tsret)
61+
62+
return tsret
63+
64+
65+
if __name__ == "__main__":
66+
# Create a lagged series of the S&P500 US stock market index
67+
snpret = create_lagged_series(
68+
"^GSPC", datetime.datetime(2001,1,10),
69+
datetime.datetime(2005,12,31), lags=5
70+
)
71+
72+
# Use the prior two days of returns as predictor
73+
# values, with direction as the response
74+
X = snpret[["Lag1","Lag2"]]
75+
y = snpret["Direction"]
76+
77+
# The test data is split into two parts: Before and after 1st Jan 2005.
78+
start_test = datetime.datetime(2005,1,1)
79+
80+
# Create training and test sets
81+
X_train = X[X.index < start_test]
82+
X_test = X[X.index >= start_test]
83+
y_train = y[y.index < start_test]
84+
y_test = y[y.index >= start_test]
85+
86+
# Create the (parametrised) models
87+
print("Hit Rates/Confusion Matrices:\n")
88+
models = [("LR", LogisticRegression()),
89+
("LSVC", LinearSVC()),
90+
("RSVM", SVC(
91+
C=1000000.0, cache_size=200, class_weight=None,
92+
coef0=0.0, degree=3, gamma=0.0001, kernel='rbf',
93+
max_iter=-1, probability=False, random_state=None,
94+
shrinking=True, tol=0.001, verbose=False)
95+
),
96+
("RF", RandomForestClassifier(
97+
n_estimators=1000, criterion='gini',
98+
max_depth=None, min_samples_split=2,
99+
min_samples_leaf=1, max_features='auto',
100+
bootstrap=True, oob_score=False, n_jobs=1,
101+
random_state=None, verbose=0)
102+
)]
103+
104+
# Iterate through the models
105+
for m in models:
106+
107+
# Train each of the models on the training set
108+
m[1].fit(X_train, y_train)
109+
110+
# Make an array of predictions on the test set
111+
pred = m[1].predict(X_test)
112+
113+
# Output the hit-rate and the confusion matrix for each model
114+
print("%s:\n%0.3f" % (m[0], m[1].score(X_test, y_test)))
115+
print("%s\n" % confusion_matrix(pred, y_test))

0 commit comments

Comments
 (0)