targetbeta_twofunds: Backtest a Two-Fund Strategy that Targets a Certain Beta

Description Usage Arguments Details Value Examples

View source: R/targetbeta_twofunds.R

Description

Implements a two-fund strategy where allocations to each fund are adjusted to maintain some user-specified portfolio beta. For example, you could back-test a zero-beta (i.e. market neutral) UPRO/VBLTX strategy using this function.

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
targetbeta_twofunds(
  tickers = NULL,
  intercepts = NULL,
  slopes = NULL,
  ...,
  benchmark.ticker = NULL,
  reference.tickers = NULL,
  tickers.gains = NULL,
  benchmark.gains = NULL,
  reference.gains = NULL,
  target.beta = 0,
  tol = 0.15,
  window.units = 50,
  failure.method = "closer",
  maxall.tol = tol - 0.05,
  initial = 10000
)

Arguments

tickers

Character vector specifying 2 ticker symbols that Yahoo! Finance recognizes, if you want to download data on the fly.

intercepts

Numeric vector of values to add to daily gains for each fund.

slopes

Numeric vector of values to multiply daily gains for each fund by. Slopes are multiplied prior to adding intercepts.

...

Arguments to pass along with tickers to load_gains.

benchmark.ticker

Character string specifying ticker symbol for benchmark index for calculating beta. If unspecified, the first fund in tickers is used as the benchmark.

reference.tickers

Character vector of ticker symbols to include on graph as data points for comparative purposes.

tickers.gains

Data frame with one column of gains for each investment and a date variable named Date.

benchmark.gains

Numeric vector of gains for the benchmark index for calculating beta. If unspecified, the first fund in tickers.gains is used as the benchmark.

reference.gains

Numeric vector or matrix of gains for funds to include on graph as data points for comparative purposes.

target.beta

Numeric value.

tol

Numeric value specifying how far the effective portfolio beta has to deviate from target.beta to trigger a rebalancing trade.

window.units

Numeric value specifying the width of the trailing moving window used to estimate each fund's beta.

failure.method

Character string or vector specifying method(s) to use when fund betas are such that the target portfolio beta cannot be achieved. Choices are "cash", "fund1", "fund2", "fund1.maxall", "fund2.maxall", "inverse1", "inverse2", and "closer". See Details.

maxall.tol

Numeric value specifying tolerance to use when implementing the "fund1.maxall" or "fund2.maxall" failure method. To illustrate, if target.beta = 0, fund 1 has a current beta of 1, fund 2 has a current beta of 0.25, failure.method = "fund2.maxall", and maxall.tol = 0.1, a trade will be triggered that results in 40% fund 2 and 60% cash. The portfolio beta is 0.4 * 0.25 = 0.1. The reason you might want maxall.tol to be less than tol is to avoid frequently triggering another trade on the very next day, as fund 2's beta changes a little and moves the portfolio beta outside of [target.beta - tol, target.beta + tol].

initial

Numeric value specifying what value to scale initial prices to.

Details

The general implementation is as follows. Beta for each of the two funds is estimated based on the first window.units gains. Initial allocations are selected to achieve portfolio beta of target.beta. If that is not possible - for example, if target.beta = 0 and both funds have positive beta - then the action taken depends on what method is selected through the failure.method input (details below).

Assuming the target beta is attainable, the function moves over 1 day, and applies each fund's gains for that day. It then re-calculates each fund's beta based on the window.units-width interval, and determines the effective portfolio beta based on fund allocations and betas. If the effective beta is outside of [target.beta - tol, target.beta + tol], a rebalancing trade is triggered. As before, if the target beta cannot be achieved, certain actions are taken depending on the selected method.

When outside of a trade because the target beta could not be achieved, the function attempts to rebalance each time it shifts over to a new day, regardless of the effective portfolio beta.

When failure.method = "cash", the entire portfolio balance is allocated to cash when the target beta cannot be achieved.

When failure.method = "fund1" (or "fund2"), the entire portfolio balance is allocated to the first (or second) fund when the target beta cannot be achieved.

When failure.method = "fund1.maxall" (or "fund2.maxall"), when the target beta cannot be achieved, fund 1 (or fund 2) is combined with cash, with the fund 1 (fund 2) allocation as high as possible while staying within maxall.tol of target.beta.

When failure.method = "inverse1" (or "inverse2"), an inverse version of the first (or second) fund is used when the target beta cannot be achieved. In many cases where the target beta cannot be achieved with the two funds, it can be achieved with an inverse version of one and the other. If the target beta still cannot be achieved, the entire portfolio balance is allocated to cash.

When failure.method = "closer", the entire portfolio balance is allocated to whichever fund has a beta closer to target.beta.

Value

For each method, a 4-element list containing:

  1. Numeric matrix named fund.balances giving fund balances over time.

  2. Numeric matrix named fund.betas giving fund betas over time.

  3. Numeric vector named effective.betas giving effective portfolio beta over time.

  4. Numeric value named trades giving the total number of trades executed.

Examples

1
2
3
4
5
6
## Not run: 
# Backtest zero-beta UPRO/VBLTX strategy
beta0 <- targetbeta_twofunds(tickers = c("UPRO", "VBLTX"), target.beta = 0)
plot(beta0$fund.balances$Portfolio)

## End(Not run)

vandomed/stocks documentation built on July 22, 2020, 3:25 a.m.