efrontier: Compute the minimum-variance efficient frontier over a target...

Description Usage Arguments Value Examples

Description

efrontier returns a list with efficient frontier results, plus solution information.

Usage

1
efrontier(er.target.vec, ersd, cormat, aa.lb = -1e+09, aa.ub = 1e+09)

Arguments

er.target.vec

Vector of targeted expected returns

ersd

data frame with 1 row per asset class: class (class name), er (expected return), sd (standard deviation)

cormat

Correlation matrix for asset class returns. Assumed to be positive definite.

aa.lb

Asset allocation lower bound. Can be scalar applied to all classes, or vector of length # of asset classes.

aa.ub

Asset allocation upper bound. Can be scalar applied to all classes, or vector of length # of asset classes.

Value

eflist if covariance matrix is positive definite, FALSE if not.

Examples

 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
library("magrittr")
library("quadprog")
library("tidyverse")

# Get no-bounds and bounded efficient frontiers for the Stalebrink capital market assumptions
ef.nobound <- efrontier(seq(.00, .20, .0025), stalebrink$ersd, stalebrink$cormat)
ef.noshort <- efrontier(seq(.00, .20, .0025), stalebrink$ersd, stalebrink$cormat, 0, 1)

# create a data frame with just the data we want
efdf <- bind_rows(ef.nobound$efrontier %>% mutate(rule="no bounds on allocation"),
                  ef.noshort$efrontier %>% mutate(rule="no shorts or leverage")) %>%
        filter(type=="high", !is.na(per))

# graph the unbounded and bounded frontiers, and the asset-class assumptions
ggplot() +
  geom_line(data=efdf, aes(psd, per, colour=rule)) +
    scale_x_continuous(name="Standard deviation", breaks=seq(0, .3, .025), labels = scales::percent) +
    scale_y_continuous(name="Expected return", breaks=seq(0, .2, .01), labels = scales::percent) +
    ggtitle("Efficient frontier for the Stalebrink capital market assumptions", subtitle="With and without bounds on asset allocations") +
    # now add the asset-class points
    geom_point(data=ef.nobound$ersd, aes(x=sd, y=er)) +
    geom_text(data=ef.nobound$ersd, aes(x=sd, y=er, label=class), nudge_y = +.003)

# Examine asset class weights for different classes
ef.noshort$weights %>%
filter(class %in% c("stocks", "cash", "bonds.dom")) %>%
  ggplot(aes(er.target, asset.weight, colour=class)) +
    geom_line()

# Compare weights for an asset class, optimized with and without bounds
aclass <- "stocks"
wts <- bind_rows(ef.nobound$weights %>% mutate(rule="no bounds on allocation"),
                ef.noshort$weights %>% mutate(rule="no shorts or leverage")) %>%
      filter(class==aclass)

wts %>%
      ggplot(aes(er.target, asset.weight, colour=rule)) +
      geom_line() +
      geom_hline(yintercept=0) +
      ggtitle(paste0(aclass, " weights"))

donboyd5/portopt documentation built on May 20, 2019, 2:58 p.m.