1

I'm having trouble writing a custom indicator function for use with quanstrat::add.indicator

Error:

Error in inherits(x, "xts") : object 'price' not found 

My code:

library(quantstrat)
symbols<-getSymbols("USD/EUR",src="oanda")
strat<-acct<-portfolio<-"tempTest"
initEq<-1000

initDate <- '2009-12-31'
currency("USD")
exchange_rate(symbols, currency="USD")
rm.strat(strat) # remove portfolio, account, orderbook if re-run
initPortf(name=portfolio, symbols, initDate=Sys.Date())
initAcct(name=acct, portfolios=portfolio,initDate=Sys.Date(), initEq=initEq)
initOrders(portfolio=portfolio, initDate=Sys.Date())
strategy(strat, store=TRUE)

colnames(USDEUR)<-"Close"
#################################################################################################

RSI.lagged<-function(lag=1,n=2,...){
  RSI <- RSI(price)
  RSI <- lag(RSI, lag)
  out <- RSI$rsi
  colnames(out) <- "rsi"
  return(out)
}

########RSI indicator
####THIS IS LAGGED TO PREVENT FOREKNOWLEDGE
add.indicator(strat, name="RSI.lagged", arguments=list(price = quote(Cl(mktdata)), n=2), label="rsiIndLagged")
test <- applyIndicators(strat, mktdata=USDEUR)

After adding the parameter price to the RSI.lagged function eg RSI.lagged<-function(lag=1,n=2,price,...) I get the error:

Error in `colnames<-`(`*tmp*`, value = "rsi") : attempt to set 'colnames' on an object with less than two dimensions 
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
Rilcon42
  • 9,584
  • 18
  • 83
  • 167
  • 1
    Where is the `add.indicator` function? The only function you show code for is `RSI.lagged` (and if you want it to use `price` inside it then you should pass in an argument named `price`), but you don't show any code that calls it. – Gregor Thomas Jun 26 '16 at 21:28
  • My apologies, `library(quantstrat)` is the required library. I have edited my code to include this. – Rilcon42 Jun 26 '16 at 22:53
  • I'm still confused---I believe you responded to the first 5 words of my comment, but ignored the other 40 words. Or am I missing something else? – Gregor Thomas Jun 27 '16 at 15:50
  • I was under the impression that the `...` meant that all arguments (like price), which are supplied in `add.indicator` `arguments` parameter would be magically passed to the function RSI.lagged. Am I misunderstanding the `...` meaning somehow? – Rilcon42 Jun 27 '16 at 16:24
  • You're not using the `...` argument of `add.indicator` at all. It has both an `arguments` parameter (which you are using) and a `...` parameter which you aren't using... though the documentation doesn't make the difference between the two very clear. – Gregor Thomas Jun 27 '16 at 17:23
  • However, you are misunderstanding `...` in `RSI.lagged`. The only reason a function `foo` should have `...` in its definition is if `foo` will do nothing to the `...` arguments except pass them to another function - whatever they may be. Your `RSI.lagged` function is specifically using an argument named `price`, so `price` should be a formal, named argument of `RSI.lagged`. – Gregor Thomas Jun 27 '16 at 17:25
  • To be clear, I think it will work if you replace `...` with `price` in your definition of `RSI.lagged`. Haven't tested though... – Gregor Thomas Jun 27 '16 at 18:17
  • Thanks for the explanation- I attempted to pass `price` with no luck. (See error above) – Rilcon42 Jun 27 '16 at 19:51
  • Well, what's the point of your `colnames(out) <- "rsi"` line? Vectors don't have column names, so either delete that line or coerce `rsi` to a 1-column data frame. Maybe you want to return a vector. Or maybe you want to return `RSI["rsi"]`. – Gregor Thomas Jun 27 '16 at 19:56
  • Cool, could you post comments 5 & 6 as an answer, with some links to documentation so I can accept it and resolve the question? – Rilcon42 Jun 29 '16 at 12:43

1 Answers1

3

You were trying to access the name of a column that does not exist. Try this instead to get your indicator to work:

RSI.lagged<-function(price, lag=1,n=2,...){
  # Stick in a browser to see your problem more clearly:
  # browser()
  rsi <- RSI(price)
  rsi <- lag(rsi, lag)
  # This column name does not exist: "rsi".  The name of the column gets the default "EMA"
  # tail(rsi)
  #                 EMA
  # 2017-11-04 63.48806
  # 2017-11-05 66.43532
  # 2017-11-06 64.41188
  # 2017-11-07 66.02659
  # 2017-11-08 67.96394
  # 2017-11-09 66.08134
  colnames(rsi) <- "rsi"
  return(out)
}

(Aside, also strongly suggest you do not try using Oanda data to backtest with,as the prices aren't "real"; they are a weighted average price for each day. See: Exact time stamp on quantmod currency (FX) data)

FXQuantTrader
  • 6,821
  • 3
  • 36
  • 67