back_test: Simulate (backtest) a rolling portfolio optimization...

View source: R/RcppExports.R

back_testR Documentation

Simulate (backtest) a rolling portfolio optimization strategy, using RcppArmadillo.

Description

Simulate (backtest) a rolling portfolio optimization strategy, using RcppArmadillo.

Usage

back_test(
  retx,
  retp,
  controlv,
  startp,
  endd,
  lambda = 0,
  coeff = 1,
  bidask = 0
)

Arguments

retp

A time series or a matrix of asset returns data.

retx

A time series or a matrix of excess returns data (the returns in excess of the risk-free rate).

controlv

A list of portfolio optimization model parameters (see Details).

startp

An integer vector of start points.

endd

An integer vector of end points.

lambda

A decay factor which multiplies the past portfolio weights. (The default is lambda = 0 - no memory.)

coeff

A numeric multiplier of the weights. (The default is 1)

bidask

A numeric bid-ask spread (the default is 0)

Details

The function back_test() performs a backtest simulation of a rolling portfolio optimization strategy over a vector of the end points endd.

It performs a loop over the end points endd, and subsets the matrix of the excess asset returns retx along its rows, between the corresponding start point and the end point.

The function back_test() passes the subset matrix of excess returns into the function calc_weights(), which calculates the optimal portfolio weights at each end point. It also passes to calc_weights() the argument controlv, which is the list of portfolio optimization parameters. See the function calc_weights() for more details. The list of portfolio optimization parameters can be created using the function param_portf().

The function back_test() then recursively averages the weights w_i at the end point = i with the weights w_{i-1} from the previous end point = (i-1), using the decay factor lambda = \lambda:

w_i = (1-\lambda) w_i + \lambda w_{i-1}

The purpose of averaging the weights is to reduce their variance, and improve their out-of-sample performance. It is equivalent to extending the portfolio holding period beyond the time interval between neighboring end points.

The function back_test() then calculates the out-of-sample strategy returns by multiplying the average weights times the future asset returns.

The function back_test() multiplies the out-of-sample strategy returns by the coefficient coeff (with default equal to 1), which allows simulating either a trending strategy (if coeff = 1), or a reverting strategy (if coeff = -1).

The function back_test() calculates the transaction costs by multiplying the bid-ask spread bidask times the absolute difference between the current weights minus the weights from the previous period. Then it subtracts the transaction costs from the out-of-sample strategy returns.

The function back_test() returns a time series (column vector) of strategy returns, of the same length as the number of rows of retp.

Value

A column vector of strategy returns, with the same length as the number of rows of retp.

Examples

## Not run: 
# Calculate the ETF daily excess returns
retp <- na.omit(rutils::etfenv$returns[, 1:16])
# riskf is the daily risk-free rate
riskf <- 0.03/260
retx <- retp - riskf
# Define monthly end points without initial warmup period
endd <- rutils::calc_endpoints(retp, interval="months")
endd <- endd[endd > 0]
nrows <- NROW(endd)
# Define 12-month look-back interval and start points over sliding window
lookb <- 12
startp <- c(rep_len(1, lookb-1), endd[1:(nrows-lookb+1)])
# Define return shrinkage and dimension reduction
alphac <- 0.5
dimax <- 3
# Create a list of portfolio optimization parameters
controlv <- HighFreq::param_portf(method="maxsharpe", dimax=dimax, alphac=alphac, scalew="sumsq")
# Simulate a monthly rolling portfolio optimization strategy
pnls <- HighFreq::back_test(retx, retp, controlv=controlv, startp=(startp-1), endd=(endd-1))
pnls <- xts::xts(pnls, index(retp))
colnames(pnls) <- "strategy"
# Plot dygraph of strategy
dygraphs::dygraph(cumsum(pnls), 
  main="Cumulative Returns of Max Sharpe Portfolio Strategy")

## End(Not run)


algoquant/HighFreq documentation built on Oct. 26, 2024, 9:20 p.m.