enrico schumann

# 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
```