2

I am trying to create a signal state when my spread calculation is greater than or less than upper/lower Bollinger Bands, however my calculations:

pair <- c("qqq","iwm")
start <-  "2014-08-08"
finish <- "2015-08-13"
stckY <- suppressWarnings(getSymbols(pair[1], from = start, to = finish, auto.assign = FALSE))
stckX <- suppressWarnings(getSymbols(pair[2], from = start, to = finish, auto.assign = FALSE))

adY <- Ad(stckY)
adX <- Ad(stckX)

logY <- log(adY)
logX <- log(adX)

spread <- cbind(logY, logX)
spread <- spread[complete.cases(spread),] #remove NAs
spread$dailyDiff <- spread[,1] - spread[,2]

ema <- EMA(spread[,1] - spread[,2], n=20)
spread$UpBand <- (runSD(ema, n=20) * 2) + ema
spread$LwBand <- ema - (runSD(ema, n=20) * 2)

chartSeries(spread$dailyDiff, up.col = "white", 
            theme = chartTheme("black"), line.type = "l")
addEMA(n = 20, col = "orange")
addBBands(n = 20, sd = 2, maType = "EMA")

aren't matching the band values displayed on the chartSeries display and I cannot figure out why? The help file states that not using SMA might cause "inconsistencies", so maybe this is the source of the problem? The chartSeries is also using an EMA.

Perhaps there is a better way to go about this? I'm not sure how to reference the upper/lower bands using BBands() alone...

trock2000
  • 302
  • 4
  • 13
  • 1
    It's not clear to me what you're comparing and how they're different. A [reproducible example](http://stackoverflow.com/q/5963269/271616) would be a lot better than a vague description. – Joshua Ulrich Aug 15 '15 at 00:57
  • The code in your comments is very hard to read. Please edit it into your question (with proper code formatting) and then delete your comments. – Joshua Ulrich Aug 15 '15 at 13:36
  • @JoshuaUlrich - sorry about that - still learning this site - I've updated the original post – trock2000 Aug 15 '15 at 16:51

1 Answers1

1

There are 2 problems:

  1. You're taking the standard deviation of the moving average when you should be taking the standard deviation of the original series.
  2. The BBands function uses sample = FALSE in the runSD call.

This replicates the output of the BBands function in your chart:

ema <- EMA(spread$dailyDiff, n=20)
spread$UpBand <- runSD(spread$dailyDiff, n=20, sample=FALSE) * 2 + ema
spread$LwBand <- ema - runSD(spread$dailyDiff, n=20, sample=FALSE) * 2
tail(spread)
#            QQQ.Adjusted IWM.Adjusted   dailyDiff      UpBand     LwBand
# 2015-08-06     4.704563     4.793060 -0.08849663 -0.06442705 -0.1381200
# 2015-08-07     4.703295     4.786575 -0.08328008 -0.06687188 -0.1322478
# 2015-08-10     4.714652     4.798267 -0.08361464 -0.06938022 -0.1267023
# 2015-08-11     4.701752     4.789323 -0.08757113 -0.07421110 -0.1198771
# 2015-08-12     4.705196     4.787408 -0.08221192 -0.07856667 -0.1126964
# 2015-08-13     4.703566     4.784320 -0.08075361 -0.08283161 -0.1055975
tail(BBands(spread$dailyDiff, n=20, maType="EMA"))
#                    dn        mavg          up      pctB
# 2015-08-06 -0.1381200 -0.10127351 -0.06442705 0.6733800
# 2015-08-07 -0.1322478 -0.09955985 -0.06687188 0.7490178
# 2015-08-10 -0.1267023 -0.09804126 -0.06938022 0.7516764
# 2015-08-11 -0.1198771 -0.09704411 -0.07421110 0.7074403
# 2015-08-12 -0.1126964 -0.09563152 -0.07856667 0.8931942
# 2015-08-13 -0.1055975 -0.09421457 -0.08283161 1.0912769
Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418