Created
August 25, 2023 22:37
-
-
Save jtrecenti/df48b1f75af41f8fd047ba3ef48e6d92 to your computer and use it in GitHub Desktop.
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
######################################## | |
# Time-varying parameter CAPM | |
######################################## | |
library(ggplot2) | |
library(BatchGetSymbols) | |
library(dplyr) | |
library(tidyr) | |
library(dlm) | |
ticker_symbols <- c('AMZN','NFLX','^GSPC') | |
start_date <- '2015-01-01' | |
# Getting data from APIs | |
data = yfR::yf_get(ticker_symbols, | |
first_date = start_date, | |
last_date = Sys.Date(), | |
bench_ticker = "^GSPC", | |
type_return = "log") | |
# data = BatchGetSymbols(ticker_symbols, | |
# first.date = start_date, | |
# last.date = Sys.Date(), | |
# bench.ticker = "^GSPC", | |
# type.return = "log", | |
# freq.data = "daily", | |
# do.complete.data = TRUE, | |
# do.fill.missing.prices = TRUE) | |
df.tickers <- data %>% | |
filter(volume!=0) | |
p <- ggplot(df.tickers, aes(x=ref_date, y=price_close, group=ticker)) + | |
geom_line(aes(color=ticker))+ | |
geom_point(aes(color=ticker))+ | |
theme(legend.position="top")+ | |
xlab('Data')+ylab('$') | |
p | |
r <- ggplot(df.tickers, aes(x=ref_date, y=ret_closing_prices, group=ticker)) + | |
geom_line(aes(color=ticker))+ | |
geom_point(aes(color=ticker))+ | |
theme(legend.position="top")+ | |
xlab('Data')+ylab('$') | |
r | |
# Static CAPM | |
ret_amazon <- df.tickers %>% | |
dplyr::select(ticker,ret_closing_prices) %>% | |
dplyr::filter(ticker == 'AMZN') %>% | |
drop_na(ret_closing_prices) | |
ret_netflix <- df.tickers %>% | |
dplyr::select(ticker,ret_closing_prices) %>% | |
dplyr::filter(ticker == 'NFLX') %>% | |
drop_na(ret_closing_prices) | |
ret_sp500 <- df.tickers %>% | |
dplyr::select(ticker,ret_closing_prices) %>% | |
dplyr::filter(ticker == '^GSPC') %>% | |
drop_na(ret_closing_prices) | |
capm_amazon = lm(ret_amazon$ret_closing_prices~ret_sp500$ret_closing_prices) | |
capm_netflix = lm(ret_netflix$ret_closing_prices~ret_sp500$ret_closing_prices) | |
summary(capm_amazon) | |
summary(capm_netflix) | |
par(mfrow=c(1,1)) | |
rang = range(ret_sp500$ret_closing_prices,ret_amazon$ret_closing_prices) | |
plot(ret_sp500$ret_closing_prices,ret_amazon$ret_closing_prices,xlab="Market return (S&P500)",ylab="Amazon",xlim=rang,ylim=rang) | |
abline(capm_amazon$coef,col=2,lwd=3) | |
title(paste("Amazon = ",round(capm_amazon$coef[1],4)," + ",round(capm_amazon$coef[2],4),"*SP500",sep="")) | |
par(mfrow=c(1,1)) | |
rang = range(ret_sp500$ret_closing_prices,ret_netflix$ret_closing_prices) | |
plot(ret_sp500$ret_closing_prices,ret_netflix$ret_closing_prices,xlab="Market return (S&P500)",ylab="Netflix",xlim=rang,ylim=rang) | |
abline(capm_netflix$coef,col=2,lwd=3) | |
title(paste("Netflix = ",round(capm_netflix$coef[1],4)," + ",round(capm_netflix$coef[2],4),"*SP500",sep="")) | |
# set up DLM | |
dlm2 = function(parm,x.mat){ | |
parm = exp(parm) | |
return( dlmModReg(X=x.mat, dV=parm[1], dW=c(parm[2],parm[3])) ) | |
} | |
# estimate parameters | |
fit2 = dlmMLE(y=ret_amazon$ret_closing_prices,parm=c(1,1,1),x.mat=ret_sp500$ret_closing_prices,build=dlm2,hessian=T) | |
# get estimates | |
se = sqrt(exp(fit2$par)) | |
se | |
# get parameter estimates over time | |
# these are the smoothed state values | |
mod2 = dlm2(fit2$par,ret_sp500$ret_closing_prices) | |
mod2f = dlmFilter(ret_amazon$ret_closing_prices,mod2) | |
mod2s = dlmSmooth(mod2f) | |
# plot filtered and smoothed states | |
date = df.tickers$ref_date[df.tickers$ticker == 'AMZN'][-1] | |
plot(date,mod2f$m[,1][-1],xlab="day",ylab=expression(alpha[t]),type="l",main="") | |
lines(date,mod2s$s[,1][-1],col=2) | |
abline(h=capm_amazon$coef[1],col=3) | |
abline(h=1,lty=2) | |
date = df.tickers$ref_date[df.tickers$ticker == 'AMZN'][-1] | |
plot(date,mod2f$m[,2][-1],xlab="day",ylab=expression(beta[t]),type="l",main="") | |
lines(date,mod2s$s[,2][-1],col=2) | |
abline(h=capm_amazon$coef[2],col=3) | |
abline(h=1,lty=2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment