3

I am attempting to apply a very basic strategy in quantstrat using the ADX indicator. The strategy looks for situations with a low but upwardly trending ADX, specifically:

Rule 1: ADX <20;

Rule 2: ADX today greater than ADX 5 periods ago;

Rule 3: Exit trade when ADX >35

I have tried to follow Guy Yollen's excellent guide, but am still stuck in the "Trading Logic" component:

library(blotter)
currency("USD")
stock("SPY",currency="USD",multiplier=1)
get("USD",envir=FinancialInstrument:::.instrument)
get("SPY",envir=FinancialInstrument:::.instrument)

Sys.setenv(TZ="UTC")
startDate <- '1998-01-01'
endDate <- '2014-07-31'

getSymbols('SPY',from=startDate,to=endDate,index.class=c("POSIXt","POSIXct"),
           adjust=T)

SPY = to.monthly(SPY,indexAt='endof',drop.time=FALSE)


SPY$ADX <- ADX(HLC(SPY))

#rm.strat(a.strategy)
a.strategy <- "TestADX"
initPortf(a.strategy,'SPY',initDate='1997-12-31')
initAcct(a.strategy,portfolios=a.strategy,initDate='1997-12-31',initEq=1e6)

first(SPY)


myTheme <- chart_theme()
myTheme$col$dn.col <- 'lightblue'
myTheme$col$dn.border <- 'lightgray'
myTheme$col$up.border <- 'lightgray'


###Not sure why this one-liner does not work but not critical
chartSeries(x=SPY,theme=myTheme,name="SPY",TA="addADX()")  

#####################Trading logic############################################

for( i in 1:nrow(SPY))
{
  #update values for this date
  CurrentDate <- time(SPY)[i]
  equity = getEndEq(a.strategy,CurrentDate)
  ClosePrice <- as.numeric(Cl(SPY[i,]))
  Posn <- getPosQty(a.strategy,Symbol='SPY',Date=CurrentDate)
  UnitSize = as.numeric(trunc(equity/ClosePrice))
  adx <- as.numeric(SPY[i,'ADX'])
  diffadx <- as.numeric(diff(SPY[i,'ADX',lag=5]))#####INSERT

  #change mkt position if necessary

  if( !is.na(adx) )#if the moving avg has begun
  {
    if(Posn == 0) {#No position test to go long
        #if((adx < 20) && (diff(adx,lag=5) > 0.2)){
        if((adx < 20) && (diffadx > 0.2)){    #####INSERT
        #enter long position
        addTxn(a.strategy,Symbol='SPY',TxnDate=CurrentDate,
               TxnPrice=ClosePrice,TxnQty=UnitSize,TxnFees=0)}
    }else {#Have a position so check exit
      if ( adx > 35){
        #exit position
        addTxn(a.strategy,Symbol='SPY',TxnDate=CurrentDate,
               TxnPrice = ClosePrice,TxnQty = -Posn,TxnFees=0)}
    }
  }

  #Calculate P&L and resulting Equity with blotter
  updatePortf(a.strategy,Dates=CurrentDate)
  updateAcct(a.strategy,Dates=CurrentDate)
  updateEndEq(a.strategy,Dates=CurrentDate)
}#end Dates loop

##End of trading logic piece####

At this stage R returns error: Error in if ((adx < 20) && (diffadx > 0.2)) { : missing value where TRUE/FALSE needed

chart.Posn(a.strategy,Symbol='SPY',Dates='1998::',theme=myTheme)     

plot(add_ADX(n=14,col=4,on=1))  
RichS
  • 659
  • 12
  • 19
  • 1
    I haven't looked closely, but the error is telling you that either `adx` or `diffadx` is missing (e.g. `NA`) on some row. That could be because `diff` adds `NA`s at the beginning by default. Perhaps you could replace those with `0` first? Also, I think there's an error where you assign `diffadx`. I assume `lag=5` is an arg to `diff`, not `[.xts`, so you should move it outside the brackets. – GSee Aug 17 '14 at 13:20
  • Thanks very much for the explanation re. the NAs. And yes lag shouldn't have been in the square bracket!! Will try to tinker with the NAs that diff generates in producing the shortened series and look again. Thanks very much for the kind help!! – RichS Aug 17 '14 at 14:24
  • 1
    As for the `chartSeries` call, you cannot mix `chart_theme()` with `chartSeries()` or `chartTheme()` with `chart_Series()`. Try this: `myTheme <- chartTheme(); myTheme$dn.col <- 'lightblue'; myTheme$dn.border <- 'lightgray'; myTheme$up.border <- 'lightgray'; chartSeries(SPY, theme=myTheme, name="SPY", TA="addADX()")` – GSee Aug 17 '14 at 14:40
  • Ah! That explains a lot. Thanks again!!! Was aware that the one with _ was an experimental series, but not that they couldn't be mixed. – RichS Aug 17 '14 at 14:48
  • 1
    Before the for loop, you should create a `diffadx` column. Otherwise, the for loop needs to start at 5 (i.e. `for (i in 5:nrow(SPY))` so that `diff(, lag=5)` has enough data, and the code in the loop needs to be something like `diffadx <- last(as.numeric(diff(tail(SPY[1:i, 'ADX'], 6), lag=5)))`. But you should really do as little as possible inside the loop. – GSee Aug 17 '14 at 14:58
  • Thanks again for the input. The following worked well: – RichS Aug 18 '14 at 09:31
  • SPY$DeltaADX <- diff(SPY$ADX,lag=5) diffadx <- as.numeric(SPY[i,'DeltaADX']) #change mkt position if necessary if( !is.na(adx) )#if the ADX has begun { if(Posn == 0) {#No position test to go long if((adx < 20) && (diffadx > 0.2)){ ##etcetc – RichS Aug 18 '14 at 09:34

0 Answers0