xts
xts copied to clipboard
a bug in plot.xts() and a possible solution / feature request
This code was extracted (with minor modifications/additions) from quantstrat::chart.forward.training
and based on the data supplied with demo(luxor.sample.walk.forward)
, using R 3.2.2 on Windows 7.
require(devtools) # version 1.9.1
install_github("joshuaulrich/xts") # as of 2015 November 07
require(quantstrat) # version 0.9.1687
audit.filename <- (paste0(path.package("quantstrat"),"/data/luxor.wfa.ples.RData"))
.audit <- NULL
load(audit.filename)
portfolios.st = ls(name = .audit, pattern = "portfolio.*")
n <- length(portfolios.st)
PL.xts <- xts()
for (portfolio.st in portfolios.st) {
p <- getPortfolio(portfolio.st, envir = .audit)
from <- index(p$summary[2])
R <- cumsum(p$summary[paste(from, "/", sep = ""), "Net.Trading.PL"])
names(R) <- portfolio.st
PL.xts <- cbind(PL.xts, R)
}
chosen.one <- .audit$param.combo.nr
chosen.portfolio.st = ls(name = .audit, pattern = glob2rx(paste("portfolio",
"*", chosen.one, sep = ".")))
R <- PL.xts[, chosen.portfolio.st]
PL.xts <- cbind(PL.xts, R)
PL.xts <- na.locf(PL.xts)
CumMax <- cummax(PL.xts)
Drawdowns.xts <- -(CumMax - PL.xts)
data.to.plot <- as.xts(cbind(PL.xts, Drawdowns.xts))
# DEMONSTRATION OF THE BUG:
# Clears each panel before drawing, so instead of 32 lines, there are only 2
plot.xts(data.to.plot,multi.panel=2,main='Walk Forward Analysis',
col = c(rep("grey", n), "blue"))
# FEATURE SUGGESTION AS A POSSIBLE SOLUTION:
# Vectorized panel plot ordering would be nice (seems it's not currently implemented)
on_ = c(rep(1,n+1),rep(2,n+1))
plot.xts(data.to.plot,multi.panel=2,main='Walk Forward Analysis',
col = c(rep("grey", n), "blue"), on=on_)
cloudcello, thank you for the reproducible example. From the ?plot.xts
and the multi.panel
argument,
For example, if multi.panel = 2, then the data will be plotted in groups of 2 columns and each group is plotted in a separate panel.
In your example, calling plot.xts
with multi.panel=2
is actually creating 15 plot windows with 2 panels in each window. Also explained in the documentation, on
is not an argument for plot.xts
, it is an argument for lines.xts
and points.xts
.
This should produce the plot you are looking for
plot(PL.xts, col=c("blue", rep("grey", n-1)), main="Walk Forward Analysis")
# set on=NA so it is drawn on a new panel
lines(Drawdowns.xts, col=c("blue", rep("grey", n-1)), on=NA, main="Drawdowns")
I think we may have a bug with multi.panel
behavior that I need to explore further.
Thank you for the solution, Ross. I definitely missed that option ("on=NA") while reading help. Also, I'm glad this has been helpful. Just one more comment: I think the code must nevertheless be as follows (as the total number of lines drawn is not n, but rather n+1:
plot(PL.xts, col=c("blue", rep("grey", n)), main="Walk Forward Analysis")
# set on=NA so it is drawn on a new panel
lines(Drawdowns.xts, col=c("blue", rep("grey", n)), on=NA, main="Drawdowns")