-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathOptimizing Effective Bets.R
More file actions
100 lines (63 loc) · 2.86 KB
/
Optimizing Effective Bets.R
File metadata and controls
100 lines (63 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
library(quantmod)
library(PerformanceAnalytics)
library(PortfolioAnalytics)
EffectiveBets = function(R, w) {
# Perform PCA on the returns
pca <- prcomp(R, cor = FALSE)
evec <- pca$rotation[] #eigenvectors
eigval <- pca$sdev^2 #eigenvalues
# Calculate the factor return streams
inv.evec <- solve(evec) #inverse of eigenvectors
# Calculate your exposure to each factor
factor.exposure <- inv.evec %*% w
# Calculate the diversification distribution
# The numerator is the variance concentration curve
# The denominator is the total portfolio variance
div.dist <- (factor.exposure^2)*eigval / sum((factor.exposure^2)*eigval)
# Calculate the effective number of bets
ENB <- exp(-sum(div.dist*log(div.dist)))
return(ENB)
}
##Estimate the inv.evec and val first when using optimization w first for easy passing to deoptim
EffectiveBets_optim = function(weights,inv.evec,eigval){
factor.exposure <- inv.evec %*% weights
# Calculate the diversification distribution
# The numerator is the variance concentration curve
# The denominator is the total portfolio variance
div.dist <- (factor.exposure^2)*eigval / sum((factor.exposure^2)*eigval)
# Calculate the effective number of bets
ENB <- exp(-sum(div.dist*log(div.dist)))
return(1/ENB)
}
###Canadian ETF LISt
canadian_etfs=c("xiu","xsp","cbo","xsb","XBB","XCB","CPD","XRE","ZHY","CLF","PGL","ZIC")
getSymbols(paste0(canadian_etfs,".TO"),from='2000-01-01')
etf_name_list = paste0(toupper(canadian_etfs),".TO")
###Combine all into a "price matrix"
pricemat=NULL
start_dates = data.frame(etf_name=etf_name_list)
start_dates$date = NA
for(etfs in etf_name_list){
step1 = Ad(get(paste0(etfs)))
colnames(step1) = etfs
pricemat = merge.xts(pricemat,step1)
start_dates[start_dates$etf_name==etfs,]$date=as.Date(start(step1))
}
returnmat = ROC(pricemat,type="discrete")
##Fix return data
retmat= returnmat['2013-04-01/2015-01-01']
retmat[is.na(retmat)]=0
##Estimate inv.evec
pca <- prcomp(retmat, cor = FALSE)
evec <- pca$rotation[] #eigenvectors
eigval <- pca$sdev^2 #eigenvalues
# Calculate the factor return streams
inv.evec <- solve(evec) #inverse of eigenvectors
###Use Portfolio Analytics to quickly model the portfolio
moms_portfolio = portfolio.spec(assets=colnames(returnmat))
moms_portfolio = add.constraint(portfolio=moms_portfolio,type="full_investment")
moms_portfolio = add.constraint(portfolio=moms_portfolio,type="long_only")
moms_portfolio = add.objective(portfolio=moms_portfolio,name="EffectiveBets_optim",type="risk",arguments=list(inv.evec=inv.evec,eigval=eigval)) ###Place holder
###Optimize (May want to switch to ROI or different optimizer if dealing with more securities)
optimal_portfolio = optimize.portfolio(retmat,moms_portfolio,optimize_method="DEoptim",
search_size=5000, trace=TRUE, traceDE=0)