Conditional Rebalancing
The default in btest
is to compute a signal and
rebalance at every instance of time, which
typically means at any price observation passed to the
function. Sometimes we may prefer to rebalance only
when the current position deviates meaningfully from
the target position. This example shows a way to
implement such conditional rebalancing.
We start by attaching the package and creating some toy data.
library("PMwR") p1 <- rep(100, 5) p2 <- p1 + seq(from = 0, to = 20, length.out = length(p1)) P <- cbind(p1, p2) P
p1 p2 [1,] 100 100 [2,] 100 105 [3,] 100 110 [4,] 100 115 [5,] 100 120
Suppose we wish to hold an equally-weighted portfolio of both assets.
bt <- btest(list(P), signal = function() c(0.5, 0.5), convert.weights = TRUE, initial.cash = 100) journal(bt)
instrument timestamp amount price 1 p1 2 0.50000000 100 2 p2 2 0.50000000 105 3 p2 3 -0.02380952 110 4 p1 4 0.01250000 100 5 p2 4 -0.01028139 115 6 p1 5 0.01190476 100 7 p2 5 -0.00990495 120 7 transactions
btest
accepts an argument do.rebalance
, which is a
function that should return TRUE
if rebalancing is to
take place. Its effect is most clearly demonstrated
when we have it return FALSE
instead.
journal(bt <- btest(list(P), signal = function() c(0.5, 0.5), do.rebalance = function() FALSE, convert.weights = TRUE, initial.cash = 100))
no transactions
There is no trade at all. It is more useful to have
do.rebalance
react to the current position.
do.rebalance <- function() { ## btest stores only positions, not weights; but ## weights may be computed from positions weights <- Portfolio()*Close()/Wealth() cat(Time(), ": ", weights, "\n") if (any(abs(weights - c(0.5, 0.5)) > 0.03)) TRUE else FALSE } journal(bt <- btest(list(P), signal = function() c(.5, .5), do.rebalance = do.rebalance, convert.weights = TRUE, initial.cash = 100))
1 : 0 0 2 : 0.5 0.525 3 : 0.4878049 0.5365854 4 : 0.4880952 0.5102814 instrument timestamp amount price 1 p1 2 0.50000000 100 2 p2 2 0.50000000 105 3 p1 4 0.01250000 100 4 p2 4 -0.03409091 115 4 transactions