Path: blob/master/inst/tests/test_qp_gmv.R
1433 views
library(PortfolioAnalytics)1library(ROI)2library(ROI.plugin.quadprog)3library(quadprog)4library(testthat)56# Test that PortfolioAnalytics with ROI.plugin.quadprog solutions equal quadprog solutions7context("GMV Portfolios: PortfolioAnalytics with ROI.plugin.quadprog and quadprog")8910##### Data #####11data(edhec)12R <- edhec[, 1:5]13funds <- colnames(R)14m <- ncol(R)1516##### Parameters #####17portf <- portfolio.spec(funds)18portf <- add.constraint(portf, type="full_investment")19portf <- add.constraint(portf, type="box", min=-Inf, max=Inf)20portf <- add.objective(portf, type="risk", name="var")2122# Quadratic part of objective function23objQ <- 2 * cov(R)2425# Linear part of objective function26objL <- rep(0, m)2728# Constraints matrix29Amat <- matrix(1, nrow=1, ncol=m)3031# right hand side of constraints32rhs <- 1333435##### Unconstrained #####3637# Solve optimization with quadprog38opt.qp <- solve.QP(Dmat=objQ, dvec=objL, Amat=t(Amat), bvec=rhs, meq=1)3940# Solve optimization with PortfolioAnalytics41opt.pa <- optimize.portfolio(R, portf, optimize_method="quadprog")42weights <- as.numeric(extractWeights(opt.pa))4344test_that("Unconstrained: PortfolioAnalytics and quadprog solution weights are equal", {45expect_that(weights, equals(opt.qp$solution))46})4748test_that("Unconstrained: PortfolioAnalytics and quadprog solution objective values are equal", {49expect_that(opt.pa$out, equals(opt.qp$value))50})5152##### Long Only #####53# Upper and lower bounds (i.e. box constraints)54lb <- rep(0, m)55ub <- rep(1, m)5657Amat <- rbind(1, diag(m), -diag(m))58rhs <- c(1, lb, -ub)5960# Update box constraints in portfolio61portf$constraints[[2]]$min <- lb62portf$constraints[[2]]$max <- ub6364# Solve optimization with quadprog65opt.qp <- solve.QP(Dmat=objQ, dvec=objL, Amat=t(Amat), bvec=rhs, meq=1)6667# Solve optimization with PortfolioAnalytics68opt.pa <- optimize.portfolio(R, portf, optimize_method="quadprog")69# some of the optimal weights are slightly negative (-7.602276e-18), but they70# are essentially zero71weights <- round(as.numeric(extractWeights(opt.pa)), 10)7273test_that("Long Only: PortfolioAnalytics and quadprog solution weights are equal", {74expect_that(weights, equals(opt.qp$solution))75})7677test_that("Long Only: PortfolioAnalytics bounds are respected", {78expect_that(all(weights >= lb) & all(weights <= ub), is_true())79})8081test_that("Long Only: quadprog bounds are respected", {82expect_that(all(round(opt.qp$solution, 10) >= lb) & all(round(opt.qp$solution, 10) <= ub), is_true())83})8485test_that("Long Only: PortfolioAnalytics and quadprog solution objective values are equal", {86expect_that(opt.pa$out, equals(opt.qp$value))87})8889##### Box #####90# Upper and lower bounds (i.e. box constraints)91lb <- rep(0.05, m)92ub <- rep(0.55, m)9394Amat <- rbind(1, diag(m), -diag(m))95rhs <- c(1, lb, -ub)9697# Update box constraints in portfolio98portf$constraints[[2]]$min <- lb99portf$constraints[[2]]$max <- ub100101# Solve optimization with quadprog102opt.qp <- solve.QP(Dmat=objQ, dvec=objL, Amat=t(Amat), bvec=rhs, meq=1)103104# Solve optimization with PortfolioAnalytics105opt.pa <- optimize.portfolio(R, portf, optimize_method="quadprog")106weights <- as.numeric(extractWeights(opt.pa))107108109test_that("Box: PortfolioAnalytics and quadprog solution weights are equal", {110expect_that(weights, equals(opt.qp$solution))111})112113test_that("Box: PortfolioAnalytics bounds are respected", {114expect_that(all(weights >= lb) & all(weights <= ub), is_true())115})116117test_that("Box: quadoprog bounds are respected", {118expect_that(all(opt.qp$solution >= lb) & all(opt.qp$solution <= ub), is_true())119})120121test_that("Box: PortfolioAnalytics and quadprog solution objective values are equal", {122expect_that(opt.pa$out, equals(opt.qp$value))123})124125##### Box with Shorting #####126# Upper and lower bounds (i.e. box constraints)127lb <- rep(-0.05, m)128ub <- rep(0.55, m)129130Amat <- rbind(1, diag(m), -diag(m))131rhs <- c(1, lb, -ub)132133# Update box constraints in portfolio134portf$constraints[[2]]$min <- lb135portf$constraints[[2]]$max <- ub136137# Solve optimization with quadprog138opt.qp <- solve.QP(Dmat=objQ, dvec=objL, Amat=t(Amat), bvec=rhs, meq=1)139140# Solve optimization with PortfolioAnalytics141opt.pa <- optimize.portfolio(R, portf, optimize_method="quadprog")142weights <- as.numeric(extractWeights(opt.pa))143144145test_that("Box with Shorting: PortfolioAnalytics and quadprog solution weights are equal", {146expect_that(weights, equals(opt.qp$solution))147})148149test_that("Box with Shorting: PortfolioAnalytics bounds are respected", {150expect_that(all(weights >= lb) & all(weights <= ub), is_true())151})152153test_that("Box with Shorting: quadprog bounds are respected", {154expect_that(all(opt.qp$solution >= lb) & all(opt.qp$solution <= ub), is_true())155})156157test_that("Box with Shorting: PortfolioAnalytics and quadprog solution objective values are equal", {158expect_that(opt.pa$out, equals(opt.qp$value))159})160161162163164