Stop Loss orders in quantstrat

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Stop Loss orders in quantstrat

Rmetrics mailing list

Greetings
I have been trying to model stoplosses in quantstrat. Since intra day lows can be spurious whipsaws, I would like to model a stop loss that triggers a market order at the open of the next day if the stop was triggered based on the close of the previous day. As of now it appears that using stoplimit orders triggers the market order based on the high( for short open positions) or the low( for long open positions). I’ve tried playing around with the prefer = option but I haven’t been able to see any changes based on this setting. 
Any help on how I can model these stop orders would be appreciated. 
Many thanks to Ilya Kipnis for pointing me to this group. Also many thanks in advance. 
Regards

Sent from Yahoo Mail for iPhone

        [[alternative HTML version deleted]]

_______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Stop Loss orders in quantstrat

braverock
On 02/10/2018 12:14 AM, Sanjay Mansabdar via R-SIG-Finance wrote:
> I have been trying to model stoplosses in quantstrat. Since intra day lows can be spurious whipsaws, I would like to model a stop loss that triggers a market order at the open of the next day if the stop was triggered based on the close of the previous day. As of now it appears that using stoplimit orders triggers the market order based on the high( for short open positions) or the low( for long open positions). I’ve tried playing around with the prefer = option but I haven’t been able to see any changes based on this setting.
> Any help on how I can model these stop orders would be appreciated.
> Many thanks to Ilya Kipnis for pointing me to this group. Also many thanks in advance.

Sanjay,

There are two basic approaches to what you want to do:

- construct a signal to fire for the case that you are describing

There should be nothing stopping you from firing a signal based on the
close price and using a regular market order to enter on the Open of the
next bar.

Your rule (presumably calling ruleSignal) should use prefer='Open'

Stops on bars are inherently a guess.  So we've chosen to have the stop
entry enter on the least favorable price.  This is documented, and
shouldn't be surprising behavior.

- use higher frequency data

If you really must use stops for this, then use higher frequency data.


If this still produces what you feel to be surprising behavior, then
please produce a *minimal* reproducible example and enter an issue on
the quantstrat github.

Regards,

Brian

--
Brian G. Peterson
http://braverock.com/brian/
Ph: 773-459-4973
IM: bgpbraverock

_______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Stop Loss orders in quantstrat

Rmetrics mailing list
In reply to this post by Rmetrics mailing list
I am not sure how to reply to digest messages in the thread, so apologies in advance for errors
@Brian, I think there is no error with the implementation as it stands of stop limit orders. However IMHO stop loss logic is not necessarily the same thing as stop limit orders and perhaps needs to be thought of separately. I will try and follow the route you have suggested.
Thanks
Regards
        [[alternative HTML version deleted]]

_______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Stop Loss orders in quantstrat

Rmetrics mailing list
 I have  been trying to implement what Brian has suggested for a simple long only macd based strategy.  Given that I am new to quantstrat, this may be quite an elementary question, but here goes. 
1. I have a simple long only MACD based system that gives me entry and exit signals on T.2. On the basis os a long signal I trigger a market order to buy on T+1, at the open.3. Based on this execution, I need to set a hard stop on the position entered in #2, that is x% below the execution price of 2, with the comparison being done at the close of each day, and if the signal triggers on some day D, the order is executed as a market sell order on the next day D+1.My signal essentially says "Check to see if the closing price on any day is less than the execution prices of the last opening trade minus a threshold and if it is, trigger a signal".4. This clearly needs, at any point, the value of the execution price of the market order in #2, the timestamp of #2 5.Finally the rule that triggers the market sell order described in #3 would need to know the existing position size as well.
I am not quite sure how to extract these state variables to include in the signal and in the rule. Any help on this would be appreciated. 
Thanks in advance.

    On Tuesday, February 13, 2018, 12:42:07 PM GMT+5:30, Sanjay Mansabdar <[hidden email]> wrote:  
 
 I am not sure how to reply to digest messages in the thread, so apologies in advance for errors
@Brian, I think there is no error with the implementation as it stands of stop limit orders. However IMHO stop loss logic is not necessarily the same thing as stop limit orders and perhaps needs to be thought of separately. I will try and follow the route you have suggested.
Thanks
Regards  
        [[alternative HTML version deleted]]

_______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Stop Loss orders in quantstrat

Rmetrics mailing list
Greetings,

Here is my implementation of the stop loss code based on suggestions from Brian and others that I have received. To recap, the current implementation of the stop loss is to compare the price midbar to the stop limit price calculated as entry price - threshold. This causes intra day whipsaws to exit positions. I would like to model the stop loss mechanism that I follow in my trading, which is to compare the closing price on any day to entry price - threshold and if true then exit using a market order at open the following day. 

This is a long only system where MACD signal crossing zero generates the long position taken at the Close of the next day. This is done via the usual quantstrat functions, drawing from the macd demo code.

I also calculate the buy signal with cross = FALSE and lag this signal by 1 day to indicate if there is a position ( as the Stop Loss order needs to be position aware). This is called 'longpos'

Once the position is taken , I calculate an indicator SLPX that is essentially the stop loss price. If the close on any day is below this stop loss price then a market order is triggered to sell out. The SLPX indicator needs to work by taking  the buy signal, lagging this by a day as the opening trade is taken the next day and using this calculate the stop loss price which is entry price*(1-stop loss percent). This is the indicator "SLPX" This updates whenever a new position is taken else equals the previous value carried forward.

I create another signal that triggers when the closing price is below the stop loss as returned by the SLPX indicator. This is the signal "SLCondition"

A final signal "SLTrigger" [using sigFormula triggers if "longpos" and "SLCondition" are true simultaneously, with cross = TRUE so that this is evaluated only the first time this happens.

A Stop Loss order is fired as a market order if "SLTrigger" is set to 1. This will happen one day after.

There is also an exit condition if the MACD signal moves below zero (with its own signal) and the exit order is set as an oco with the stop loss order.

The code is attached with this mail and also presented at the end of this mail. I suspect there are much easier ways of doing this, however as an R novice, I am not quite sure of how else to make the indicators and signals position aware which they need to be to trigger the stop losses in this way the next day, and based on the close of the previous day, rather than on the same day and based on the low of the day. I will appreciate any help with how to do this, if there is an easier way.

When I run this the error I get is as follows. 

------

 applyStrategy(strategy=strat.name , portfolios=portfoli .... [TRUNCATED] 
Error in attr(x, "tsp") <- c(1, NROW(x), 1) : 
  attempt to set an attribute on NULL
In addition: Warning messages:
1: In rm("account.st", "portfolio.st", "stock.str", "stratMACD", "initDate",  :
  object 'stratMACD' not found
2: In rm("account.st", "portfolio.st", "stock.str", "stratMACD", "initDate",  :
  object 'start_t' not found
3: In rm("account.st", "portfolio.st", "stock.str", "stratMACD", "initDate",  :
  object 'end_t' not found

------

A few questions if anyone can help.

1. What am I doing wrong? 
2. Is it even possible to make the signals position aware as I have done given that Ive seen in the documentation that they are not supposed to be path dependent (as I imagine position awareness demands)
3. If yes, Is there a way of referencing positions and prices within signals?


Thanks in advance for any pointers. Quantstrat is an excellent bit of work from my perspective and I hope to learn enough about it to use it in my trading and to contribute to it.

Sanjay

########################




Full Code:

######################################################################################
# This script tries to implement a stop loss on a closing price basis.
# Rules:
# BTO: when MACD crosses threshold of zero from below
# STC: when MACD crosses threshold of zero from above
# Stop Loss: If on any day the closing price is less than the BTO*(1-X), exit at market 
# on open the next day where X is the loss tolerable
######################################################################################

# libraries###########################################################################

require(quantstrat)



# remove old parameters ##############################################################

try(rm("order_book.macd",pos=.strategy),silent=TRUE)

try(rm("account.macd","portfolio.macd",pos=.blotter),silent=TRUE)

try(rm("account.st","portfolio.st","stock.str","stratMACD","initDate","initEq",'start_t','end_t'),silent=TRUE)

# settingup quantstrat ##############################################################

stock.str='AAPL' 

currency('USD')

stock(stock.str,currency='USD',multiplier=1)

initDate<-'2009-12-31'

initEq=1000000

portfolio.st<-'macd'

account.st<-'macd'

strat.name <- 'stratMACD'

initPortf(portfolio.st,symbols=stock.str, initDate=initDate)

initAcct(account.st,portfolios=portfolio.st, initDate=initDate)

initOrders(portfolio=portfolio.st,initDate=initDate)

strategy(strat.name,store = TRUE)

# System parameters ##################################################################

fastMA <- 12 

slowMA <- 26 

signalMA <- 9

maType <-"EMA"

slpercent <-0.05

# Get Data ###########################################################################

getSymbols(stock.str,from=initDate)

# Custom Indicator Function #########################################################

# This is a function to create an indicator that is path dependent.
# This function looks at the MACD signal that triggers an entry trade and then creates the appropriate stop loss
# level for that entry. This will be used to create a signal 

SLPX<-function(OHLC,slpercent){
  slpx<-rep(NA, times = nrow(OHLC))    # create the output vector and fill with NA
  OHLC$longlag<-lag(OHLC$signal.gt.zero.x,n=1) #lag the BTO signal by 1 bar as position taken the next day
  for (counter in (1:nrow(OHLC))){
    slpx[counter]
    if (!is.na(OHLC[counter]$longlag)) {  # do nothing if the signal is an NA value
      if(OHLC[counter]$longlag==1) {
        slpx[counter] = Op(OHLC[counter])*(1-slpercent) # if signal is 1, then figure out operating stop loss
      } else {
        slpx[counter] = slpx[counter-1] # is signal is zero then carry forward previously calculated value
      }
    }
    
    
  }
  
  return(slpx)
}


# Add Indicator MACD   ###############################################################

add.indicator(strategy = strat.name,
              name = "MACD",
              arguments = list(x = quote(Cl(mktdata)), nFast=fastMA, nSlow = maSlow, nSig = signalMA, maType=maType)  
              )


# Add BTO Signal ######################################################################

add.signal(strategy = strat.name,
           name = "sigThreshold",
           arguments = list(column = "signal.MACD.ind",
                            relationship = "gt",
                            threshold = 0,
                            cross = TRUE
                            ),
            label = "signal.gt.zero.x"  
            )

# Add STC Signal ######################################################################

add.signal(strategy = strat.name,
           name = "sigThreshold",
           arguments = list(column = "signal.MACD.ind",
                            relationship = "lt",
                            threshold = 0,
                            cross = TRUE
                            ),
           label = "signal.lt.zero.x"
          )

# Add signal that indicates whether there is a position due to BTO signal

add.signal(strategy = strat.name,
           name = "sigThreshold",
           arguments = list(column = "signal.MACD.ind",
                            relationship = "gt",
                            threshold = 0,
                            cross = FALSE
           ),
           label = "signal.gt.zero.pos"  
)

# Lag the above signal by 1 bar as long position gets taken the next bar ############

add.indicator (strategy = strat.name,
                 name = "lag",
                 arguments = (list(x=quote(mktdata$signal.gt.zero.pos), n=1)),
                 label = "longpos"
                 )


# Add SLPX Indicator ################################################################

add.indicator( strategy = strat.name,
               name = "SLPX",
               arguments = (list(OHLC=quote(mktdata), slpercent = 0.05)),
               label = "SLPX")
               



# Add signal to check whether Close on any day is less that the stop loss level from
# the indicator SLPX  ###############################################################

add.signal(strategy = strat.name,
           name = "sigComparison",
           arguments = list(columns=c(quote(Cl(mktdata)),"SLPX")),
           label = "SLCondition")        

# Check whether longpos and SL condition are met simultaneously #####################

add.signal( strategy = strat.name,
            name = "sigFormula",
            arguments = list(formula = "longpos & SLCondition", cross = TRUE),
            label = "SLTrigger"
          )

# Add BTO Rule #######################################################################

add.rule(strategy = strat.name,
         name =  "ruleSignal",
         arguments = list(
                          sigcol = "signal.gt.zero.x",
                          sigval = TRUE,
                          orderqty = 100,
                          prefer = "Open",
                          replace = TRUE,
                          ordertype = 'market',
                          orderside = 'long',
                          threshold = NULL
                          ),
         type= "enter",
         label = "enterlong"
        )

# Add STC Rule #######################################################################

add.rule(strategy = strat.name,
         name =  "ruleSignal",
         arguments = list(
           sigcol = "signal.lt.zero.x",
           sigval = TRUE,
           orderqty = 'all',
           prefer = "Open",
           replace = FALSE,
           ordertype = 'market',
           orderside = 'long',
           threshold = NULL,
           orderset = 'ocolong'
         ),
         type= "exit",
         label = "exitlong"
)

# Add Stop Loss Rule [part of orderset 'ocolong'] ##############################

add.rule(strategy = strat.name,
         name =  "ruleSignal",
         arguments = list(
           sigcol = "SLTrigger",
           sigval = TRUE,
           orderqty = 'all',
           prefer = "Open",
           replace = FALSE,
           ordertype = 'market',
           orderside = 'long',
           threshold = NULL,
           orderset = 'ocolong'
         ),
         type= "exit",
         label = "SL")


#Apply Strategy #######################################################################

applyStrategy(strategy=strat.name , portfolios=portfolio.st)

# Updates #############################################################################

updatePortf(Portfolio=portfolio.st,Dates=paste('::',as.Date(Sys.time()),sep=''))

#  Outputs ############################################################################

chart.Posn(Portfolio=portfolio.st,Symbol=stock.str)

plot(add_MACD(fast=fastMA, slow=slowMA, signal=signalMA,maType="EMA"))

print ('order book')


getOrderBook(portfolio.st)

print('transactions')


getTxns(Portfolio=portfolio.st, Symbol=stock.str)




On Tuesday, February 13, 2018, 6:28:13 PM GMT+5:30,


I have  been trying to implement what Brian has suggested for a simple long only macd based strategy.  Given that I am new to quantstrat, this may be quite an elementary question, but here goes. 

1. I have a simple long only MACD based system that gives me entry and exit signals on T.
2. On the basis os a long signal I trigger a market order to buy on T+1, at the open.
3. Based on this execution, I need to set a hard stop on the position entered in #2, that is x% below the execution price of 2, with the comparison being done at the close of each day, and if the signal triggers on some day D, the order is executed as a market sell order on the next day D+1.My signal essentially says "Check to see if the closing price on any day is less than the execution prices of the last opening trade minus a threshold and if it is, trigger a signal".
4. This clearly needs, at any point, the value of the execution price of the market order in #2, the timestamp of #2 
5.Finally the rule that triggers the market sell order described in #3 would need to know the existing position size as well.

I am not quite sure how to extract these state variables to include in the signal and in the rule. Any help on this would be appreciated. 

Thanks in advance.


On Tuesday, February 13, 2018, 12:42:07 PM GMT+5:30


I am not sure how to reply to digest messages in the thread, so apologies in advance for errors

@Brian, I think there is no error with the implementation as it stands of stop limit orders. However IMHO stop loss logic is not necessarily the same thing as stop limit orders and perhaps needs to be thought of separately. I will try and follow the route you have suggested.

Thanks

Regards

_______________________________________________
[hidden email] 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.

macd_SL6.R (10K) Download Attachment