Created
February 8, 2021 14:31
-
-
Save juangesino/53f3d6f33a486aa026ed92940f204531 to your computer and use it in GitHub Desktop.
Bayesian CAPM Beta Estimation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pymc3 as pm | |
X = stocks["AMZN"]["X"].values | |
y = stocks["AMZN"]["y"].values | |
with pm.Model() as model_1: | |
alpha = pm.Normal("alpha", mu=0, sigma=1) | |
beta = pm.Normal("beta", mu=0, sigma=1) | |
exp_returns = pm.Deterministic("exp_returns", alpha + beta * X) | |
noise = pm.HalfNormal("noise", sigma=1) | |
returns = pm.Normal("returns", mu=exp_returns, sigma=noise, observed=y) | |
trace_1 = pm.sample(tune=1500) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
beta_samples = trace_1["beta"] | |
np.mean(beta_samples > 1.2) | |
# => 0.32125 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import statsmodels.api as sm | |
X = stocks["AMZN"]["X"].values | |
y = stocks["AMZN"]["y"].values | |
X = sm.add_constant(X) | |
model = sm.OLS(y, X) | |
results = model.fit() | |
model.data.xnames = ["alpha", "beta"] | |
print(results.summary()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Tickers to get data | |
tickers = ["MSFT", "GOOG", "AMZN", "FB"] | |
# Add S&P 500 | |
tickers.append("^GSPC") | |
# Download data from Yahoo Finance | |
data = yf.download( | |
" ".join(tickers), | |
period = "5y", | |
interval = "1mo", | |
group_by = "ticker", | |
) | |
# Store the S&P 500 data | |
market = data["^GSPC"].dropna().reset_index().set_index("Date") | |
tickers.remove("^GSPC") | |
# Get the data for each stock | |
stocks = {} | |
for ticker in tickers: | |
stock_data = data[ticker].dropna().reset_index().set_index("Date") | |
monthly_prices = pd.concat([stock_data["Close"], market["Close"]], axis=1) | |
monthly_prices.columns = [ticker, "market"] | |
monthly_returns = monthly_prices.pct_change(1).dropna(axis=0) | |
stocks[ticker] = { | |
"data": stock_data, | |
"monthly_prices": monthly_prices, | |
"monthly_returns": monthly_returns, | |
"X": monthly_returns["market"], | |
"y": monthly_returns[ticker] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for ticker in stocks.keys(): | |
X = stocks[ticker]["X"].values | |
y = stocks[ticker]["y"].values | |
X = sm.add_constant(X) | |
model = sm.OLS(y, X) | |
results = model.fit() | |
print(f"{ticker}: ", results.params[1]) |
Stock | Yahoo! Finance | OLS | Bayesian |
---|---|---|---|
MSFT | 0.83 | 0.808 | 0.65 - 0.90 (72%) |
GOOG | 0.99 | 0.981 | 0.80 - 1.10 (76%) |
AMZN | 1.20 | 1.152 | 0.90 - 1.30 (70%) |
FB | 1.18 | 1.266 | 1.00 - 1.40 (73%) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment