2

I'm a bit puzzled with how exactly Quantstrat places orders if they are generated within a single day by several signals. I'm trying to implement a simple pair-trading strategy (with zero being both an entry and exit threshold), so when z-score flips its sign, two signals should be generated for each symbol (SELL LONG -> SELL SHORT or COVER SHORT -> BUY LONG). The problem is QS always ignores exit order (makes it 'replaced' by a subsequent entry order). What should I do to prevent signals from being replaced or canceled? Is it possible to execute several orders on a single bar at all?

Here's my setup. Signals:

        add.signal( strategy = strategy_st, 
                    name = 'sigFormula', 
                    arguments = list(   columns = c('score', 'entry_threshold'),
                                        formula = 'score > entry_threshold',
                                        cross = TRUE
                                    ), 
                    label = 'sigEnterUpper')        

        add.signal( strategy = strategy_st, 
                    name = 'sigFormula', 
                    arguments = list(   columns = c('score', 'entry_threshold'),
                                        formula = 'score <= -entry_threshold', 
                                        cross = TRUE
                                    ), 
                    label = 'sigEnterLower')

    #exit
        add.signal( strategy = strategy_st, 
                    name = 'sigFormula', 
                    arguments = list(   columns = c('score', 'exit_threshold'),
                                        formula = 'score <= exit_threshold',
                                        cross = TRUE
                                    ), 
                    label = 'sigExitUpper')     

        add.signal( strategy = strategy_st, 
                    name = 'sigFormula', 
                    arguments = list(   columns = c('score', 'exit_threshold'),
                                        formula = 'score >= -exit_threshold', 
                                        cross = TRUE
                                    ), 
                    label = 'sigExitLower') 

Rules:

#entries    
    #longs

        add.rule(   strategy = strategy_st,     
                    name = 'ruleSignal',
                    label = 'increase_long_up',
                    arguments = list(   sigcol = 'sigEnterUpper',
                                        sigval = TRUE, 
                                        orderqty = default_order_quantity, 
                                        ordertype = 'market',
                                        orderside = 'long', 
                                        osFUN = orderSizeIncrease), 
                    type = 'enter',
                    path.dep = TRUE
                    )

        add.rule(   strategy = strategy_st,     
                    name = 'ruleSignal',
                    label = 'increase_long_low',
                    arguments = list(   sigcol = 'sigEnterLower', #sigcol = 'sigFlipper', #sigcol = 'sigStartTrading', 
                                        sigval = TRUE, 
                                        orderqty = default_order_quantity, 
                                        ordertype = 'market',
                                        orderside = 'long', 
                                        osFUN = orderSizeIncrease), 
                    type = 'enter',
                    path.dep = TRUE)

    #shorts
        add.rule(   strategy = strategy_st,     
                    name = 'ruleSignal',
                    label = 'increase_short_up',
                    arguments = list(   sigcol = 'sigEnterUpper', #sigcol = 'sigFlipper', #sigcol = 'sigStartTrading', 
                                        sigval = TRUE, 
                                        orderqty = default_order_quantity, 
                                        ordertype = 'market',
                                        orderside = 'short', 
                                        osFUN = orderSizeIncrease), 
                    type = 'enter',
                    path.dep = TRUE)

        add.rule(   strategy = strategy_st,     
                    name = 'ruleSignal',
                    label = 'increase_short_low',
                    arguments = list(   sigcol = 'sigEnterLower', #sigcol = 'sigFlipper', #sigcol = 'sigStartTrading', 
                                        sigval = TRUE, 
                                        orderqty = default_order_quantity, 
                                        ordertype = 'market',
                                        orderside = 'short', 
                                        osFUN = orderSizeIncrease), 
                    type = 'enter',
                    path.dep = TRUE)                  

#exits
    add.rule(   strategy = strategy_st,
                name = 'ruleSignal', 
                label = 'close_position_up',
                arguments = list(   sigcol = 'sigExitUpper', 
                                    sigval = TRUE, 
                                    orderqty = 'all', 
                                    ordertype = 'market', 
                                    orderside = NULL), 
                type = 'exit')

    add.rule(   strategy = strategy_st,
                name = 'ruleSignal', 
                label = 'close_position_low',
                arguments = list(   sigcol = 'sigExitLower', 
                                    sigval = TRUE, 
                                    orderqty = 'all', 
                                    ordertype = 'market', 
                                    orderside = NULL), 
                type = 'exit')

Signals generated:

    EWA.Close   score   entry_threshold exit_threshold  sigEnterUpper   sigEnterLower   sigExitUpper    sigExitLower
2006-04-04  22.95   0.00000000  0   0   NA  NA  NA  NA
2006-04-05  22.78   0.00000000  0   0   NA  NA  NA  NA
2006-04-06  22.94   0.00000000  0   0   NA  NA  NA  NA
2006-04-07  23.05   0.00000000  0   0   NA  NA  NA  NA
2006-04-08  23.32   0.00000000  0   0   NA  NA  NA  NA
2006-04-09  23.12   0.00000000  0   0   NA  NA  NA  NA
2006-04-10  23.01   0.00000000  0   0   NA  NA  NA  NA
2006-04-11  23.33   0.00000000  0   0   NA  NA  NA  NA
2006-04-12  23.23   0.00000000  0   0   NA  NA  NA  NA
2006-04-13  23.54   0.00000000  0   0   NA  NA  NA  NA
2006-04-14  23.56   0.00000000  0   0   NA  NA  NA  NA
2006-04-15  23.17   0.00000000  0   0   NA  NA  NA  NA
2006-04-16  22.76   0.00000000  0   0   NA  NA  NA  NA
2006-04-17  22.20   0.00000000  0   0   NA  NA  NA  NA
2006-04-18  22.29   0.00000000  0   0   NA  NA  NA  NA
2006-04-19  21.79   0.00000000  0   0   NA  NA  NA  NA
2006-04-20  21.47   0.00000000  0   0   NA  NA  NA  NA
2006-04-21  21.55   0.00000000  0   0   NA  NA  NA  NA
2006-04-22  21.35   0.00000000  0   0   NA  NA  NA  NA
2006-04-23  21.37   0.00000000  0   0   NA  NA  NA  NA
2006-04-24  21.15   0.00000000  0   0   NA  NA  NA  NA
2006-04-25  21.99   0.00000000  0   0   NA  NA  NA  NA
2006-04-26  22.20   1.89349767  0   0   NA   1  NA  1
2006-04-27  22.10   2.05270575  0   0   NA  NA  NA  NA
2006-04-28  22.38   2.68490142  0   0   NA  NA  NA  NA
2006-04-29  22.38   2.40434146  0   0   NA  NA  NA  NA
2006-04-30  22.60   1.87012946  0   0   NA  NA  NA  NA
2006-05-01  22.09   1.42771737  0   0   NA  NA  NA  NA
2006-05-02  21.86   1.49838977  0   0   NA  NA  NA  NA
2006-05-03  21.44   1.18071344  0   0   NA  NA  NA  NA
2006-05-04  21.04   0.59868857  0   0   NA  NA  NA  NA
2006-05-05  21.32   0.85730960  0   0   NA  NA  NA  NA
2006-05-06  21.02   0.77078417  0   0   NA  NA  NA  NA
2006-05-07  20.23   0.74856764  0   0   NA  NA  NA  NA
2006-05-08  20.41   -0.01843937 0   0    1  NA  1   NA  #I expect to cover short and buy long here
2006-05-09  21.00   -0.26363152 0   0   NA  NA  NA  NA
2006-05-10  20.78   -0.44662726 0   0   NA  NA  NA  NA
2006-05-11  20.32   -0.71957534 0   0   NA  NA  NA  NA
2006-05-12  20.29   -0.76088199 0   0   NA  NA  NA  NA

Orders generated:

 Order.Qty Order.Price Order.Type Order.Side Order.Threshold Order.Status Order.StatusTime      Prefer Order.Set Txn.Fees Rule                 Time.In.Force
2006-04-26 "-1.046"  "22.2"      "market"   "short"    NA              "closed"     "2006-04-27 00:00:00" ""     NA        "0"      "increase_short_low" ""           
2006-05-08 "all"     "20.41"     "market"   "short"    NA              "replaced"   "2006-05-08"          ""     NA        "0"      "close_position_up"  ""           
2006-05-08 "1.046"   "20.41"     "market"   "long"     NA              "closed"     "2006-05-09 00:00:00" ""     NA        "0"      "increase_long_up"   ""

1 Answers1

0

Yes, you must set the replace parameter in ruleSignal to FALSE. Otherwise, all but the the last processed order for a symbol at a given time will get replaced by the last order.

James Hirschorn
  • 7,032
  • 5
  • 45
  • 53
  • Thanks James! Unfortunately I've switched completely to Python trading libs long time ago, so I can't check whether this works fine with my code. – Vyacheslav Zotov Jul 25 '18 at 02:16