rquantmoddynamic-chart-series

quantmod chartSeries TA inside a function: an environment issue?


Supplying an argument to TA in chartSeries inside a function only works when TA´s are in .GlobalEnv$. Taking .GlobalEnv$ out, it gets this error:

Error in addTA(cChart.env$I1, col = "red", on = 1) : 
object 'cChart.env' not found 

It seems that chartSeries is looking for TA´s only in global environment.

#lib
library(quantmod)
#function
left <- function(x, n)  if(n>0) substr(x, 1, n) else substr(x, 1-n, nchar(x))
cChart=function(chart,dt_venc,nSem,diasPos=0){
  dt_ini=dt_venc-(7*nSem)
  dt_fim=dt_ini+4
  dt_fim=dt_fim+diasPos
  dt_ini=dt_ini-120
  price <- Cl(chart)

  #it only worked with .GlobalEnv$cChart.env
  .GlobalEnv$cChart.env=list( # cChart.env=list(...) does not work
     I1 = SMA(price,10)
    ,I2 = SMA(price,20)
    ,I3 = SMA(price,50)
    ,I4 = SMA(price,100)
  )
  #it only worked with .GlobalEnv$cChart.env

  TA=list("addTA(cChart.env$I1,col='red',on=1)"
          ,"addTA(cChart.env$I2,col='blue',on=1)"
          ,"addTA(cChart.env$I3,col='#009900',on=1)"
          ,"addTA(cChart.env$I4,col='black',on=1)"
          ,"addBBands(22)")
  assign(deparse(substitute(chart)),chart)
  chartSeries(chart,type='candlesticks',theme=chartTheme('white',up.col='#009900',dn.col='darkred')
              ,subset=paste0(dt_ini,'/',dt_fim)
              ,major.ticks='weeks'
              ,TA=TA)
  print(deparse(substitute(chart)))
}
#input
getSymbols('PETR4.SA')
hj=Sys.Date()
p4=PETR4.SA[paste0('2017-01-01/',hj)]
colnames(p4)=left(colnames(p4),-9)
p4=p4[complete.cases(p4) & p4$Volume > 0,]
#routine
dt_venc=as.date('2018-01-15') 
cChart(p4,dt_venc,nSem=2,diasPos=0)

Is there an option for TA´s environment?

enter image description here


Solution

  • I've simplified your code, because it distracts from your core problem. Here are two options for solving your problem.

    #option 1: explicitly use addTA
    
    chart2 <- function(x) {
      x <- x[complete.cases(x)]
      I1 = SMA(Cl(x),10)
      TA <- list("addTA(I1,col='red',on=1)")
      chartSeries(x,type='candlesticks',theme=chartTheme('white',up.col='#009900',dn.col='darkred')
                  #,subset=paste0(dt_ini,'/',dt_fim)
                  ,major.ticks='weeks'
                  ,TA=NULL)
      addTA(I1, col='red',on=1)
      #plot(current.chob())
    }
    # this works:
    chart2(PETR4.SA["2017"])
    

    This alternative approach might be new, so I've added an example of theme and pars which you could modify for your own purposes as a little bit of an extra starter.

    # option 2: use chart_Series instead and you won't have the problem (also looks better?)
    
    # Completely optional:
    chart_theme1 <- function() {
      myTheme<-chart_theme()
      myTheme$col$up.col<-'darkgreen'
      myTheme$col$dn.col<-'darkred'
      myTheme$col$dn.border <- 'black'
      myTheme$col$up.border <- 'black'
      myTheme$rylab <- FALSE
      myTheme$col$grid <- "lightgrey"
      myTheme
    }
    
    # Completely optional:
    chart_pars1 <- function() {
      myPars <- chart_pars()
      myPars$cex <- 1
      myPars$mar <- c(3, 2.5, 0, 0) # default is c(3, 1, 0, 1)  # bottom, left, top, right c(3, 2, 0, .2)
      myPars
    }
    
    
    
    
    
    chart3 <- function(x) {
      x <- x[complete.cases(x)]
      I1 = SMA(Cl(x),10)
      TA <- list("add_TA(I1,col='purple',on=1)")
      chart_Series(x, TA = TA, theme = chart_theme1(), pars = chart_pars1())
    
      #add_TA(I1, col='red',on=1)
    
    }
    # this works, no error
    chart3(PETR4.SA["2017"])