So I have the monthly returns on the SP500 in addition to the risk free rate in a zoo timeseries object called SP500.df
. I want to backtest two different trading strategies and plot them in a graph. In form of either cumulative return, or just how much 1$ intial investment would be at end of period.
Strategy 1: buy and hold SP500 the whole period.
Strategy 2: Hold SP500 from nov - april (winter), then switch to risk free rate from may - october (summer).
Notice that I also have extracted the winter and summer return in two respective vectors. called Winter_returns
and summer_returns
.
mkt= returns
rf= risk free rate
this is how dataframe SP500.df looks:
dput(head(SP500.df, 10))
structure(c(0.0286195, 0.03618317, -0.01363269, 0.02977401, 0.04461314,
0.0015209, -0.03207303, -0.0079275, 0.01882991, 0.00584478, 0.02372219,
0.03299206, -0.017908, 0.02540426, 0.04163062, -0.00317315, -0.03732322,
-0.0109474, 0.0147047, 0.00087712, 0.00608527826274047, 0.00495046849033236,
0.00503506482970477, 0.00481634688889247, 0.00424210936461577,
0.00358500724272255, 0.00424210936461577, 0.00480928182207086,
0.00485872460615713, 0.00487990531586144, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0), .Dim = c(10L, 6L), .Dimnames = list(NULL, c("MKT", "CAP",
"RF", "dummy", "dummyJAN", "adjdummy")), index = structure(c(-36494,
-36466, -36435, -36405, -36374, -36344, -36313, -36282, -36252,
-36221), class = "Date"), class = "zoo")
Here is a way.
Define a calculations function calc
and apply it to the column MKT
to have strategy 1 then create a vector of all returns/rates rates
and apply the function to it. The plot uses base R graphics.
library(zoo)
calc <- function(x, returns) x*cumprod((1 + returns))
strat1 <- calc(1, SP500.df$MKT)
strat1
#> 1870-01-31 1870-02-28 1870-03-31 1870-04-30 1870-05-31 1870-06-30 1870-07-31
#> 1.028620 1.065838 1.051308 1.082610 1.130908 1.132628 1.096301
#> 1870-08-31 1870-09-30 1870-10-31
#> 1.087610 1.108090 1.114567
i_winter <- SP500.df$dummy == 1
rates <- numeric(NROW(SP500.df))
rates[i_winter] <- SP500.df$MKT[i_winter]
rates[!i_winter] <- SP500.df$RF[!i_winter]
strat2 <- calc(1, rates)
strat2
#> [1] 1.028620 1.065838 1.051308 1.082610 1.087202 1.091100 1.095728 1.100998
#> [9] 1.106347 1.111746
matplot(cbind(strat1, strat2), pch = 19)
matlines(cbind(strat1, strat2), lty = "solid")
legend("bottomright", legend = c("strategy 1", "strategy 2"),
col = 1:2, lty = "solid", pch = 19)
Created on 2022-02-07 by the reprex package (v2.0.1)
With ggplot2
graphics, create a temporary data.frame and pipe it to package tidyr
's reshaping function pivot_longer
. Then pipe the result to ggplot
.
library(ggplot2)
data.frame(
date = index(SP500.df),
strategy1 = strat1,
strategy2 = strat2
) |>
tidyr::pivot_longer(-date) |>
ggplot(aes(date, value, color = name)) +
geom_line() +
geom_point() +
scale_color_manual(values = c("black", "red")) +
theme_bw()
Created on 2022-02-07 by the reprex package (v2.0.1)