back_test | R Documentation |
RcppArmadillo
.Simulate (backtest) a rolling portfolio optimization strategy, using
RcppArmadillo
.
back_test(
retx,
retp,
controlv,
startp,
endd,
lambda = 0,
coeff = 1,
bidask = 0
)
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 |
coeff |
A numeric multiplier of the weights. (The
default is |
bidask |
A numeric bid-ask spread (the default is
|
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
.
A column vector of strategy returns, with the same length as
the number of rows of retp
.
## 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)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.