[R-SIG-Finance] Quantstrat code works for long position but not short position

Joshua Ulrich josh.m.ulrich at gmail.com
Tue Dec 15 13:39:06 CET 2015


On Tue, Dec 15, 2015 at 2:51 AM, Damon Verial <verial.damon at gmail.com> wrote:
> So I have this code that works fine for long positions. However, when I
> reversed the code to make a short version, it breaks, giving me an error of:
>
> Error in osFUN(strategy = strategy, data = mktdata, timestamp = timestamp,
> :
>   ATR corresponding to atrX is invalid at this point in time.
>                Add a logical operator to account for this.
>
The error could be more informative ('at this point in time' should be
'for this timestamp', and it would be nice if the specific timestamp
were reported in the error), but it does give you hints about what's
wrong.  Look at your mktdata:

           atr.atrX gap.gap   TP.gap shortEntry
2015-01-02       NA       0       NA         NA
2015-01-05       NA       0       NA          0
2015-01-06       NA       0       NA          0
2015-01-07       NA       0       NA          0
2015-01-08       NA       1 199.8034          1
2015-01-09       NA       0 199.8034          0
2015-01-12       NA       0 199.8034          0
2015-01-13       NA       0 199.8034          0
2015-01-14       NA       0 199.8034          0
2015-01-15       NA       0 199.8034          0
2015-01-16       NA       0 199.8034          0
2015-01-20 3.465414       0 199.8034          0

Your first sell signal is on 2015-01-08, but atr.atrX is NA at that
point.  So the order sizing function doesn't know how to size that
sell order.

I think the "IKTrading-way" to fix this is to change your signals to:

#signals
add.signal(strategy.st, name="sigThreshold",
           arguments=list(column="gap.gap", threshold=.5,
                          relationship="gt", cross=TRUE),
           label="shortEntryRaw")

add.signal(strategy.st, name="sigAND",
           arguments=list(columns=c("atr.atrX","shortEntryRaw")),
           label="shortEntry")

Which will make 'shortEntry' NA if 'shortEntryRaw' is true before
atr.atrX is non-NA.

It might be more user-friendly if the osDollarATR function returned an
order size of zero, with a warning, if the ATR column it references is
NA.

> Why does this occur with the short position but not the long position? The
> code follows, for reference:
>
Thank you for the reproducible example.

> library("quantstrat")
> require(IKTrading)
>
> initDate<-startDate<-'2015-01-01'
> endDate<-'2015-12-09'
>
> rm(list = ls(.blotter), envir = .blotter)
> currency("USD")
> Sys.setenv(TZ = "UTC")
> symbols<-"SPY"
>
> strategy.st <- portfolio.st <- account.st <- "Gaps"
> getSymbols(symbols, src="yahoo",
> index.class=c("POSIXt","POSIXct"),from=startDate,
> to=endDate, adjust=T)
> stock(symbols,currency="USD",multiplier=1)
> tradeSize <- 100000
> initEq <- tradeSize*length(symbols)
>
> strategy.st <- portfolio.st <- account.st <- "Gaps"
> rm.strat(strategy.st)
> initPortf(portfolio.st, symbols=symbols, initDate=initDate, currency='USD')
> initAcct(account.st, portfolios=portfolio.st, initDate=initDate,
> currency='USD',initEq=initEq)
> initOrders(portfolio.st, initDate=initDate)
> strategy(strategy.st, store=TRUE)
>
You do not need to specify initDate in the calls to initPortf,
initAcct, and initOrders.  The defaults (1950-01-01, and 1997-12-31
for initOrders until recently) should be sufficient.  Specifying them
has the potential to cause errors that are hard for users to recognize
and fix, so you should only specify them if you know what you're doing
(or need them to be earlier than Jan-1950).

>
> period=10
> pctATR=.1
>
> ####################
> ## UP GAPS ##
> ####################
>
> #necessary functions
>
> gap <- function(x,k) {
>  low <- Lo(x)
>  high<- Hi(x)
>  yesHigh <- lag.xts(high,k=1)
>  gapDay <- low > yesHigh
>  gapDay[1] <- 0
>  gaps <- x[gapDay==1,]
>  gaps$takeProfit <- yesHigh[gapDay==1,]
>  gaps<-cbind(gapDay,gaps$takeProfit)
>  gaps$takeProfit<-na.locf(gaps$takeProfit)
>  colnames(gaps) <- c("gap","TP")
>  return(gaps)
> }
>
>
> period=10
> pctATR=.1
>
>
> #indicators
>
> add.indicator(strategy.st, name="lagATR",
>               arguments=list(HLC=quote(HLC(mktdata)),
>                              n=period),
>               label="atrX")
>
> add.indicator(strategy.st, name="gap",
>               arguments=list(x=quote(HLC(mktdata))),
>               label="gap")
>
>
> test <- applyIndicators(strategy.st, mktdata=SPY)
> tail(test, 50)
>
> #signals
> add.signal(strategy.st, name="sigThreshold",
>            arguments=list(column="gap.gap", threshold=.5,
>                           relationship="gt", cross=TRUE),
>            label="shortEntry")
>
> test <- applySignals(strategy.st, test)
> tail(test,50)
>
> #Add rules
> #rules
> add.rule(strategy.st, name="ruleSignal",
>          arguments=list(sigcol="shortEntry",
>                         sigval=TRUE,
>                         ordertype="market",
>                         orderside="short",
>                         replace=FALSE,
>                         osFUN=osDollarATR,
>                         tradeSize=tradeSize,
>                         prefer="Open",
>                         pctATR=pctATR,
>                         atrMod="X",
>                         orderset="orders"),
>          type="enter", path.dep=TRUE,
>          label="gapEntry")
>
> add.rule(strategy.st, name="ruleSignal",
>          arguments=list(sigcol="shortEntry",
>                         sigval=TRUE,
>                         ordertype="limit",
>                         orderside="short",
>                         replace=FALSE,
>                         orderqty='all',
>                         order.price=quote(mktdata$TP.gap[timestamp]),
>                         orderset="orders"),
>          type="chain",
>          parent="gapEntry",
>          label="takeProfitShort",
>          path.dep=TRUE)
>
>
> #apply strategy
> t1 <- Sys.time()
> out <- applyStrategy(strategy=strategy.st,portfolios=portfolio.st)
>
> Damon Verial
> Office: (206) 395-3688
> Skype: DamonVerial
> LinkedIn: https://www.linkedin.com/profile/view?id=175736313
> A Seasonal Healthcare Portfolio
> <http://seekingalpha.com/article/3693506-a-seasonal-healthcare-portfolio-using-vht>
> I purposely keep my emails to 5 sentences or fewer - which is a miracle for
> a writer.
> I do this to show that I respect both your time and mine.
>
>         [[alternative HTML version deleted]]
>
> _______________________________________________
> R-SIG-Finance at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.
> -- Also note that this is not the r-help list where general R questions should go.



-- 
Joshua Ulrich  |  about.me/joshuaulrich
FOSS Trading  |  www.fosstrading.com



More information about the R-SIG-Finance mailing list