knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

Introduction

The investmentsim package implements a function make_path to simulate an investment portfolio. It supports time-varying allocation of assets, automatic rebalancing, and planned transactions. The purpose of the package is to backtest investment plans as one might do for retirement accounts. (It does not have support for taxes or fees.)

Example

This example will demonstrate how to create an investment portfolio with defined allocations and transactions, and then simulate the balance of the portfolio over a period of time.

library(tidyverse)
library(xts)
library(lubridate)
library(investmentsim)

First let's create a portfolio. The simreturns data contains an xts time-series with fictional yearly returns for a stock fund and a bond fund over the years 1928 to 2018.

data(simreturns)
head(simreturns)

An asset in the investmentsim package is a function with parameters start and end that returns the percent change in the asset over the dates from start to end. The make_historical function will construct an asset given a time-series of returns. This function is supposed to be used when you want to use predetermined data as opposed to something generated at runtime.

simstock_asset <- make_historical(simreturns$Stock.Returns)
simbond_asset <- make_historical(simreturns$Bond.Returns)

Next we define a portfolio with the make_portfolio function. It takes a list of names for the assets together with the functions defining them and a list for their initial balances. Also, let's define a sequences of dates over which we'll run the simulation.

asset_names <- c("Stocks", "Bonds")
port <- make_portfolio(asset_names,
                       c(simstock_asset,
                         simbond_asset),
                       c(2500, 2500))
dates <- seq(ymd("1940-01-01"), ymd("2010-01-01"), by="years")

Then we can define our desired allocations with make_linear_allocation. It needs a list of dates and also a list of percentages for each asset.

alloc <- make_linear_allocation_path(asset_names,
                                     c(ymd("1970-01-01"),
                                       ymd("2000-01-01")),
                                     list(c(0.9, 0.1),
                                          c(0.4, 0.6)))

It's easiest to see how it works by looking at a graph.

as <- map(dates,
          alloc) %>%
    do.call(rbind, .) %>%
    xts(order.by = dates)

plot(as, ylim = c(0, 1),
     col = c("red", "blue"),
     main = "Asset Allocation")
addLegend("topright",
          asset_names,
          col = c("red", "blue"),
          lty = 1, cex = 1,
          bty = "o")

Finally, we can define our desired transactions and collect everything together in a model. The make_transactions_on_dates function does what it sounds like it does: defines for the model a specified deposit (positive value) or a specified withdrawal (negative value). Within the simulation, transactions are applied at the end of the years given. So this transaction path just makes a $1000 deposit at the end of each year.

trans <- make_transactions_on_dates(rep(1000, length(dates)),
                                    dates)
model <- make_model(port, alloc, trans, dates)

Lastly, we evaluate make_path on the model to run the simulation.

path <- make_path(model)
c(head(path), tail(path))
plot(path[,1:3],
     col = c("red", "blue", "green"),
     main = "Investment Path")
addLegend("topleft",
          c(asset_names, "Total"),
          col = c("red", "blue", "green"),
          lty = 1, cex = 1,
          bty = "o")

We're rich!



ryanholbrook/investmentsim documentation built on Nov. 5, 2019, 5:10 a.m.