函数内的 quantmod chartSeries TA:环境问题?

quantmod chartSeries TA inside a function: an environment issue?

在函数内部为 chartSeries 中的 TA 提供参数仅在 TA 位于 .GlobalEnv$ 中时有效。取出.GlobalEnv$,得到这个错误:

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

似乎 chartSeries 只在全局环境中寻找 TA

#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)

TA的环境有选项吗?

我已经简化了您的代码,因为它会分散您对核心问题的注意力。这里有两个选项可以解决您的问题。

#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"])

这种替代方法可能是新的,因此我添加了一个 themepars 的示例,您可以根据自己的目的对其进行修改,作为一个额外的入门。

# 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"])