Raw backtest computations in R

This note – which originated from an answer on Stack Exchange/Quantitative Finance – discusses how raw signals can be translated into P/L or returns.

Raw P/L computation from a vector of signals in R can be quite fast. As signal, I define a vector that is 1 if the portfolio is long, and 0 if it is not invested. In different words, the signals define the position; the changes in the signal define trades.

P <- c(100, 99, 104, 103, 105, 104)  ## price series
S <- c(  0,  1,   1,   0,   1,   0)  ## position to be held
dS <- c(0, diff(S))                  ## change in position ==> trades
(portfolio.value <- S*P - cumsum(dS*P))

Proportional Transactions costs are easy to add.

dSP <- dS*P ## with 10bp proportional fees
(portfolio.value <- S*P - cumsum(dSP) - cumsum(abs(dSP)*0.001))

We have now stored all trades in the vector dS. Here is a sketch how you could handle the trades, using package PMwR (which I maintain).

## trades
library("PMwR")
J <- journal(amount = dS, price = P, timestamp = seq_along(P))
J
pl(J)

pl will give the total P/L. But you can easily split up the trades.

  trade <- dS != 0
  trades <- split_trades(amount = dS[trade],
                         price = P[trade],
                         timestamp = seq_along(P)[trade])
  trades

Call pl for each single trade.

sapply(trades, function(x) pl(as.journal(x), pl.only = TRUE))