Chapter 7 Dynamic Models
7.1 Import Data
#insbeta=read.table(choose.files(), header=TRUE, sep="\t")
library(nlme)
insbeta=read.table("TXTData/insbeta.txt", sep ="\t", quote = "",header=TRUE)
insbeta$YEAR=1995+(insbeta$Time-1)/12
This is the data used at page 302 for 8.6 Example: Capital Asset Pricing Model. No more information could be found.
7.2 Example 8.6: Capital Asset Pricing Model (Page 302)
The capital asset pricing model (CAPM) is a representation that is widely used in financial economics. An intuitively appealing idea, and one of the basic characteristics of the CAPM, is that there should be a relationship between the performance of a security and the performance of the market. One rationale is simply that if economic forces are such that the market improves, then those same forces should act upon an individual stock, suggesting that it also improve. We measure performance of a security through the return. To measure performance of the market, several market indices exist for each exchange. As an illustration, in the following we use the return from the “value-weighted” index of the market created by the Center for Research in Securities Prices (CRSP). The value-weighted index is defined by assuming a portfolio is created when investing an amount of money in proportion to the market value (at a certain date) of firms listed on the New York Stock Exchange, the American Stock Exchange, and the Nasdaq stock market.
7.2.1 Plot of RETFREE vs. VWFREE for Incoln insurance company
plot(retfree ~ vwfree, data = subset(insbeta, insbeta$PERMNO==49015), type="p", xaxt="n", yaxt="n", ylab="", xlab="", font=10, cex=1, pch="o", las=1, mkh=0.0001, lwd=0.5)
axis(2, at=seq(-30, 30, by=10), las=1, font=10, cex=0.005, tck=0.01)
axis(2, at=seq(-30, 30, by=1), lab=F, tck=0.005)
axis(1, at=seq(-20,20, by=10), font=10, cex=0.005, tck=0.01)
axis(1, at=seq(-20,20, by=1), lab=F, tck=0.005)
axis(2, at=seq(-70, 110, by=10), las=1, font=10, cex=0.005, tck=0.01)
axis(2, at=seq(-70, 110, by=1), lab=F, tck=0.005)
axis(1, at=seq(-20,10, by=10), font=10, cex=0.005, tck=0.01)
axis(1, at=seq(-20,10, by=1), lab=F, tck=0.005)
mtext("retfree", side=2, line=0, at=28, font=10, cex=1, las=1)
mtext("vwfree", side=1, line=2, at=-5, font=10, cex=1)
7.2.2 Plot of RETFREE vs. VWFREE for 90 insurance firms
plot(retfree ~ vwfree, data =insbeta, type="p", xaxt="n", yaxt="n", ylab="", xlab="", font=10, cex=1, pch="o", las=1, mkh=0.0001, lwd=0.5)
axis(2, at=seq(-70, 110, by=10), las=1, font=10, cex=0.005, tck=0.01)
axis(2, at=seq(-70, 110, by=1), lab=F, tck=0.005)
axis(1, at=seq(-20,10, by=10), font=10, cex=0.005, tck=0.01)
axis(1, at=seq(-20,10, by=1), lab=F, tck=0.005)
mtext("retfree", side=2, line=0, at=115, font=10, cex=1, las=1)
mtext("vwfree", side=1, line=2, at=-5, font=10, cex=1)
mtext("RETFREE vs. VWFREE for 90 Insurance Firms", side=1, line=4, at=-5, font=10, cex=1)
7.2.3 Plot of RETFREE vs. YEAR for Lincoln insurance company
plot(retfree ~ YEAR, data = subset(insbeta, insbeta$PERMNO==49015), type="o", xaxt="n", yaxt="n", ylab="", xlab="", font=10, cex=1, pch=16, las=1, mkh=0.0001, lwd=0.5)
axis(2, at=seq(-30, 30, by=10), las=1, font=10, cex=0.005, tck=0.01)
axis(2, at=seq(-30, 30, by=1), lab=F, tck=0.005)
axis(1, at=seq(1995,2000, by=1), font=10, cex=0.005, tck=0.01)
axis(1, at=seq(1995,2000, by=0.1), lab=F, tck=0.005)
mtext("retfree", side=2, line=0, at=28, font=10, cex=1, las=1)
mtext("year", side=1, line=2, at=1997.50, font=10, cex=1)
mtext("Lincoln RETFREE vs. YEAR", side=1, line=5, at=1997.50, font=10, cex=1)
7.2.4 Table 8.2 Summary statistics for market index and risk-free security
LINCOLN<-subset(insbeta, insbeta$PERMNO==49015)
summary(LINCOLN[, c("VWRETD", "SPRTRN", "riskf", "vwfree", "spfree")])
VWRETD SPRTRN riskf vwfree
Min. :-15.6765 Min. :-14.5797 Min. :0.2964 Min. :-16.0683
1st Qu.: -0.2581 1st Qu.: 0.1612 1st Qu.:0.3811 1st Qu.: -0.6755
Median : 2.9464 Median : 2.6730 Median :0.4147 Median : 2.5174
Mean : 2.0914 Mean : 2.0380 Mean :0.4075 Mean : 1.6839
3rd Qu.: 4.9429 3rd Qu.: 5.0748 3rd Qu.:0.4267 3rd Qu.: 4.5654
Max. : 8.3054 Max. : 8.0294 Max. :0.4829 Max. : 7.8798
spfree
Min. :-14.9714
1st Qu.: -0.2533
Median : 2.2244
Mean : 1.6305
3rd Qu.: 4.6481
Max. : 7.7330
sd1<-sqrt(diag(var(insbeta[,c("VWRETD", "SPRTRN", "riskf", "vwfree", "spfree")])))
sd1
VWRETD SPRTRN riskf vwfree spfree
4.09890088 3.98794716 0.03380599 4.09997511 3.98932881
cor(LINCOLN[,c("VWRETD", "SPRTRN", "riskf", "vwfree", "spfree")])
VWRETD SPRTRN riskf vwfree spfree
VWRETD 1.0000000 0.97950897 -0.02765660 0.99996603 0.97940410
SPRTRN 0.9795090 1.00000000 -0.03663843 0.97955443 0.99996414
riskf -0.0276566 -0.03663843 1.00000000 -0.03589477 -0.04509984
vwfree 0.9999660 0.97955443 -0.03589477 1.00000000 0.97951935
spfree 0.9794041 0.99996414 -0.04509984 0.97951935 1.00000000
Table 8.2 summarizes the performance of the market through the return from the value-weighted index, VWRETD
, and risk free instrument, RISKFREE
. We also consider the difference between the two, VWFREE
, and interpret this to be the return from the market in excess of the risk-free rate.
7.2.5 TABLE 8.3 Summary statistics for individual security returns
summary(insbeta[,c("RET", "retfree", "PRC")])
RET retfree PRC
Min. :-66.1972 Min. :-66.5785 Min. : 0.81
1st Qu.: -3.8462 1st Qu.: -4.2428 1st Qu.: 14.25
Median : 0.7453 Median : 0.3402 Median : 26.88
Mean : 1.0521 Mean : 0.6446 Mean : 547.11
3rd Qu.: 5.8823 3rd Qu.: 5.4675 3rd Qu.: 45.89
Max. :102.5000 Max. :102.0850 Max. :78305.00
# STANDARD DEVIATION
sd1<-sqrt(diag(var(insbeta[,c("RET", "retfree", "PRC")])))
sd1
RET retfree PRC
10.03772 10.03552 5178.49653
cor(insbeta[,c("RET", "VWRETD", "SPRTRN", "riskf", "retfree", "vwfree", "spfree")])
RET VWRETD SPRTRN riskf retfree
RET 1.00000000 0.2937725 0.28237030 0.06693926 0.99999435
VWRETD 0.29377254 1.0000000 0.97950897 -0.02765660 0.29393029
SPRTRN 0.28237030 0.9795090 1.00000000 -0.03663843 0.28255580
riskf 0.06693926 -0.0276566 -0.03663843 1.00000000 0.06358534
retfree 0.99999435 0.2939303 0.28255580 0.06358534 1.00000000
vwfree 0.29314362 0.9999660 0.97955443 -0.03589477 0.29332899
spfree 0.28170525 0.9794041 0.99996414 -0.04509984 0.28191911
vwfree spfree
RET 0.29314362 0.28170525
VWRETD 0.99996603 0.97940410
SPRTRN 0.97955443 0.99996414
riskf -0.03589477 -0.04509984
retfree 0.29332899 0.28191911
vwfree 1.00000000 0.97951935
spfree 0.97951935 1.00000000
Table 8.3 summarizes the performance of individual securities through the monthly return, RET
. These summary statistics are based on 5,400 monthly observations taken from 90 firms. The difference between the return and the corresponding risk-free instrument is RETFREE
.
7.2.6 TABLE 8.4 Fixed effects models
#HOMOGENEOUS MODEL
insbetahomo<-gls(retfree~vwfree, method="REML", data=insbeta)
anova(insbetahomo)
Denom. DF: 5398
numDF F-value p-value
(Intercept) 1 24.3686 <.0001
vwfree 1 508.1788 <.0001
insbetahomo$sigma^2
[1] 92.06322
AIC(insbetahomo)
[1] 39757.19
logLik(insbetahomo)*(-2)
'log Lik.' 39751.19 (df=3)
insbeta$FACPERM<-factor(insbeta$PERMNO)
#VARIABLE INTERCEPT MODEL
insbetafx1<-gls(retfree~vwfree+FACPERM, method="REML", data=insbeta)
anova(insbetafx1)
Denom. DF: 5309
numDF F-value p-value
(Intercept) 1 24.2193 <.0001
vwfree 1 505.0665 <.0001
FACPERM 89 0.6285 0.9975
insbetafx1$sigma^2
[1] 92.63053
AIC(insbetafx1)
[1] 39672.63
logLik(insbetafx1)*(-2)
'log Lik.' 39488.63 (df=92)
#VARIALBE SLOPES MODEL
insbetafx2<-gls(retfree~vwfree*FACPERM-vwfree-FACPERM, method="REML", data=insbeta)
anova(insbetafx2)
Denom. DF: 5309
numDF F-value p-value
(Intercept) 1 24.712995 <.0001
vwfree:FACPERM 90 7.562791 <.0001
insbetafx2$sigma^2
[1] 90.78022
AIC(insbetafx2)
[1] 39830.52
logLik(insbetafx2)*(-2)
'log Lik.' 39646.52 (df=92)
#VARIABLE INTERCEPTS AND SLOPES MODEL
insbetafx3<-gls(retfree~vwfree*FACPERM, method="REML", data=insbeta)
anova(insbetafx3)
Denom. DF: 5220
numDF F-value p-value
(Intercept) 1 24.6569 <.0001
vwfree 1 514.1906 <.0001
FACPERM 89 0.6399 0.9966
vwfree:FACPERM 89 2.0776 <.0001
insbetafx3$sigma^2
[1] 90.98683
AIC(insbetafx3)
[1] 39712.59
logLik(insbetafx3)*(-2)
'log Lik.' 39350.59 (df=181)
#VARIABLE SLOPES MODEL WITH AR(1) TERM
insbetafx4<-gls(retfree~vwfree:FACPERM, data=insbeta, method="REML", correlation=corAR1(form=~1|PERMNO)) #Model probably not working
anova(insbetafx4)
Denom. DF: 5309
numDF F-value p-value
(Intercept) 1 29.285237 <.0001
vwfree:FACPERM 90 7.941803 <.0001
insbetafx4$sigma^2
[1] 90.76872
AIC(insbetafx4)
[1] 39796.92
logLik(insbetafx4)*(-2)
'log Lik.' 39610.92 (df=93)
insbetafx4$modelStruct
corStruct parameters:
[1] -0.1689266
Table 8.4 summarizes the fit of each model. Based on these fits, we will use the variable slopes with an \(AR(1)\) error term model as the baseline for investigating time-varying coefficients.
Then we can include random effects:
insbetarm<-lme(retfree~vwfree, data=insbeta, random=~vwfree-1|PERMNO) #Random - Effects Model
insbetarco<-lme(retfree~vwfree, data=insbeta, random=~1+vwfree|PERMNO, correlation=corAR1(form=~1|PERMNO),control = lmeControl(opt = "optim"))
#due to convergence problem, I add the "control = lmeControl(opt = "optim")".
#Random - Coefficients Model
summary(insbetarm)
Linear mixed-effects model fit by REML
Data: insbeta
AIC BIC logLik
39738.53 39764.91 -19865.27
Random effects:
Formula: ~vwfree - 1 | PERMNO
vwfree Residual
StdDev: 0.2569603 9.527865
Fixed effects: retfree ~ vwfree
Value Std.Error DF t-value p-value
(Intercept) -0.5644229 0.14016877 5309 -4.026737 1e-04
vwfree 0.7179819 0.04164033 5309 17.242464 0e+00
Correlation:
(Intr)
vwfree -0.289
Standardized Within-Group Residuals:
Min Q1 Med Q3 Max
-7.18150077 -0.49947031 -0.02643177 0.46193572 10.17362517
Number of Observations: 5400
Number of Groups: 90
summary(insbetarco)
Linear mixed-effects model fit by REML
Data: insbeta
AIC BIC logLik
39697.8 39743.95 -19841.9
Random effects:
Formula: ~1 + vwfree | PERMNO
Structure: General positive-definite, Log-Cholesky parametrization
StdDev Corr
(Intercept) 0.5759112 (Intr)
vwfree 0.3182517 -0.831
Residual 9.5058076
Correlation Structure: AR(1)
Formula: ~1 | PERMNO
Parameter estimate(s):
Phi
-0.08830483
Fixed effects: retfree ~ vwfree
Value Std.Error DF t-value p-value
(Intercept) -0.5905640 0.14322023 5309 -4.123468 0
vwfree 0.7378101 0.04596025 5309 16.053222 0
Correlation:
(Intr)
vwfree -0.508
Standardized Within-Group Residuals:
Min Q1 Med Q3 Max
-7.20057083 -0.49733487 -0.02677384 0.46069650 10.22355808
Number of Observations: 5400
Number of Groups: 90
Cleaning up companies with more than one Ticker names but having the same PERMNO
:
tab<-as.matrix(xtabs(~PERMNO+TICKER, insbeta)) #a logical matrix cross-tabulation of PERMNO and TIcker
which(rowSums(tab>0)>1)
10085 10388 10933 11203 11371 11406 11713 22198 37226 48901 52936 58393
1 5 10 12 13 14 16 24 30 41 44 50
60687 76099 76697 77052 77815
56 72 79 83 86
# PERMNOs that have more than one ticker
#10085 10388 10933 11203 11371 11406 11713 22198 37226 48901 52936 58393 60687
# 1 5 10 12 13 14 16 24 30 41 44 50 56
#76099 76697 77052 77815
# 72 79 83 86
# For each PERMNO go through the following code check on the the TICKER names and frequency
# which(tab["10388",]>0)
#TREN TWK
# 96 99
#> tab["10388", c(96,99)]
# TREN TWK
# 57 3 # THIS SHOWS THE FREQUENCY AS WELL AS THE TICKER NAMES FOR ONE SINGLE PERMNO "10388"
Recode Tickers:
insbeta$TICKER[insbeta$PERMNO=="10085"]<-"UICI"
insbeta$TICKER[insbeta$PERMNO=="10388"]<-"TREN"
insbeta$TICKER[insbeta$PERMNO=="10933"]<-"MKL"
insbeta$TICKER[insbeta$PERMNO=="11203"]<-"PXT"
insbeta$TICKER[insbeta$PERMNO=="11371"]<-"HCCC"
insbeta$TICKER[insbeta$PERMNO=="11406"]<-"CSH"
insbeta$TICKER[insbeta$PERMNO=="11713"]<-"PTAC"
insbeta$TICKER[insbeta$PERMNO=="22198"]<-"CRLC"
insbeta$TICKER[insbeta$PERMNO=="37226"]<-"FOM"
insbeta$TICKER[insbeta$PERMNO=="48901"]<-"MLA"
insbeta$TICKER[insbeta$PERMNO=="52936"]<-"MCY"
insbeta$TICKER[insbeta$PERMNO=="58393"]<-"RLR"
insbeta$TICKER[insbeta$PERMNO=="60687"]<-"AFG"
insbeta$TICKER[insbeta$PERMNO=="76099"]<-"DFG"
insbeta$TICKER[insbeta$PERMNO=="76697"]<-"FHS"
insbeta$TICKER[insbeta$PERMNO=="77052"]<-"UWZ"
insbeta$TICKER[insbeta$PERMNO=="77815"]<-"EQ"
Retuen the following checking the consistency between PERMNO
and TICKER
:
tab<-as.matrix(xtabs(~PERMNO+TICKER, insbeta))
which(rowSums(tab>0)>1) #RESULT SHOULD BE ZERO
named integer(0)
7.2.7 Figure 8.1: Trellis plot of returns versus market return
#PRODUCE A TRELLIS PLOT TO SHOW VARYING BETAS
library(lattice)
insbeta$ID=factor(insbeta$PERMNO)
insbeta$TK=factor(insbeta$TICKER)
sampbeta <- subset(insbeta, ID %in% sample(levels(insbeta$ID), 18, replace=FALSE) )
xyplot(RET ~ VWRETD | TK, data=sampbeta, layout=c(6,3,1), panel = function(x, y) {
panel.grid()
panel.xyplot(x, y)
panel.loess(x, y, span = 1.5)
})