Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
braverock
GitHub Repository: braverock/portfolioanalytics
Path: blob/master/sandbox/script.buildFactors.R
1433 views
1
# Acquire data for factors
2
3
# Script downloads, parses, and transforms data for a small set
4
# of common factors to be included as example data within
5
# FactorAnalytics. For more information, see the help file
6
# for ?factors
7
8
# Peter Carl
9
10
### Needed packages
11
require(gdata)
12
require(quantmod)
13
require(RQuantLib)
14
Sys.setenv(TZ="GMT")
15
16
## Set up required directory structure
17
18
19
### Equities
20
# Download the first sheet in the xls workbook directly from the S&P web site:
21
x = read.xls("http://www.spindices.com/documents/additional-material/monthly.xlsx?force_download=true")
22
rawdates = x[-1:-4,1]
23
rawreturns = x[-1:-4,12]
24
ISOdates = as.Date(as.yearmon(rawdates, "%m/%Y"), frac=1)
25
totalreturns = as.numeric(as.character((sub("%", "", rawreturns, fixed=TRUE))))/100
26
SP500.R=na.omit(as.xts(totalreturns, order.by=ISOdates))
27
colnames(SP500.R)="SP500TR"
28
# see parse.SP500TR.R in the FinancialInstrument package's inst/parsers directory for more detail
29
30
31
### Bonds
32
# Calculate total returns from the yeild of the 10 year constant maturity index maintained by the Fed
33
getSymbols("GS10", src="FRED") #load US Treasury 10y yields from FRED
34
# Dates should be end of month, not beginning of the month as reported
35
index(GS10) = as.Date(as.yearmon(index(GS10)), frac=1)
36
GS10.pr <- GS10 #set this up to hold price returns
37
GS10.pr[1,1] <- 0
38
colnames(GS10.pr) <- "Price Return"
39
for (i in 1:(NROW(GS10)-1)) {
40
GS10.pr[i+1,1] <- FixedRateBondPriceByYield(yield=GS10[i+1,1]/100, issueDate=Sys.Date(), maturityDate=advance("UnitedStates/GovernmentBond", Sys.Date(), 10, 3), rates=GS10[i,1]/100,period=2)[1]/100-1
41
}
42
# total return will be the price return + yield/12 for one month
43
GS10.R <- GS10.pr + lag(GS10,k=1)/12/100
44
colnames(GS10.R)<-"GS10TR"
45
46
#@TODO: Calc the same for 2y and 5y
47
48
49
### Currencies
50
# Trade Weighted U.S. Dollar Index: Major Currencies - TWEXMMTH
51
getSymbols("TWEXMMTH", src="FRED") # index values
52
# Dates should be end of month, not beginning of the month as reported
53
index(TWEXMMTH) = as.Date(as.yearmon(index(TWEXMMTH)), frac=1)
54
USDI.R=ROC(TWEXMMTH)
55
colnames(USDI.R)="USD Index"
56
57
58
### Credit Spread
59
# Yield spread of Merrill Lynch High-Yield Corporate Master II Index minus 10-year Treasury
60
getSymbols("BAMLH0A0HYM2EY",src="FRED")
61
BAMLH0A0HYM2EY.M=Cl(to.monthly(BAMLH0A0HYM2EY))
62
index(BAMLH0A0HYM2EY.M) = as.Date(as.yearmon(index(BAMLH0A0HYM2EY.M)), frac=1)
63
CREDIT=(BAMLH0A0HYM2EY.M-GS10)/100
64
colnames(CREDIT)="Credit Spread"
65
66
67
### Liquidity
68
getSymbols("TB3MS",src="FRED")
69
index(TB3MS) = as.Date(as.yearmon(index(TB3MS)), frac=1)
70
getSymbols("MED3",src="FRED")
71
index(MED3) = as.Date(as.yearmon(index(MED3)), frac=1)
72
TED=MED3/100-TB3MS/100
73
colnames(TED)="TED Spread"
74
75
76
### Real estate
77
# Use the NAREIT index
78
x = read.xls("http://returns.reit.com/returns/MonthlyHistoricalReturns.xls", pattern="Date", sheet="Index Data", stringsAsFactors=FALSE)
79
x.dates = as.Date(as.yearmon(x[,1], format="%b-%y"), frac=1)
80
REALESTATE.R = xts(x[,2]/100, order.by = x.dates)
81
colnames(REALESTATE.R) = "NAREIT Returns"
82
83
84
### Commodities
85
## Use the DJUBS Commodities index
86
x = read.xls("http://www.djindexes.com/mdsidx/downloads/xlspages/ubsci_public/DJUBS_full_hist.xls", sheet="Total Return")
87
x=x[-1:-2,] # Get rid of the headings
88
x=x[-dim(x)[1],] # Get rid of the last line, which contains the disclaimer
89
ISOdates = as.Date(x[,1], "%m/%d/%Y") # Get dates
90
x.xts = as.xts(as.numeric(as.vector(x[,2])), order.by=ISOdates)
91
x.m.xts = to.monthly(x.xts)
92
x.m.xts = ROC(Cl(x.m.xts)) # Calc monthly returns
93
index(x.m.xts)=as.Date(index(x.m.xts), frac=1)
94
DJUBS.R = x.m.xts
95
colnames(DJUBS.R)="DJUBSTR"
96
97
98
### Volatility
99
# as per Lo, the first difference of the end-of-month value of the CBOE Volatility Index (VIX)
100
# Older VIX data is available at:
101
# http://www.cboe.com/publish/ScheduledTask/MktData/datahouse/vixarchive.xls
102
# Daily from 1990-2003
103
x= read.xls( "http://www.cboe.com/publish/ScheduledTask/MktData/datahouse/vixarchive.xls" )
104
ISOdates = as.Date(x[,1], "%m/%d/%y") # Get dates
105
x.xts = as.xts(as.numeric(as.vector(x[,5])), order.by=ISOdates)
106
x.m.xts = to.monthly(x.xts)
107
getSymbols("VIXCLS", src="FRED")
108
# Calculate monthly returns
109
VIX=to.monthly(VIXCLS)
110
VIX=rbind(x.m.xts,VIX)
111
index(VIX)=as.Date(index(VIX), frac=1)
112
dVIX=diff(Cl(VIX))
113
colnames(dVIX)="dVIX"
114
115
116
### Term spread
117
# 10 year yield minus 3 month
118
TERM = GS10/100-TB3MS/100
119
colnames(TERM)="Term Spread"
120
121
122
### Gold
123
# Monthly return on gold spot price
124
# Fred London 3pm Fix: GOLDPMGBD228NLBM
125
getSymbols("GOLDPMGBD228NLBM",src="FRED") # daily series
126
GOLD=ROC(Cl(to.monthly(GOLDPMGBD228NLBM)))
127
index(GOLD) = as.Date(as.yearmon(index(GOLD)), frac=1)
128
129
130
### Oil
131
# Monthly returns of spot price of West Texas Intermediate
132
getSymbols("OILPRICE", src="FRED")
133
index(OILPRICE) = as.Date(as.yearmon(index(OILPRICE)), frac=1)
134
135
136
### PUT
137
# Monthly returns of PUT Index
138
# Retrieve in two pieces; first the historical from 1986 to 2006
139
system("wget https://www.cboe.com/micro/put/PUT_86-06.xls")
140
x = read.xls("PUT_86-06.xls")
141
x=na.omit(x[-1:-4,1:2])
142
ISOdates = as.Date(x[,1], "%d-%b-%Y") # Get dates
143
PUT1 = xts(as.numeric(as.vector(x[,2])), order.by=ISOdates)
144
# Next is current from 2007 on
145
system("wget https://www.cboe.com/publish/ScheduledTask/MktData/datahouse/PUTDailyPrice.csv")
146
y=read.csv("PUTDailyPrice.csv")
147
y=y[-1:-4,]
148
ISOdates = as.Date(y[,1], "%m/%d/%Y") # Get dates
149
PUT2 = xts(as.numeric(as.vector(y[,2])), order.by=ISOdates)
150
# Combine the two series
151
PUT = rbind(PUT1,PUT2)
152
colnames(PUT)="Close"
153
PUT = ROC(Cl(to.monthly(PUT)))
154
index(PUT) = as.Date(as.yearmon(index(PUT)), frac=1)
155
# need to drop the last row if inter-month
156
157
158
factors=cbind(SP500.R, GS10.R, USDI.R, TERM, CREDIT, DJUBS.R, dVIX, TED, OIL.R, TB3MS/100) # GOLD.R, REALESTATE.R
159
factors=factors["1997::",]
160
161
## Create a chart of the factor set
162
asofdate= tail(index(factors),1)
163
labels=colnames(factors)
164
pdf(file=paste("Cumulative Factor Returns as of ", asofdate, ".pdf", sep=""), paper="letter", width=7.5, height=10)
165
op <- par(no.readonly=TRUE)
166
layout(matrix(c(1:NCOL(factors)), ncol = 1, byrow = TRUE), widths=1)
167
op <- par(oma = c(5,0,4,0), mar=c(0,4,0,4))
168
for(i in 1:NCOL(factors)){
169
xaxis=FALSE
170
yaxis=TRUE
171
if(even(i))
172
yaxis.right=TRUE
173
else
174
yaxis.right=FALSE
175
if(i==NCOL(factors))
176
xaxis = TRUE
177
chart.TimeSeries(cbind(factors["1997::",i],SMA(na.locf(factors["1997::",i], n=12))), type="l", colorset=c("blue","lightblue"), ylog=FALSE, xaxis=xaxis, main="", ylab="", yaxis=yaxis, yaxis.right=yaxis.right, lwd=2)
178
text(.9, .70*(par("usr")[4]), adj=c(0,1), cex = 1.1, labels = labels[i])
179
}
180
par(op)
181
mtext(expression(bold("Monthly Factor Returns")), side=3, outer=TRUE, line=-3, adj=0.1, col="black", cex=1.2)
182
mtext(paste("As of", asofdate), side=3, outer=TRUE, line=-3, adj=0.9, col="darkgray", cex=0.8)
183
dev.off()
184