Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
braverock
GitHub Repository: braverock/portfolioanalytics
Path: blob/master/sandbox/ptcQP.R
1433 views
1
2
# proportional transaction costs minimum variance QP
3
4
library(PortfolioAnalytics)
5
library(corpcor)
6
library(quadprog)
7
library(ROI)
8
library(ROI.plugin.quadprog)
9
10
data(edhec)
11
R <- edhec[, 1:4]
12
13
N <- ncol(R)
14
mu <- colMeans(R)
15
mu_target <- median(mu)
16
w_init <- rep(1 / N, N)
17
tcb <- tcs <- rep(0.01, N)
18
min_sum <- 0.99
19
max_sum <- 1.01
20
min_box <- rep(0, N)
21
max_box <- rep(1, N)
22
lambda <- 1
23
24
R0 <- matrix(0, ncol=ncol(R), nrow=nrow(R))
25
returns <- cbind(R, R0, R0)
26
V <- corpcor::make.positive.definite(cov(returns))
27
28
Amat <- matrix(c(1 + mu, rep(0, 2 * N)), nrow=1)
29
rhs <- 1 + mu_target
30
dir <- "=="
31
32
# separate the weights into w, w+, and w-
33
# w - w+ + w- = 0
34
Amat <- rbind(Amat, cbind(diag(N), -diag(N), diag(N)))
35
rhs <- c(rhs, w_init)
36
dir <- c(dir, rep("==", N))
37
meq <- N + 1
38
39
# w+ >= 0
40
Amat <- rbind(Amat, cbind(diag(0, N), diag(N), diag(0, N)))
41
rhs <- c(rhs, rep(0, N))
42
dir <- c(dir, rep(">=", N))
43
44
# w- >= 0
45
Amat <- rbind(Amat, cbind(diag(0, N), diag(0, N), diag(N)))
46
rhs <- c(rhs, rep(0, N))
47
dir <- c(dir, rep(">=", N))
48
49
# 1^T w + tcb^T w^+ + tcs^T w^- >= min_sum
50
Amat <- rbind(Amat, c(rep(1, N), tcb, tcs))
51
rhs <- c(rhs, min_sum)
52
dir <- c(dir, ">=")
53
54
# 1^T w + tcb^T w^+ + tcs^T w^- >= min_sum
55
Amat <- rbind(Amat, c(rep(-1, N), -tcb, -tcs))
56
rhs <- c(rhs, -max_sum)
57
dir <- c(dir, ">=")
58
59
# -(1 + tcb)^T w^+ + (1 - tcs)^T w^- >= 0
60
Amat <- rbind(Amat, c(rep(0, N), -(1 + tcb), (1 - tcs)))
61
rhs <- c(rhs, 0)
62
dir <- c(dir, ">=")
63
64
# lower box constraints
65
Amat <- rbind(Amat, cbind(diag(N), diag(0, N), diag(0, N)))
66
rhs <- c(rhs, min_box)
67
dir <- c(dir, rep(">=", N))
68
69
# upper box constraints
70
Amat <- rbind(Amat, cbind(-diag(N), diag(0, N), diag(0, N)))
71
rhs <- c(rhs, -max_box)
72
dir <- c(dir, rep(">=", N))
73
74
sol <- solve.QP(Dmat=V, dvec=rep(0, 3*N), Amat=t(Amat), bvec=rhs, meq=meq)
75
sol
76
77
weights <- sol$solution[1:N]
78
round(weights, 4)
79
sum(weights * mu)
80
81
##### ROI #####
82
ROI_objective <- Q_objective(Q=make.positive.definite(2*lambda*V),
83
L=rep(0, N*3))
84
85
opt.prob <- OP(objective=ROI_objective,
86
constraints=L_constraint(L=Amat, dir=dir, rhs=rhs))
87
88
roi.result <- ROI_solve(x=opt.prob, solver="quadprog")
89
wts <- roi.result$solution[1:N]
90
round(wts, 4)
91
sum(wts)
92
93
# The quadprog and ROI solution should result in the same solution using the
94
# same Amat, dir, and rhs objects
95
all.equal(weights, wts)
96
97
98