2

I cannot grasp how to properly use sigPeak() in quantstrat.

A (not working) example follows.

I add an indicator to mktdata:

add.indicator(strategy = name,
              name = 'WinDoPar',
              arguments = list(x = quote(OHLC(mktdata)),
                               n = 300,
                               w = 'run',
                               fun = RSI_dens),
              label = 'pti',
              store = TRUE)

It should produce a column named X1.pti because of the label, and actually it does. Then I would like to use sigPeak() to add a signal:

add.signal(strategy = name,
           name = 'sigPeak',
           arguments = list(data = mktdata,
                            column = 'pti',
                            direction = 'peak'),
           label = 'pti.buy',
           store = TRUE)

There's an additional argument required by sigPeak(), which is label: however, I didn't get how to use it. Thus, when I add a rule like this and apply the strategy, it fails:

add.rule(strategy = name,
         name = 'ruleSignal',
         arguments = list(sigcol = 'pti.buy',
                          sigval = TRUE,
                          orderqty = 1,
                          ordertype = 'market',
                          orderside = 'long',
                          replace = TRUE,
                          osFUN = osTotSize,
                          acct.name = name,
                          TxnFees = TxnFees),
         label = 'pti.buy.enter',
         type = 'enter',
         store = TRUE)

Error thrown:

Error in applyRules(portfolio = portfolio, symbol = symbol, strategy = strategy,  : 
  mktdata does not contain 'sigcol': pti.buy

A closer inspection of mktdata revelas there is a column labelled like this: pti.buy.peak.sig.pti.buy, which seems quite odd.

So how am I supposed to use sigPeak() to generate a signal to buy after indicator's peaks?

FXQuantTrader
  • 6,821
  • 3
  • 36
  • 67
Lisa Ann
  • 3,345
  • 6
  • 31
  • 42

1 Answers1

1

Looking at the source, sigPeak generates a signal when you effectively have a 'triangle' pattern in the underlying time series, and fires a signal when the "triangle" is complete. It makes sense to use this signal in combination with others to generate a meaningful trade signal (maybe smooth the sigPeak time series with EMA, etc to make it more robust, and act on it breaching some threshold value between 0 and 1, etc)

Your error is telling you 'pti.buy' is not a column name in mktdata. So your add.rule needs to change the sigcol = "pti.buy" argument to whatever the name is of the column containing your entry signal. Sounds like it should be sigcol = "pti.buy.peak.sig.pti.buy" and then things should work.

On closer inspection of sigPeak, it looks like the name of the column output from sigPeak takes the form [label].peak.sig.[label] when direction = "peak" or [label].valley.sig.[label] when direction = "valley" (using direction = "bottom" current generates an error in sigPeak, due to an error in the switch code inside sigPeak). Not exactly intuitive.

An easy way to use sigPeak is to modify the function and pass that in as the function for add.signal. I do this with sigPeak2 below.

Here is a reproducible example using sigPeak that might help:

library(quantstrat)
strategy.st <- "RSI"
initEq=100000
port.st<-'RSI'

rm.strat(strategy.st)
stratRSI <- strategy(strategy.st, store = TRUE)

add.indicator(strategy = strategy.st, name = "RSI", arguments = list(price = quote(getPrice(mktdata))), label="pti")


sigPeak2 <- function (label, data, column, direction = c("peak", "bottom"))  {
    if (!is.numeric(column)) {
        colNum <- match.names(column, colnames(data))
    }
    else colNum <- column
    direction = direction[1]
    switch(direction, peak = {
        ret_sig <- Lag(data[, colNum], 2) < Lag(data[, colNum],
                                                1) & Lag(data[, colNum], 1) > data[, colNum]
    }, bottom = , valley = {
        ret_sig <- Lag(data[, colNum], 2) > Lag(data[, colNum],
                                                1) & Lag(data[, colNum], 1) < data[, colNum]
    })
    if (!missing(label))
        colnames(ret_sig) <- label
    return(ret_sig)
}


add.signal(strategy = strategy.st,
           name = 'sigPeak',
           arguments = list(data = quote(mktdata),
                            column = 'pti',
                            direction = 'peak'),
           label = 'drop')

add.signal(strategy = strategy.st,
           name = 'sigPeak2',
           arguments = list(data = quote(mktdata),
                            column = 'pti',
                            direction = 'bottom'),
           label = 'jump')

add.signal(strategy = strategy.st, name="sigThreshold",
           arguments = list(threshold=70, column="pti",relationship="gt", cross= TRUE),
           label="RSI.gt.70")

add.signal(strategy = strategy.st, name="sigThreshold",
           arguments = list(threshold=60, column="pti",relationship="lt", cross= TRUE),
           label="RSI.lt.60")

add.signal(strategy = strategy.st, name="sigFormula",arguments = list(formula = "RSI.gt.70 == 1 & jump == 1"),label="enterLong")

add.signal(strategy = strategy.st, name="sigFormula",arguments = list(formula = "RSI.lt.60 == 1 & drop.peak.sig.drop == 1"),label="exitLong")


add.rule(strategy = strategy.st, name='ruleSignal',
         arguments = list(sigcol="enterLong",
                          sigval=TRUE,
                          orderqty= 100,
                          TxnFees=0,
                          ordertype='market',
                          orderside='long',
                          pricemethod='market',
                          replace=FALSE),
         type='enter', path.dep=TRUE)

add.rule(strategy = strategy.st, name='ruleSignal',
         arguments = list(sigcol="exitLong",
                          sigval=TRUE,
                          orderqty='all',
                          TxnFees=0,
                          ordertype='market',
                          orderside='long',
                          pricemethod='market',
                          replace=FALSE),
         type='exit', path.dep=TRUE)



currency("USD")
symbols = c("SPY")
stock.str = symbols

startDate <- "2013-01-01"


getSymbols(stock.str,from=startDate, to= Sys.Date())


for(symbol in symbols){
    stock(symbol, currency="USD",multiplier=1)
}


initPortf(port.st, symbols=symbols)
initAcct(port.st, portfolios=port.st, initEq=initEq)
initOrders(portfolio=port.st)


for(symbol in symbols){ addPosLimit(port.st, symbol, timestamp = startDate, maxpos = 1000) }

applyStrategy(strategy=strategy.st, portfolios=port.st)

updatePortf(strategy.st)
updateAcct(strategy.st)
updateEndEq(strategy.st)


chart.Posn(strategy.st, Symbol = 'SPY', Dates = '2000::')
FXQuantTrader
  • 6,821
  • 3
  • 36
  • 67