Skip to content

Commit ce7cad7

Browse files
committed
Refactor addTA to use panel functionality
When "ta" is not characters of functions from TTR (SMA, BBands, ...), shading regime or new series are added if "ta" is logic or an object of xts class, respectively.
1 parent bdac3b4 commit ce7cad7

File tree

1 file changed

+98
-26
lines changed

1 file changed

+98
-26
lines changed

R/TA.R

Lines changed: 98 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,42 +38,114 @@ function(ta, order=NULL, on=NA, legend='auto', yrange=NULL, ...) {
3838
plot(do.call(paste('add',ta,sep=''),list(...)))
3939
} else stop(paste('no TA method found for',paste('add',ta,sep='')))
4040
} else {
41-
lchob <- get.current.chob()
42-
chobTA <- new("chobTA")
43-
if(any(is.na(on))) {
44-
chobTA@new <- TRUE
45-
} else {
46-
chobTA@new <- FALSE
47-
chobTA@on <- on
41+
lenv <- new.env()
42+
lenv$chartTA <- function(x, ta, order, on, legend, yrange, ...) {
43+
xsubset <- x$Env$xsubset
44+
if(!is.null(order)) ta <- ta[,order]
45+
if(all(is.na(on))) {
46+
xlim <- x$Env$xlim
47+
frame <- x$get_frame()
48+
print(frame)
49+
ylim <- x$get_ylim()[[frame]]
50+
theme <- x$Env$theme
51+
y_grid_lines <- x$Env$y_grid_lines
52+
53+
# add inbox color
54+
rect(xlim[1], ylim[1], xlim[2], ylim[2], col=theme$fill)
55+
# add grid lines and left-side axis labels
56+
segments(xlim[1], y_grid_lines(ylim),
57+
xlim[2], y_grid_lines(ylim),
58+
col = theme$grid, lwd = x$Env$grid.ticks.lwd, lty = 3)
59+
text(xlim[1], y_grid_lines(ylim), y_grid_lines(ylim),
60+
col = theme$labels, srt = theme$srt,
61+
offset = 0.5, pos = 2, cex = theme$cex.axis, xpd = TRUE)
62+
# add border of plotting area
63+
rect(xlim[1], ylim[1], xlim[2], ylim[2], border=theme$labels)
64+
}
65+
if(is.logical(ta)) {
66+
ta <- merge(ta, xdata, join="right",retside=c(TRUE,FALSE))[xsubset]
67+
shade <- shading(as.logical(ta,drop=FALSE))
68+
if(length(shade$start) > 0) # all FALSE cause zero-length results
69+
rect(shade$start-1/3, ylim[1] ,shade$end+1/3, ylim[2], col=theme$BBands$col$fill,...)
70+
} else {
71+
# we can add points that are not necessarily at the points
72+
# on the main series
73+
subset.range <- paste(start(xdata[xsubset]),
74+
end(xdata[xsubset]),sep="/")
75+
ta.adj <- merge(n=.xts(1:NROW(xdata[xsubset]),
76+
.index(xdata[xsubset]), tzone=indexTZ(xdata)),ta)[subset.range]
77+
ta.x <- as.numeric(na.approx(ta.adj[,1], rule=2) )
78+
ta.y <- ta.adj[,-1]
79+
for(i in 1:NCOL(ta.y))
80+
lines(ta.x, as.numeric(ta.y[,i]), ...)
81+
}
4882
}
49-
nrc <- NROW(lchob@xdata)
83+
if(!is.character(legend) || legend == "auto")
84+
legend <- gsub("^add", "", deparse(match.call()))
85+
# map all passed args (if any) to 'lenv' environment
86+
mapply(function(name,value) { assign(name,value,envir=lenv) },
87+
names(list(ta=ta,order=order,on=on,legend=legend,yrange=yrange,...)),
88+
list(ta=ta,order=order,on=on,legend=legend,yrange=yrange,...))
89+
exp <- parse(text=gsub("list","chartTA",
90+
as.expression(substitute(list(x=current.chob(),
91+
ta=get("ta"),order=order,
92+
on=on,legend=legend,
93+
yrange=yrange,...)))),
94+
srcfile=NULL)
95+
exp <- c(exp, expression(
96+
frame <- get_frame(),
97+
lc <- xts:::legend.coords("topleft", xlim, ylim[[frame]]),
98+
legend(x = lc$x, y = lc$y,
99+
legend = c(paste(legend, ":"),
100+
paste(sprintf("%.3f", last(ta)))),
101+
text.col = c(theme$fg, col),
102+
xjust = lc$xjust,
103+
yjust = lc$yjust,
104+
bty = "n",
105+
y.intersp=0.95)))
106+
107+
lchob <- current.chob()
108+
ncalls <- length(lchob$Env$call_list)
109+
lchob$Env$call_list[[ncalls + 1]] <- match.call()
110+
if(!hasArg(col)) lenv$col <- lchob$Env$theme$BBands$col$ma
111+
xdata <- lchob$Env$xdata
112+
xsubset <- lchob$Env$xsubset
113+
nrc <- NROW(xdata)
50114

51115
ta <- try.xts(ta, error=FALSE)
52116

53117
if(is.xts(ta)) {
54-
x <- merge(lchob@xdata, ta, fill=ifelse(is.logical(ta),0,NA),join='left', retside=c(FALSE,TRUE))
118+
x <- merge(xdata, ta, fill=ifelse(is.logical(ta),0,NA),join='left', retside=c(FALSE,TRUE))
55119
} else {
56120
if(NROW(ta) != nrc)
57121
stop('non-xtsible data must match the length of the underlying series')
58-
x <- merge(lchob@xdata, ta, join='left', retside=c(FALSE,TRUE))
122+
x <- merge(xdata, ta, join='left', retside=c(FALSE,TRUE))
59123
}
60124
if(is.logical(ta))
61125
x <- as.logical(x, drop=FALSE) #identical to storage.mode(x)<-"logical"
62-
63-
chobTA@TA.values <- coredata(x)[lchob@xsubset,]
64-
chobTA@name <- "chartTA"
65-
chobTA@call <- match.call()
66-
chobTA@params <- list(xrange=lchob@xrange,
67-
yrange=yrange,
68-
colors=lchob@colors,
69-
spacing=lchob@spacing,
70-
width=lchob@width,
71-
bp=lchob@bp,
72-
isLogical=is.logical(ta),
73-
x.labels=lchob@x.labels,
74-
order=order,legend=legend,
75-
pars=list(list(...)),
76-
time.scale=lchob@time.scale)
126+
127+
lenv$xdata <- structure(x, .Dimnames=list(NULL, names(x)))
128+
lenv$ta <- lchob$Env$TA$ta <- x
129+
lenv$get_frame <- lchob$get_frame
130+
if(all(is.na(on))) {
131+
if(missing(yrange))
132+
lchob$add_frame(ylim=range(lenv$ta[xsubset],na.rm=TRUE), asp=1)
133+
else {
134+
lchob$add_frame(ylim=lenv$yrange, asp=1)
135+
}
136+
lchob$next_frame()
137+
lchob$replot(exp, env=c(lenv, lchob$Env), expr=TRUE)
138+
}
139+
else {
140+
for(i in seq_along(on)) {
141+
lchob$set_frame(on[i]+1L)
142+
if(!missing(yrange)) {
143+
frame <- lchob$get_frame()
144+
lchob$Env$ylim[[frame]] <- structure(yrange, fixed=FALSE)
145+
}
146+
lchob$replot(exp, env=c(lenv, lchob$Env), expr=TRUE)
147+
}
148+
}
77149
# if(is.null(sys.call(-1))) {
78150
79151
# [email protected]$TA <- c(TA,chobTA)
@@ -82,7 +154,7 @@ function(ta, order=NULL, on=NA, legend='auto', yrange=NULL, ...) {
82154
# #quantmod:::chartSeries.chob(lchob)
83155
# invisible(chobTA)
84156
# } else {
85-
return(chobTA)
157+
lchob
86158
# }
87159
}
88160
}#}}}

0 commit comments

Comments
 (0)