Skip to content

Trailing stop not working in R (Luxor example)

3 messages · Peter Neumaier, Derek Wong, Joshua Ulrich

#
I am trying to implement a trailing stop in the Luxor example.

I have tried many approaches to debug/find the error, i.e.

   - run with and without stoploss enabled
   - different levels of stoptrailingpercent
   - the list goes on

But my orderbook (ob.df at the of code) simply is not showing any trailing
stops executed.

Anyone got any suggestions why my trailing stop is not working? Here is my
code:


## ----results='hide'------------------------------------------------------
library(quantstrat)

options(width = 240)#options(warn=1)

Sys.setenv(TZ="UTC")
###
initDate = '2003-10-21'
.from='2012-01-01'
.to='2016-03-01'

currency(c('EUR', 'USD'))
exchange_rate('EURUSD', tick_size=0.0001)

# moving average lengths
.fast = 6
.slow = 21
# optimization range
.FastSMA = (1:30)
.SlowSMA = (20:80)
# trade parameters
.threshold = 0.0005
.orderqty = 100000
.txnfees = -6  # round-trip fee
# stop loss amount
.stoploss <- 0.30/100
# trading window
.timespan = 'T00:00/T23:59'
# number of optimization samples
.nsamples=80

## ------------------------------------------------------------------------portfolio.st
= 'forex'account.st = 'IB1'strategy.st = 'luxor'

.trailingStopPercent <- 0.001

rm.strat(portfolio.st)
rm.strat(account.st)
rm.strat(strategy.st)
## ----results='hide'------------------------------------------------------
initPortf(portfolio.st, symbols='EURUSD', initDate=initDate, currency='USD')
addPosLimit(portfolio=portfolio.st,symbol='EURUSD',
timestamp=initDate,maxpos=.orderqty)

    initAcct(account.st,portfolios=portfolio.st,initDate=initDate,currency='USD')
initOrders(portfolio.st, initDate=initDate)
strategy(strategy.st, store=TRUE)

getSymbols("EUR/USD", src="oanda", from=.from, to=.to,
index.class="POSIXct",adjust=T)

EURUSD = to.minutes30(EURUSD)
EURUSD = align.time(EURUSD, 1800)



add.indicator(strategy.st, name = "SMA",
          arguments = list(
            x = quote(Cl(mktdata)[,1]),
            n = .fast
          ),
          label="nFast")

add.indicator(strategy.st, name="SMA",
          arguments = list(
            x = quote(Cl(mktdata)[,1]),
            n = .slow
          ),
          label="nSlow")


add.signal(strategy.st, name='sigCrossover',
       arguments = list(
         columns=c("nFast","nSlow"),
         relationship="gte"
       ),
       label='long')

add.signal(strategy.st, name='sigCrossover',
       arguments = list(
         columns=c("nFast","nSlow"),
         relationship="lt"
       ),
       label='short')


add.rule(strategy.st, name = 'ruleSignal',
     arguments=list(sigcol='long' , sigval=TRUE,
                    replace=FALSE,
                    orderside='long' ,
                    ordertype='stoplimit',
                    prefer='High',
                    threshold=.threshold,
                    TxnFees=0,
                    orderqty=+.orderqty,
                    osFUN=osMaxPos,
                    orderset='ocolong'
     ),
     type='enter',
     timespan = .timespan,
     label='EnterLONG')


add.rule(strategy.st, name = 'ruleSignal',
     arguments=list(sigcol='short', sigval=TRUE,
                    replace=FALSE,
                    orderside='short',
                    ordertype='stoplimit',
                    prefer='Low',
                    threshold=.threshold,
                    TxnFees=0,
                    orderqty=-.orderqty,
                    osFUN=osMaxPos,
                    orderset='ocoshort'
     ),
     type='enter',
     timespan = .timespan,
     label='EnterSHORT')


add.rule(strategy.st, name = 'ruleSignal',
     arguments=list(sigcol='short', sigval=TRUE,
                    replace=TRUE,
                    orderside='long' ,
                    ordertype='market',
                    TxnFees=.txnfees,
                    orderqty='all',
                    orderset='ocolong'
     ),
     type='exit',
     timespan = .timespan,
     label='Exit2SHORT')


add.rule(strategy.st, name = 'ruleSignal',
     arguments=list(sigcol='long' , sigval=TRUE,
                    replace=TRUE,
                    orderside='short',
                    ordertype='market',
                    TxnFees=.txnfees,
                    orderqty='all',
                    orderset='ocoshort'
     ),
     type='exit',
     timespan = .timespan,
     label='Exit2LONG')


add.rule(strategy.st, name = 'ruleSignal',
     arguments=list(sigcol='long' , sigval=TRUE,
                    replace=FALSE,
                    orderside='long',
                    ordertype='stoplimit',
                    tmult=TRUE,
                    threshold=quote(.stoploss),
                    TxnFees=.txnfees,
                    orderqty='all',
                    orderset='ocolong'
     ),
     type='chain', parent='EnterLONG',
     label='StopLossLONG',
     enabled=FALSE)

add.rule(strategy.st, name = 'ruleSignal',
     arguments=list(sigcol='long' , sigval=TRUE,
                    replace=FALSE,
                    orderside='long',
                    ordertype='stoptrailing',
                    tmult=TRUE,
                    threshold=quote(.trailingStopPercent),
                    orderqty='all',
                    orderset='ocolong'
     ),
     type='chain', parent='EnterLong',
     label='StopTrailingLong',
     enabled=FALSE)

add.rule(strategy.st, name = 'ruleSignal',
     arguments=list(sigcol='short' , sigval=TRUE,
                    replace=FALSE,
                    orderside='short',
                    ordertype='stoplimit',
                    tmult=TRUE,
                    threshold=quote(.stoploss),
                    TxnFees=.txnfees,
                    orderqty='all',
                    orderset='ocoshort'
     ),
     type='chain', parent='EnterSHORT',
     label='StopLossSHORT',
     enabled=FALSE)
# add.rule(strategy.st, name = 'ruleSignal',#
arguments=list(sigcol='short' , sigval=TRUE,#
replace=FALSE,#                         orderside='short',#
             ordertype='stoptrailing',#
tmult=TRUE,#
threshold=quote(trailingStopPercent),#
orderqty='all',#                         orderset='ocoshort'#
),#          type='chain', parent='EnterShort',#
label='StopTrailingShort',#          enabled=FALSE# )

enable.rule('luxor', 'chain', 'StopLoss')
enable.rule('luxor', 'chain', 'StopTrailingLong')


out <- applyStrategy(strategy.st, portfolio.st)
updatePortf(portfolio.st, Symbols='EURUSD',
        Dates=paste('::',as.Date(Sys.time()),sep=''))

ob <- getOrderBook(portfolio.st)$forex$EURUSD
ob.df <- data.frame(Date=time(ob),coredata(ob))
View(ob.df)
#
Hi Peter,

I had submitted a problem with the trailing stop in quantstrat 2 weeks
ago. I have looked at the code in the orders.R and ruleproc.R and
still have not discovered the problem. It does not update on every
higher high, or lower low. But in a more jumpy fashion, especially if
you use prefer= anything other than close. Although diving in to that
code, the logic seemed correct. I just have not found that the
trailingstop is reliable at this time in quantstrat.

-Derek

On Mon, Mar 7, 2016 at 12:47 AM, Peter Neumaier
<peter.neumaier at gmail.com> wrote:
5 days later
#
Hi Derek,

I just replied to your earlier email and wanted to note here that the
issue only seems to be with stoptrailing orders on OHLC data.  Using
them on BBO data should work correctly.

Best,
Josh
On Sun, Mar 6, 2016 at 6:44 PM, Derek Wong <treydog999 at gmail.com> wrote: