Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
braverock
GitHub Repository: braverock/portfolioanalytics
Path: blob/master/demo/meucci_ffv.R
1433 views
1
#' ---
2
#' title: "Meucci FFV Demo"
3
#' author: Ross Bennett
4
#' date: "7/17/2014"
5
#' ---
6
7
#' This script demonstrate Meucci's Fully Flexible Views framework to estimate
8
#' moments to use as inputs for a minimum variance optimization.
9
10
#' Load package and data
11
library(PortfolioAnalytics)
12
data(edhec)
13
R <- edhec[,1:5]
14
funds <- colnames(R)
15
16
#' Construct initial portfolio with basic constraints.
17
init.portf <- portfolio.spec(assets=funds)
18
init.portf <- add.constraint(portfolio=init.portf, type="weight_sum",
19
min_sum=0.99, max_sum=1.01)
20
init.portf <- add.constraint(portfolio=init.portf, type="box",
21
min=0.05, max=0.5)
22
init.portf <- add.objective(portfolio=init.portf, type="risk", name="StdDev")
23
init.portf <- add.objective(portfolio=init.portf, type="return", name="mean", multiplier=0)
24
25
# prior probabilities
26
p <- rep(1 / nrow(R), nrow(R))
27
28
#' Here we express views
29
#' lambda is the ad-hoc multiplier
30
#' m_k = m(V_k) + lambda * sigma(V_k)
31
#' sigma(k) is a measure of volatility (i.e. standard deviation, interquartile range, etc.)
32
#' Meucci recommends -2 (very bearish), -1 (bearish), 1 (bullish), 2 (very bullish)
33
34
#' View 1: very bearish view on R[,1] - R[,2]
35
V1 <- coredata(R[,1] - R[,2])
36
b1 <- mean(V1) - 2 * sd(V1)
37
38
#' View 2: bearish view on R[,5] - R[,4]
39
V2 <- coredata(R[,5] - R[,4])
40
b2 <- mean(V2) - 1 * sd(V2)
41
42
#' Here we compute the posterior probabilities for each view.
43
44
#' Set up equality constraints to constrain the posterior probabilities to
45
#' sum to 1.
46
Aeq <- matrix(1, ncol=nrow(R))
47
beq <- 1
48
49
#' Run the entropy optimization to compute the posterior for each view.
50
p1 <- EntropyProg(p, t(V1), b1, Aeq, beq)$p_
51
p2 <- EntropyProg(p, t(V2), b2, Aeq, beq)$p_
52
53
#' Assign confidence weights to the views and pool opinions.
54
#' 0.35 : confidence weight on reference model
55
#' 0.25 : confidence weight on view 1
56
#' 0.4 : confidence weight on view 2
57
58
#' Use entropy pooling to estimate the posterior.
59
p_ <- cbind(p, p1, p2) %*% c(0.35 , 0.25 , 0.4)
60
61
#' Generate random portfolios for use in the optimization.
62
rp <- random_portfolios(init.portf, 10000)
63
64
#' Run the optimization using first and second moments estimated from
65
#' Meucci's Fully Flexible Views framework.
66
opt.meucci <- optimize.portfolio(R,
67
init.portf,
68
optimize_method="random",
69
rp=rp,
70
trace=TRUE,
71
method="meucci",
72
posterior_p=p_)
73
74
75
# Run the optimization using sample estimates for first and second moments.
76
opt.sample <- optimize.portfolio(R,
77
init.portf,
78
optimize_method="random",
79
rp=rp,
80
trace=TRUE)
81
82
#' Extract the stats for plotting.
83
stats.meucci <- extractStats(opt.meucci)
84
stats.sample <- extractStats(opt.sample)
85
86
#' Plot the optimal weights.
87
chart.Weights(combine.optimizations(list(meucci=opt.meucci, sample=opt.sample)))
88
89
#' Plot the risk-reward of each chart on the same scale.
90
xrange <- range(c(stats.meucci[,"StdDev"], stats.sample[,"StdDev"]))
91
yrange <- range(c(stats.meucci[,"mean"], stats.sample[,"mean"]))
92
layout(matrix(c(1,2)), widths=1, heights=1)
93
# c(bottom, left, top, right)
94
par(mar=c(0, 4, 4, 4) + 0.1)
95
plot(x=stats.meucci[,"StdDev"], stats.meucci[,"mean"], xlab="", ylab="mean",
96
xlim=xrange, ylim=yrange, xaxt="n", yaxt="n")
97
axis(2, pretty(yrange), cex.axis=0.8)
98
legend("topright", legend="Meucci", bty="n")
99
par(mar=c(5, 4, 0, 4) + 0.1)
100
plot(x=stats.sample[,"StdDev"], stats.sample[,"mean"], xlab="StdDev", ylab="",
101
xlim=xrange, ylim=yrange, yaxt="n", cex.axis=0.8)
102
axis(4, pretty(yrange), cex.axis=0.8)
103
legend("topright", legend="Sample", bty="n")
104
par(mar=c(5, 4, 4, 2) + 0.1)
105
layout(matrix(1), widths=1, heights=1)
106
107