From fc0467a18b6a948a2215ecebfca64b1a8c646e3c Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Sun, 10 Jul 2016 23:36:22 +0800 Subject: [PATCH 01/12] Refactor chartSeries to a wrapper for chart_Series Remain the code that handles argument differ from chart_Series in the original chartSeries function. Parameters created by chartTheme() are passed to the plot object and coordinate with parameters created by chart_theme(), theme$BBands, for example. --- R/chartSeries.R | 139 +++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 79 deletions(-) diff --git a/R/chartSeries.R b/R/chartSeries.R index b563ca74..523d1530 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -402,7 +402,7 @@ function(x, sub.index <- index(do.call(subsetvec[1],list(x,subset.n))) xsubset <- which(index(x) %in% sub.index) } else xsubset <- which(index(x) %in% index(x[subset])) - } else xsubset <- 1:NROW(x) + } else xsubset <- "" xdata <- x x <- x[xsubset] @@ -457,101 +457,82 @@ function(x, chart <- ifelse(NROW(x) > 300,"matchsticks","candlesticks") } if(chart[1]=="candlesticks") { - spacing <- 3 + #spacing <- 3 width <- 3 } else if(chart[1]=="matchsticks" || chart[1]=='line') { - spacing <- 1 + #spacing <- 1 width <- 1 } else if(chart[1]=="bars") { - spacing <- 4 + #spacing <- 4 width <- 3 if(NROW(x) > 60) width <- 1 } - ep <- axTicksByTime(x,major.ticks) - x.labels <- names(ep) - - chob <- new("chob") - chob@call <- match.call(expand.dots=TRUE) if(is.null(name)) name <- as.character(match.call()$x) + cs <- chart_Series(x = xdata, name = name, type = chart[1], + subset = xsubset, yaxis.left = FALSE, ...) - chob@xdata <- xdata - chob@xsubset <- xsubset - chob@name <- name - chob@type <- chart[1] - - chob@xrange <- c(1,NROW(x)) if(is.OHLC(x)) { - chob@yrange <- c(min(Lo(x),na.rm=TRUE),max(Hi(x),na.rm=TRUE)) - } else chob@yrange <- range(x[,1],na.rm=TRUE) + cs$Env$ylim[[2]] <- structure(c(min(Lo(x),na.rm=TRUE),max(Hi(x),na.rm=TRUE)), fixed = TRUE) + } else cs$Env$ylim[[2]] <- structure(range(x[,1],na.rm=TRUE), fixed = TRUE) if(!is.null(yrange) && length(yrange)==2) - chob@yrange <- yrange - - chob@log.scale <- log.scale + cs$Env$ylim[[2]] <- structure(yrange, fixed = TRUE) - chob@color.vol <- color.vol - chob@multi.col <- multi.col - chob@show.vol <- show.vol - chob@bar.type <- bar.type - chob@line.type <- line.type - chob@spacing <- spacing - chob@width <- width - chob@bp <- ep - chob@x.labels <- x.labels - chob@colors <- theme - chob@layout <- layout - chob@time.scale <- time.scale - chob@minor.ticks <- minor.ticks - chob@major.ticks <- major.ticks - - chob@length <- NROW(x) - - chob@passed.args <- as.list(match.call(expand.dots=TRUE)[-1]) - if(!is.null(TA)) { - - # important to force eval of _current_ chob, not saved chob - thisEnv <- environment() - if(is.character(TA)) TA <- as.list(strsplit(TA,TAsep)[[1]]) - #if(!has.Vo(x)) TA <- TA[-which(TA=='addVo()')] # remove addVo if no volume - chob@passed.args$TA <- list() - #if(length(TA) > 0) { - for(ta in 1:length(TA)) { - if(is.character(TA[[ta]])) { - chob@passed.args$TA[[ta]] <- eval(parse(text=TA[[ta]]),envir=thisEnv) - } else chob@passed.args$TA[[ta]] <- eval(TA[[ta]],envir=thisEnv) - } - # check if all args are indeed chobTA - poss.new <- sapply(chob@passed.args$TA, function(x) - { - if(isS4(x) && is(x, 'chobTA')) - return(x@new) - stop('improper TA argument/call in chartSeries', call.=FALSE) - } ) - if(length(poss.new) > 0) - poss.new <- which(poss.new) - chob@windows <- length(poss.new) + 1 - #chob@windows <- length(which(sapply(chob@passed.args$TA, - # function(x) ifelse(is.null(x),FALSE,x@new))))+1 - chob@passed.args$show.vol <- any(sapply(chob@passed.args$TA, - function(x) x@name=="chartVo")) - #} else { - # chob@windows <- 1 - # chob@passed.args$TA <- NULL - #} - } else chob@windows <- 1 + cs$Env$log.scale <- log.scale # special handling needed - #if(debug) return(str(chob)) - # re-evaluate the TA list, as it will be using stale data, - chob@passed.args$TA <- sapply(chob@passed.args$TA, function(x) { eval(x@call) } ) - - if(plot) # draw the chart - do.call('chartSeries.chob',list(chob)) + cs$Env$theme$up.col <- theme$up.col + cs$Env$theme$dn.col <- theme$dn.col + + # set bar color + cs$Env$theme$dn.up.col <- theme$dn.up.col + cs$Env$theme$up.up.col <- theme$up.up.col + cs$Env$theme$up.dn.col <- theme$up.dn.col + cs$Env$theme$dn.dn.col <- theme$dn.dn.col + + # set border color + cs$Env$theme$dn.up.border <- theme$dn.up.border + cs$Env$theme$up.up.border <- theme$up.up.border + cs$Env$theme$up.dn.border <- theme$up.dn.border + cs$Env$theme$dn.dn.border <- theme$dn.dn.border + + cs$Env$theme$bg <- theme$bg.col + cs$Env$theme$fg <- theme$fg.col + cs$Env$theme$labels <- theme$major.tick + # deprecated arguments(? + #cs$Env$theme$border + #cs$Env$theme$minor.tick + #cs$Env$theme$main.color + #cs$Env$theme$sub.col + #cs$Env$theme$fill + + cs$Env$color.vol <- color.vol + cs$Env$multi.col <- multi.col + cs$Env$show.vol <- show.vol + cs$Env$bar.type <- bar.type + cs$Env$line.type <- line.type + #cs$Env$theme$spacing <- spacing + cs$Env$theme$Expiry <- theme$Expiry + cs$Env$theme$width <- width + cs$Env$layout <- layout + cs$Env$time.scale <- time.scale + cs$Env$minor.ticks <- minor.ticks + cs$Env$major.ticks <- major.ticks + if(!show.grid){ + cs$Env$theme$grid <- NULL + cs$Env$theme$grid2 <- NULL + } else { + cs$Env$theme$grid <- theme$grid.col + cs$Env$theme$grid2 <- theme$grid.col + } - chob@device <- as.numeric(dev.cur()) + cs$Env$length <- NROW(x) + cs$Env$theme$bbands$col$fill <- theme$BBands.fill + cs$Env$theme$bbands$col$upper <- theme$BBands.col + cs$Env$theme$bbands$col$lower <- theme$BBands.col - write.chob(chob,chob@device) - invisible(chob) + if(plot) # draw the chart + cs } #}}} From 2c4bd0c3887be523241443fe4b2fab27ba59d318 Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Mon, 11 Jul 2016 18:50:50 +0800 Subject: [PATCH 02/12] Add legend to first panel Add legend to show the last close price of series. --- R/chartSeries.R | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/R/chartSeries.R b/R/chartSeries.R index 523d1530..02ffb715 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -533,6 +533,17 @@ function(x, cs$Env$theme$bbands$col$upper <- theme$BBands.col cs$Env$theme$bbands$col$lower <- theme$BBands.col + # add legend + text.exp <- expression( + Closes <- Cl(xdata), + lc <- xts:::legend.coords("topleft", xlim, get_ylim()[[2]]), + legend(x = lc$x, y = lc$y, + legend = paste("Last", last(Closes)), + text.col = theme$up.col, + bty='n', + y.intersp=0.95)) + cs$set_frame(2) + cs$add(text.exp, env=cs$Env, expr=TRUE) if(plot) # draw the chart cs } #}}} From b07da36faf15c9a4ed51830ceb9aedccbdb59695 Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Mon, 11 Jul 2016 19:58:12 +0800 Subject: [PATCH 03/12] Change minor ticks to be downward As the direction of minor ticks of the original chartSeries is downward, the second action of replot_xts-class object is modified to reach that. --- R/chartSeries.R | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/R/chartSeries.R b/R/chartSeries.R index 02ffb715..35d6cf9c 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -532,6 +532,16 @@ function(x, cs$Env$theme$bbands$col$fill <- theme$BBands.fill cs$Env$theme$bbands$col$upper <- theme$BBands.col cs$Env$theme$bbands$col$lower <- theme$BBands.col + + # change minor ticks to be downward + exp <- expression(if (NROW(xdata[xsubset]) < 400) { + axis(1, at = xycoords$x, labels = FALSE, col = theme$grid2, + col.axis = theme$grid2, tcl = -0.4) + }) + exp <- structure(exp, frame = 1) + exp <- structure(exp, clip = TRUE) + exp <- structure(exp, env = cs$Env) + cs$Env$actions[[2]] <- exp # add legend text.exp <- expression( From 51ae3cfcbffe5fcdf24ed19e5cd97f9cd7fddbb7 Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Sat, 16 Jul 2016 17:38:41 +0800 Subject: [PATCH 04/12] Add border and remove x-axis grid line To create the chart the same as quantmod::chartSeries, border of plotting area and inbox color are applied. Remove x-axis grid line. --- R/chartSeries.R | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/R/chartSeries.R b/R/chartSeries.R index 35d6cf9c..84922f80 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -473,6 +473,8 @@ function(x, if(is.null(name)) name <- as.character(match.call()$x) cs <- chart_Series(x = xdata, name = name, type = chart[1], subset = xsubset, yaxis.left = FALSE, ...) + # remove x-axis grid line + cs$Env$actions[[1]] <- NULL if(is.OHLC(x)) { cs$Env$ylim[[2]] <- structure(c(min(Lo(x),na.rm=TRUE),max(Hi(x),na.rm=TRUE)), fixed = TRUE) @@ -502,11 +504,11 @@ function(x, cs$Env$theme$fg <- theme$fg.col cs$Env$theme$labels <- theme$major.tick # deprecated arguments(? - #cs$Env$theme$border + cs$Env$theme$border <- theme$border #cs$Env$theme$minor.tick #cs$Env$theme$main.color #cs$Env$theme$sub.col - #cs$Env$theme$fill + cs$Env$theme$fill <- theme$fill cs$Env$color.vol <- color.vol cs$Env$multi.col <- multi.col @@ -541,7 +543,21 @@ function(x, exp <- structure(exp, frame = 1) exp <- structure(exp, clip = TRUE) exp <- structure(exp, env = cs$Env) - cs$Env$actions[[2]] <- exp + cs$Env$actions[[1]] <- exp + + # add border + exp.border <- expression(rect(xlim[1], get_ylim()[[2]][1], xlim[2], get_ylim()[[2]][2],col=theme$fill), + segments(xlim[1], y_grid_lines(get_ylim()[[2]]), xlim[2], + y_grid_lines(get_ylim()[[2]]), col = theme$grid, lwd = grid.ticks.lwd, + lty = grid.ticks.lty), text(xlim[2] + xstep * 2/3, y_grid_lines(get_ylim()[[2]]), + noquote(format(y_grid_lines(get_ylim()[[2]]), justify = "right")), + col = theme$labels, srt = theme$srt, offset = 0, pos = 4, + cex = theme$cex.axis, xpd = TRUE), + rect(xlim[1], get_ylim()[[2]][1], xlim[2], get_ylim()[[2]][2],border=theme$labels)) + exp.border <- structure(exp.border, frame = 2) + exp.border <- structure(exp.border, clip = TRUE) + exp.border <- structure(exp.border, env = cs$Env) + cs$Env$actions[[4]] <- exp.border # add legend text.exp <- expression( From 5160aea6edcbe876694ab78efc0d631054aa71e5 Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Sat, 16 Jul 2016 23:34:05 +0800 Subject: [PATCH 05/12] Reserve space of both sides In the original chartSeries, space of left and right sides is reserved. x limit is reset to reach that, which makes the chart more readable. Change inbox color from theme$fill to theme$area. Since the inbox area is behind of horizontal ticks and border should be on the top of the ticks, border is added after the ticks and the inbox area. --- R/chartSeries.R | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/R/chartSeries.R b/R/chartSeries.R index 84922f80..cb75e439 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -473,6 +473,9 @@ function(x, if(is.null(name)) name <- as.character(match.call()$x) cs <- chart_Series(x = xdata, name = name, type = chart[1], subset = xsubset, yaxis.left = FALSE, ...) + # set xlim to reserve space + xlim <- cs$get_xlim() + cs$set_xlim(c(xlim[1]-xlim[2]*0.04,xlim[2]+xlim[2]*0.04)) # remove x-axis grid line cs$Env$actions[[1]] <- NULL @@ -508,7 +511,7 @@ function(x, #cs$Env$theme$minor.tick #cs$Env$theme$main.color #cs$Env$theme$sub.col - cs$Env$theme$fill <- theme$fill + cs$Env$theme$fill <- theme$area cs$Env$color.vol <- color.vol cs$Env$multi.col <- multi.col @@ -546,8 +549,7 @@ function(x, cs$Env$actions[[1]] <- exp # add border - exp.border <- expression(rect(xlim[1], get_ylim()[[2]][1], xlim[2], get_ylim()[[2]][2],col=theme$fill), - segments(xlim[1], y_grid_lines(get_ylim()[[2]]), xlim[2], + exp.border <- expression(segments(xlim[1], y_grid_lines(get_ylim()[[2]]), xlim[2], y_grid_lines(get_ylim()[[2]]), col = theme$grid, lwd = grid.ticks.lwd, lty = grid.ticks.lty), text(xlim[2] + xstep * 2/3, y_grid_lines(get_ylim()[[2]]), noquote(format(y_grid_lines(get_ylim()[[2]]), justify = "right")), @@ -559,6 +561,11 @@ function(x, exp.border <- structure(exp.border, env = cs$Env) cs$Env$actions[[4]] <- exp.border + # add inbox color + exp.area <- expression(rect(xlim[1], get_ylim()[[2]][1], xlim[2], get_ylim()[[2]][2],col=theme$fill)) + cs$set_frame(-2) + cs$add(exp.area, env=cs$Env, expr=TRUE) + # add legend text.exp <- expression( Closes <- Cl(xdata), From b62b868eea3b7a94ef14ff1e697a51c8d3dc525b Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Thu, 21 Jul 2016 16:27:10 +0800 Subject: [PATCH 06/12] Add TA functionality to chartSeries Add TA functionality to handle "addVo()" argument. If Volume is not included in x, "addVo()" will be removed from TA. Allow TA=NULL to work. --- R/chartSeries.R | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/R/chartSeries.R b/R/chartSeries.R index cb75e439..6ab6ecd3 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -577,6 +577,20 @@ function(x, y.intersp=0.95)) cs$set_frame(2) cs$add(text.exp, env=cs$Env, expr=TRUE) + + # handle TA="addVo()" as we would interactively FIXME: allow TA=NULL to work + if(!show.vol) TA <- TA[-grep("addVo()", TA)] + if(!is.null(TA) && length(TA) > 0) { + TA <- parse(text=TA, srcfile=NULL) + for(ta in seq_along(TA)) { + if(length(TA[ta][[1]][-1]) > 0) { + cs <- eval(TA[ta]) + } else { + cs <- eval(TA[ta]) + } + } + } + assign(".xts_chob", cs, xts:::.plotxtsEnv) if(plot) # draw the chart cs } #}}} From adf2ea1c571b12be4a3e6d2410528831dcac50c3 Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Wed, 3 Aug 2016 15:00:44 +0800 Subject: [PATCH 07/12] Translate xsubset into length of the series To coordinate with addPoints(), when x is specified by numeric vector and without subsetting the intersection of x and the index of series will be FALSE because xsubset is always "". It should be the index of the raw series, namely, 1:NROW(x), which is also the original setting in chartSeries. --- R/chartSeries.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/chartSeries.R b/R/chartSeries.R index 6ab6ecd3..de3dc423 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -402,7 +402,7 @@ function(x, sub.index <- index(do.call(subsetvec[1],list(x,subset.n))) xsubset <- which(index(x) %in% sub.index) } else xsubset <- which(index(x) %in% index(x[subset])) - } else xsubset <- "" + } else xsubset <- 1:NROW(x) xdata <- x x <- x[xsubset] From 7affc11edd4185f619cef7e5e652f41008c2e418 Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Wed, 3 Aug 2016 15:20:04 +0800 Subject: [PATCH 08/12] Fix subsetting bug of minor ticks on x-axis When reChart is called to draw subset series, minor ticks on xycoords$x do not change with the subset sereis. Fix xycoords$x to be xycoords$x[1:NROW(xsubset)] in the x-axis expression. --- R/chartSeries.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/chartSeries.R b/R/chartSeries.R index de3dc423..9c03344e 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -540,7 +540,7 @@ function(x, # change minor ticks to be downward exp <- expression(if (NROW(xdata[xsubset]) < 400) { - axis(1, at = xycoords$x, labels = FALSE, col = theme$grid2, + axis(1, at = xycoords$x[1:NROW(xsubset)], labels = FALSE, col = theme$grid2, col.axis = theme$grid2, tcl = -0.4) }) exp <- structure(exp, frame = 1) From 7a18877d997c269c83aa114a192163f3c0e7dd7a Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Tue, 9 Aug 2016 18:32:02 +0800 Subject: [PATCH 09/12] Fix bug in TA argument Since "Volume" is not included in xts series, show.vol will be FALSE and grep("addVo()", TA) returns 'integer(0)', TA specified in the argument will not be added to the plot object. 'match' is applied instead. --- R/chartSeries.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/R/chartSeries.R b/R/chartSeries.R index 9c03344e..e55060e7 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -579,7 +579,11 @@ function(x, cs$add(text.exp, env=cs$Env, expr=TRUE) # handle TA="addVo()" as we would interactively FIXME: allow TA=NULL to work - if(!show.vol) TA <- TA[-grep("addVo()", TA)] + TA <- unlist(strsplit(TA, TAsep)) + if(!show.vol) { + which.vo <- match("addVo()", TA) + if(!is.na(which.vo)) TA <- TA[-which.vo] + } if(!is.null(TA) && length(TA) > 0) { TA <- parse(text=TA, srcfile=NULL) for(ta in seq_along(TA)) { From 29edf4d94b40d6978b62bf3dfba3ae013b3bd555 Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Tue, 9 Aug 2016 18:42:52 +0800 Subject: [PATCH 10/12] Pass layout settings to the plot object In the original chartSeries that used S4 method, chart.layout is called to setup layout and margins. Since now chartSeries is a wrapper for chart_Series, it should be layout-free and only margins are applied. --- R/chartSeries.R | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/R/chartSeries.R b/R/chartSeries.R index e55060e7..e4572df2 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -594,6 +594,16 @@ function(x, } } } + # Pass chart.layout settings + cs$Env$chart.layout <- chart.layout + if(!inherits(layout, "chart.layout")) { + cl <- chart.layout(length(cs$Env$ylim)-1) + } else + cl <- layout + # since xts::plot.xts is applied, chartSeries should now be layout free + # layout(cl$mat, cl$width, cl$height, respect=FALSE) + cs$Env$mar <- cl$par.list[[3]]$mar + assign(".xts_chob", cs, xts:::.plotxtsEnv) if(plot) # draw the chart cs From e8eac03c14a8d189e3b99e2a5572d2565e6b4f2a Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Sat, 13 Aug 2016 15:42:32 +0800 Subject: [PATCH 11/12] Update last price when subsetting The last price displayed on chart will change if subset is specified in chartSeries. However when zoomChart is called view the subset series, the last price didn't change. The displayed price should be the price of the last day in the subset period. --- R/chartSeries.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/chartSeries.R b/R/chartSeries.R index e4572df2..fc00d6ac 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -568,10 +568,10 @@ function(x, # add legend text.exp <- expression( - Closes <- Cl(xdata), + Closes <- Cl(xdata[xsubset]), lc <- xts:::legend.coords("topleft", xlim, get_ylim()[[2]]), legend(x = lc$x, y = lc$y, - legend = paste("Last", last(Closes)), + legend = paste("Last", sprintf("%.3f", last(Closes))), text.col = theme$up.col, bty='n', y.intersp=0.95)) From fe79a2fd4a49979bede957a9716d2a6fc051d22d Mon Sep 17 00:00:00 2001 From: Eric Hung Date: Sun, 14 Aug 2016 15:27:27 +0800 Subject: [PATCH 12/12] Allow custom settings to TAs' color Users can now enter TAs' color settings by calling chartTheme(addTA = list(...)) to create custom theme parameters. BBands settings in .chart.theme is refactored to coordinate with addBBands function. --- R/chartSeries.R | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/R/chartSeries.R b/R/chartSeries.R index fc00d6ac..4771437e 100644 --- a/R/chartSeries.R +++ b/R/chartSeries.R @@ -276,7 +276,10 @@ function(x,subset = NULL, fill="#F7F7F7", Expiry='#C9C9C9', BBands.col='#666666',BBands.fill="#F7F7F7", - BBands=list(col='#666666',fill='#F7F7F7'), + BBands=list(col=list(upper='#666666', + lower='#666666', + fill='#F7F7F7', + ma='#D5D5D5')), theme.name='white.mono' ), 'black'= @@ -294,7 +297,10 @@ function(x,subset = NULL, fill="#282828", Expiry='#383838', BBands.col='red',BBands.fill="#282828", - BBands=list(col='red',fill='#282828'), + BBands=list(col=list(upper='red', + lower='red', + fill='#282828', + ma='#D5D5D5')), theme.name='black' ), 'black.mono'= @@ -310,7 +316,10 @@ function(x,subset = NULL, main.col="#999999",sub.col="#999999", fill="#777777", Expiry='#383838', - BBands=list(col='#DDDDDD',fill='#777777'), + BBands=list(col=list(upper='#DDDDDD', + lower='#DDDDDD', + fill='#777777', + ma='#D5D5D5')), BBands.col='#DDDDDD',BBands.fill="#777777", theme.name='black.mono' ), @@ -328,7 +337,10 @@ function(x,subset = NULL, fill="#F5F5F5", Expiry='#C9C9C9', BBands.col='orange',BBands.fill='#F5F5DF', - BBands=list(col='orange',fill='#F5F5DF'), + BBands=list(col=list(upper='orange', + lower='orange', + fill='#F5F5DF', + ma='#D5D5D5')), theme.name='beige' ), 'wsj'= @@ -534,9 +546,17 @@ function(x, } cs$Env$length <- NROW(x) - cs$Env$theme$bbands$col$fill <- theme$BBands.fill - cs$Env$theme$bbands$col$upper <- theme$BBands.col - cs$Env$theme$bbands$col$lower <- theme$BBands.col + cs$Env$theme$BBands$col$fill <- theme$BBands$col$fill + cs$Env$theme$BBands$col$upper <- theme$BBands$col$upper + cs$Env$theme$BBands$col$lower <- theme$BBands$col$lower + cs$Env$theme$BBands$col$ma <- theme$BBands$col$ma + + # allow custom settings to TAs color + # use chartTheme() to enter + which.TA <- grep("add", names(theme)) + names(theme)[which.TA] <- gsub("^add", "", names(theme)[which.TA]) + cs$Env$theme <- append(cs$Env$theme, theme[which.TA]) + # change minor ticks to be downward exp <- expression(if (NROW(xdata[xsubset]) < 400) {