Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

quantstrat in R: Setting a date based exit signal

Much of quantstrat and the accompanying examples seem to be set around entering and exiting trades by crossing some kind of technical indicator.

However, let's say you have an arbitrary indicator which you're using to trigger an entry to the trade, but then you want to just unwind the trade on the next day's open or close. How would you best implement this example?

Let's take the following example:

  • Two instruments: XYZ and ABC
  • Entry Signal: Can be anything - we just want to enter the trade any time our "signal" evaluates to true. For this example, let's say any time the ratio of XYZ/ABC changes by more than 1% in either direction from Open to Close on T+0
  • Exit Signal: A market event such as an Open or Close. Let's say, in this example, we want to unwind the trade we set above at the next day's open.

For instance, writing something like this using blotter would be relatively easy:

Assume xts object called ratio with columns for:

  1. ABC OHLC,
  2. XYZ OHLC,
  3. the ratio of ABC/XYZ expressed as an OHLC
  4. currency OHLC "CCY" (this is a cross currency pair)
  5. our indicator (the OpCl(ABC/XYZ)),
  6. "signal up?" which will evaluate to 1 if the indicator is > 1%, else 0 if not
  7. "signal dn?" which will evaluate to 1 if the indicator is < -1%, else 0 if not

Our code would then be:

for( i in 1:nrow(ratio) ) {

  ## Define the dates:

  CurrentDate <- index(ratio[i,])

  NextDate <- index(ratio[i+1,])

  ## Define the prices:

  XYZClosePrice <- as.numeric(ratio$XYZ.Close[i,])
  ABCClosePrice <- as.numeric(ratio$ABC.Close[i,])

  XYZOpenPrice <- as.numeric(ratio$XYZ.Open[i+1,])
  ABCOpenPrice <- as.numeric(ratio$ABC.Open[i+1,])

  CCYClosePrice <- as.numeric(ratio$CCY.Close[i,])
  CCYOpenPrice <- as.numeric(ratio$CCY.Open[i+1,])


  ## Define the spread:      

  SpreadOp <- ABCOpenPrice/XYZOpenPrice
  SpreadCl <- ABCClosePrice/XYZClosePrice

  ## Define the hedge ratio (let's say XYZ has a multiplier of 25 and ABC of 50)

  HedgeOp <- 25 * ((CCYOpenPrice/50)/SpreadOp)
  HedgeCl <- 25 * ((CCYClosePrice/50)/SpreadCl)

  # We want to trade 20 lots of XYZ each time with the corresponding hedge amount of   ABC
  Posn <- round(20 * HedgeCl,0)

  ## Add the trading rules (if move > 1% / else move <-1%):     

  # >= +1 % move

  if(ratio[i,'signal up?']==1){


    ## enter position on today's close

    addTxn(strat.name, Symbol='XYZ', TxnDate=CurrentDate,
           TxnPrice=XYZClosePrice, TxnQty = 20 , TxnFees=0)
    addTxn(strat.name, Symbol='ABC', TxnDate=CurrentDate,
           TxnPrice=ABCClosePrice, TxnQty = - Posn , TxnFees=0)

    ## exit position tomorrow's open

    addTxn(strat.name, Symbol='XYZ', TxnDate=NextDate,
           TxnPrice=XYZOpenPrice, TxnQty = - 20, TxnFeABC=0)
    addTxn(strat.name, Symbol='ABC', TxnDate=NextDate,
           TxnPrice=ABCOpenPrice, TxnQty = Posn , TxnFeABC=0)}

  else {

    # <= -1% move
    if(ratio[i,'signal dn?']==1){

      ## enter position on today's close

      addTxn(strat.name, Symbol='XYZ', TxnDate=CurrentDate,
             TxnPrice=XYZClosePrice, TxnQty = -20 , TxnFees=0)
      addTxn(strat.name, Symbol='ABC', TxnDate=CurrentDate,
             TxnPrice=ABCClosePrice, TxnQty =  Posn , TxnFees=0)

      # exit position on tomorrow's open

      addTxn(strat.name, Symbol='XYZ', TxnDate=NextDate,
             TxnPrice=XYZOpenPrice, TxnQty =  20, TxnFees=0)
      addTxn(strat.name, Symbol='ABC', TxnDate=NextDate,
             TxnPrice=ABCOpenPrice, TxnQty =  - Posn , TxnFees=0)}

  }

This works just fine.

But let's say we want to implement this in quantstrat -- it gets a bit trickier. Assuming all portfolios, accounts, indicators and signals etc are set up correctly, i would then add these trading rules to enter the trade:

> strat <- add.rule(strat, name='ruleSignal',
+                   arguments = list(sigcol="Cl.gt.1pct", sigval=TRUE, orderqty=20,
+                                    ordertype='market', orderside='long', pricemethod='market'),
+                   type='enter', path.dep=TRUE,symbol='XYZ')


> strat <- add.rule(strat, name='ruleSignal',
+                   arguments = list(sigcol="Cl.lt.1pct", sigval=TRUE, orderqty=Posn,
+                                    ordertype='market', orderside='short', pricemethod='market'),
+                   type='enter', path.dep=TRUE,symbol='ABC')

My question is: How do I enter the next two ruleSignal 's to simply unwind the pair on the next day's open?

I know it probably has something to do with the timestamp argument in ruleSignal but I can't figure out how I'd implement it.

There may be a very simple solution here, but I've caught myself in a bit of a loop trying to solve this one.

As ever, any help very much appreciated.

like image 405
n.e.w Avatar asked May 04 '12 01:05

n.e.w


1 Answers

quantstrat, as described in the manual, is a signals-based framework. It is not designed for filters based trades really.

You could do what you want by using the delay argument to your exit rule. Set the delay to be one day, and the prefer argument to prefer a different price column.

I'm not going to write it for you, but that is enough information to solve your problem.

like image 178
Brian G. Peterson Avatar answered Sep 28 '22 07:09

Brian G. Peterson