【问题标题】:How to Write a Custom Rule Function for Quantstrat in R - Replace trailing stop order with stoplimit with ruleOrderProc如何在 R 中为 Quantstrat 编写自定义规则函数 - 使用 ruleOrderProc 将追踪止损订单替换为 stoplimit
【发布时间】:2018-03-02 12:20:39
【问题描述】:

我的目标是使用我在下面概述的规则来生成一个信号,以放置一个新的“止损限价”订单来代替我的追踪止损。我不希望我的止损无限期地追踪,直到它达到我的盈亏平衡价格(如果这已经可以实现,请告诉我)。

我希望在 quantstrat 中编写自定义规则,目标如下:

如果今天的“收盘价”减去 (-) 交易打开时间戳的阈值(标量),则大于 (>) 交易打开时间戳的“打开”价格(这也是填充值或order.price) 然后生成一笔交易(我也只希望这种情况发生一次,所以像 cross = T)

For example:
Open a Trade on 01-01-2000 @ $150.00
Threshold value on 01-01-2000 is $5.00
Today's Close on 02-01-2000  = "$155.50"

由于今天的收盘价减去阈值是 > 成交价,因此生成下单信号。问题是我不认为 add.signal 可以做到这一点,至少不能在 add.rule 函数之外完成,因为我需要访问订单簿。我无法预先计算 mktdata 对象,因为我有许多不生成订单的入场信号,并且仅查看 mktdata 无法判断哪些信号导致了订单。

有人可以告诉我我需要调整 add.rule() 的哪一部分以使这成为可能吗?如果我需要编写自己的ruleSignal 函数,由于我提前没有信号,我应该为 sigcol 和 sigval 放什么?

以下是我目前的多头交易规则:

# Long Entry
add.rule(strategy.st, name = 'ruleSignal',
     arguments = list(sigcol = 'longSig',
                      sigval = TRUE,
                      replace = F,
                      orderside = 'long',
                      ordertype = 'market',
                      osFUN     = osATR,
                      prefer    = 'Open'),
                      type      = 'enter',
                      label     = 'enterLong',
                      path.dep  = T)


# Long Stop
add.rule(strategy.st, name = 'ruleSignal',
     arguments = list(sigcol = 'longSig', sigval = T,
                      orderqty = 'all', ordertype = 'stoptrailing',
                      orderside = 'long',
                      replace   = F,
                      threshold = 'stpVal'),
                      orderset = 'goLong',
                      type = 'chain',
                      path.dep = T,
                      parent = 'enterLong')

感谢任何帮助,我将分享我的结果。谢谢!

【问题讨论】:

    标签: r trading algorithmic-trading quantstrat blotter


    【解决方案1】:

    您在 quantstrat 中修改核心 ruleOrderProc 函数的解决方案似乎很好。如果您正在寻找不需要修改 quantstrat 源代码的开箱即用解决方案,您可以使用方便的 "trigger" 订单数量参数。正如在ruleSignal.R 中找到的ruleSignal 的quantstrat 文档中所述:

    \code{orderqty} 应该是数字,或“全部”/“触发器”之一。 'all' 只能与 ruletype='exit' 的顺序一起使用 或“风险”,并将关闭整个头寸。 “触发器”只能是 与 ruletype='chain' 一起使用并且与 'all' 完全相同,除了 实际交易被抑制,可用于启动 新的订单链。

    这是一个自包含的简化策略,我认为它可以满足您的需求。

    请注意,如果带有触发器的限价单被执行,则不会发生实际交易(查看ruleOrderProc 的源代码,您会看到addTxn 如果是@,则不会被调用987654327@数量)。

    工具为 GBPUSD,数据来自 quantstrat。当 MACD 信号从下方穿过 0 时,该策略进入多头头寸。如果 MACD 信号随后穿过 0 以下,则退出任何未平仓多头头寸。如果在入场时价格上涨超过价格的 0.05%(请记住,这是一个外汇汇率,因此与股票相比,预计变动百分比较小),那么任何未平仓追踪止损都将转换为止损限价。

    这种方法需要定义一个新的规则函数来处理从 stoptrailing 到 stoplimit 的转换。

    library(quantstrat)
    from <- "2002-10-20"
    to <- "2002-10-21"
    
    symbols <- "GBPUSD"
    # Load 1 minute data stored in the quantstrat package
    getSymbols.FI(Symbols = symbols,
                  dir=system.file('extdata',package='quantstrat'),
                  from=from, 
                  to=to
    )
    
    currency(c('GBP', 'USD'))
    exchange_rate('GBPUSD', tick_size=0.0001)
    
    strategy.st <- "updateStopStrat"
    portfolio.st <- "updateStopStrat"
    account.st <- "updateStopStrat"
    
    rm.strat(strategy.st)
    
    initPortf(portfolio.st, symbols = symbols)
    initAcct(account.st, portfolios = portfolio.st, initEq = 1e5)
    initOrders(portfolio.st)
    strategy(strategy.st, store = TRUE)
    
    tradeSize <- 1000
    for (sym in symbols) {
      addPosLimit(portfolio.st, sym, start(get(sym)), tradeSize)
    }
    
    
    strategy(strategy.st, store=TRUE)
    
    fastMA = 12 
    slowMA = 26 
    signalMA = 9
    maType = "EMA"
    n.RSI <- 30
    thresRSI <- 80
    
    add.indicator(strategy.st, name = "MACD", 
                  arguments = list(x=quote(Cl(mktdata)),
                                   nFast=fastMA, 
                                   nSlow=slowMA),
                  label='co' 
    )
    
    add.signal(strategy.st,name="sigThreshold",
               arguments = list(column="signal.co",
                                relationship="gt",
                                threshold=0,
                                cross=TRUE),
               label="signal.gt.zero"
    )
    
    
    entryThreshold <- 0.0005
    
    
    add.signal(strategy.st,name="sigThreshold",
               arguments = list(column="signal.co",
                                relationship="lt",
                                threshold=0,
                                cross=TRUE),
               label="signal.lt.zero"
    )
    
    # For debugging purposes:
    #mdata <- applyIndicators(strategy.st, GBPUSD)
    #mdata <- applySignals(strategy.st, mdata)
    #stop()
    
    # Define a custom rule to handle converting an "open" stoptrailing order to a stoplimit order.  This will be included as part of a rule:
    
    ruleModify_stoptrailing1 <- function(mktdata = mktdata, 
                                         timestamp, 
                                         sigcol, 
                                         sigval, 
                                         orderqty=0, 
                                         ordertype, 
                                         orderside=NULL, 
                                         orderset=NULL, 
                                         threshold=NULL, 
                                         tmult=FALSE, 
                                         replace=TRUE, 
                                         delay=0.0001, 
                                         osFUN='osNoOp', 
                                         pricemethod=c('market','opside','active'), 
                                         portfolio, 
                                         symbol, 
                                         ..., 
                                         ruletype, 
                                         TxnFees=0, 
                                         prefer=NULL, 
                                         sethold=FALSE, 
                                         label='', 
                                         order.price=NULL, 
                                         chain.price=NULL, 
                                         time.in.force='') {
    
    
      orderbook <- getOrderBook(portfolio)
      ordersubset <- orderbook[[portfolio]][[symbol]]
    
      # Use quantstrat helper function to identify which row in orderbook for this symbol (ordersubset) has the order we want to change:
      ii <- getOrders(portfolio=portfolio, 
                      symbol=symbol, 
                      status="open", 
                      timespan=timespan, 
                      ordertype="stoptrailing", 
                      side = orderside,
                      orderset = orderset,
                      which.i = TRUE)
      if (length(ii) > 0) {
        # If a stoptrailing order is open, then we may turn it into a fixed "hardstop" (stoplimit)
    
        ordersubset[ii,"Order.Status"] <- 'replaced' 
        ordersubset[ii,"Order.StatusTime"] <- format(timestamp, "%Y-%m-%d %H:%M:%S")
    
        if (length(ii) != 1) 
          stop("Have not got logic for handling case with more than one open trailing stop on one order side.")
    
        orderThreshold <- as.numeric(ordersubset[ii, "Order.Threshold"])
        if(hasArg(prefer)) prefer=match.call(expand.dots=TRUE)$prefer
        else prefer = NULL
        neworder <- addOrder(portfolio=portfolio,
                             symbol=symbol,
                             timestamp=timestamp,
                             qty=ordersubset[ii,"Order.Qty"],
                             # add back in the orderThreshold (orderThreshold is
                             # negative), so the Order.Price reported in the order
                             # book is the correct level for the stop.  Put
                             # another way, if you don't subtract the
                             # order.threshold here, the stop price level, given by
                             # Order.Price in the orderbook, won't be set at the
                             # expected level, but rather at the stop level - the value of orderThreshold.
                             price= as.numeric(ordersubset[ii, "Order.Price"]) -
                               orderThreshold,
                             ordertype="stoplimit",
                             prefer=prefer,
                             side=ordersubset[ii,"Order.Side"],
                             # if you dont provide the correct sign of orderThreshold (want negative for long side), addOrder will automagically set the sign appropriately to negative value here for a orderside = "long" stoplimit order.  
                             threshold = orderThreshold,
                             status="open",
                             replace=FALSE, 
                             return=TRUE,
                             orderset=ordersubset[ii,"Order.Set"],
                             label=label,
                             ...=..., 
                             TxnFees=TxnFees)
        # ^ Do not need to set the statustimestamp because any new orders start with statustimestamp = NA.
    
        ordersubset<-rbind(ordersubset, neworder)
    
        # we we have updated the orderbook for this symbol, we should reflect this
        # where the orderbook is stored (in the .strategy environment):
        orderbook[[portfolio]][[symbol]] <- ordersubset
        put.orderbook(portfolio, orderbook)
      }
    }
    
    
    add.rule(strategy.st,name='ruleSignal', 
             arguments = list(sigcol="signal.gt.zero",
                              sigval=TRUE, 
                              orderqty=tradeSize, 
                              ordertype='market', 
                              orderside='long', 
                              threshold=NULL),
             type='enter',
             label='enterL',
             storefun=FALSE
    )
    
    # convert the stop order when this threshold is achieved:
    entryThreshold <- 0.0005
    
    add.rule(strategy.st,name='ruleSignal', 
             arguments = list(sigcol="signal.gt.zero", 
                              sigval=TRUE, 
                              orderqty='trigger', 
                              ordertype='limit', 
                              orderside='long', 
                              threshold=entryThreshold, 
                              # cant be part of the 'sysMACD'orderset, otherwise when this limit order closes, it will cancel the trailingstop in the same orderset, as well as any other potential orders in the 'sysMACD' orderset such as a potential take profit (limit)
                              orderset='sysMACD.augment',
                              tmult=TRUE, 
                              replace = FALSE),
             type='chain', 
             parent='enterL', 
             label='updateStopTrigger')
    
    
    add.rule(strategy.st,name='ruleSignal', 
             arguments = list(sigcol="signal.lt.zero",
                              sigval=TRUE, 
                              orderqty='all', 
                              ordertype='market', 
                              orderside='long', 
                              threshold=NULL,
                              orderset='sysMACD',
                              replace = TRUE),
             type='exit',
             label='exitL'
    )
    
    # Typically stoptrailing order in quantstrat:
    add.rule(strategy.st,name='ruleSignal', 
             arguments = list(sigcol="signal.gt.zero", 
                              sigval=TRUE, 
                              orderqty='all', 
                              ordertype='stoptrailing', 
                              orderside='long', 
                              threshold=-entryThreshold, 
                              tmult=TRUE, 
                              orderset='sysMACD',
                              replace = FALSE),
             type='chain', 
             parent='enterL', 
             label='movingStop')
    
    
    
    
    # Make sure to cancel the trigger limit order under all possible scenarios in which the trigger order is not "filled"/closed, which for this strategy are:
    # 1) trailing stop in order set sysMACD was closed
    # 2) exit order (MACD crosses below 0) in order set sysMACD.augment was closed
    
    # Custom functions to cancel the "open" "updateStopTrigger" order, otherwise this order will remain open while the underlying position was closed from a stop filling, or an exit trade:
    ruleCancTriggerStop <- function(portfolio, symbol, timespan, orderside, orderset, timestamp, ...) {
    
      updateOrders(portfolio=portfolio, 
                   symbol=symbol, 
                   timespan=timespan,
                   side=orderside,
                   orderset=orderset, 
                   oldstatus='open', 
                   newstatus='canceled',
                   statustimestamp=timestamp
      )
      return()
    }
    
    ruleCancTriggerExit <- function(portfolio, symbol, timespan, orderside, orderset, timestamp, ...) {
    
      updateOrders(portfolio=portfolio, 
                   symbol=symbol, 
                   timespan=timespan,
                   side=orderside,
                   orderset=orderset, 
                   oldstatus='open', 
                   newstatus='canceled',
                   statustimestamp=timestamp
      )
      return()
    }
    
    
    add.rule(strategy.st,name='ruleCancTriggerExit', 
             arguments = list(sigcol="signal.lt.zero",
                              sigval=TRUE, 
                              orderqty='all', 
                              ordertype='chain', 
                              orderside='long', 
                              threshold=NULL,
                              orderset='sysMACD.augment',
                              replace = FALSE),
             parent = "exitL",
             type='chain',
             label='revokeTrig1'
    )
    
    add.rule(strategy.st,name='ruleCancTriggerStop', 
             arguments = list(sigcol="signal.lt.zero",
                              sigval=TRUE, 
                              orderqty='all', 
                              ordertype='chain', 
                              orderside='long', 
                              threshold=NULL,
                              orderset='sysMACD.augment',
                              replace = FALSE),
             parent = "movingStop",
             type='chain',
             label='revokeTrig2'
    )
    
    
    # New rule that may convert an open long trailing stop to a stoplimit, if the price increases by more than a certain amount.
    
    add.rule(strategy.st, name = 'ruleModify_stoptrailing1', 
             # sigcol here and sigval don't matter as this rule is activated just when the limit order with label "updateStopTrigger" fills.
             arguments = list(sigcol="signal.gt.zero", 
                              sigval=TRUE, 
                              orderqty='all', 
                              ordertype='stoplimit', 
                              orderside='long', 
                              threshold=-entryThreshold,
                              tmult=TRUE, 
                              orderset='sysMACD',
                              replace = FALSE),
             type = 'chain',  # process and update this order after processing whether the trailing stop was touched, any chain exit and entry orders
             parent = "updateStopTrigger",
             label ='HARDSTOP')
    #stop("update applyStrat for not updating stoptrailng.")
    
    out<-applyStrategy(strategy.st, portfolios=portfolio.st, verbose=TRUE)
    
    tx <- getTxns(portfolio.st, "GBPUSD")
    
    sum(tx$Net.Txn.Realized.PL)
    # -2.26905
    
    head(tx)
    # Txn.Qty Txn.Price Txn.Fees Txn.Value Txn.Avg.Cost Net.Txn.Realized.PL
    # 1950-01-01 00:00:00       0  0.000000        0     0.000     0.000000             0.00000
    # 2002-10-20 21:31:00    1000  1.547700        0  1547.700     1.547700             0.00000
    # 2002-10-20 21:40:00   -1000  1.547326        0 -1547.326     1.547326            -0.37385
    # 2002-10-20 22:04:00    1000  1.548200        0  1548.200     1.548200             0.00000
    # 2002-10-20 23:07:00   -1000  1.549000        0 -1549.000     1.549000             0.80000
    # 2002-10-20 23:39:00    1000  1.548900        0  1548.900     1.548900             0.00000
    
    ob <- getOrderBook(portfolio.st)
    
    # Look at the orderbook and see if things are working as expected:
    head(ob[[portfolio.st]]$GBPUSD, 15)
    # Order.Qty Order.Price  Order.Type     Order.Side Order.Threshold Order.Status Order.StatusTime      Prefer Order.Set         Txn.Fees Rule                Time.In.Force
    # 2002-10-20 21:30:00.00010 "1000"    "1.5478"     "market"       "long"     NA              "closed"     "2002-10-20 21:31:00" ""     NA                "0"      "enterL"            ""           
    # 2002-10-20 21:31:00.00010 "trigger" "1.54847385" "limit"        "long"     "0.00077385"    "canceled"   "2002-10-20 21:40:00" ""     "sysMACD.augment" "0"      "updateStopTrigger" ""           
    # 2002-10-20 21:31:00.00010 "all"     "1.54692615" "stoptrailing" "long"     "-0.00077385"   "replaced"   "2002-10-20 21:33:00" ""     "sysMACD"         "0"      "movingStop"        ""           
    # 2002-10-20 21:33:00.00001 "all"     "1.54702615" "stoptrailing" "long"     "-0.00077385"   "replaced"   "2002-10-20 21:34:00" ""     "sysMACD"         "0"      "movingStop"        ""           
    # 2002-10-20 21:34:00.00001 "all"     "1.54732615" "stoptrailing" "long"     "-0.00077385"   "closed"     "2002-10-20 21:40:00" ""     "sysMACD"         "0"      "movingStop"        ""           
    # 2002-10-20 22:03:00.00010 "1000"    "1.5482"     "market"       "long"     NA              "closed"     "2002-10-20 22:04:00" ""     NA                "0"      "enterL"            ""           
    # 2002-10-20 22:04:00.00010 "trigger" "1.5489741"  "limit"        "long"     "0.0007741"     "closed"     "2002-10-20 22:21:00" ""     "sysMACD.augment" "0"      "updateStopTrigger" ""           
    # 2002-10-20 22:04:00.00010 "all"     "1.5474259"  "stoptrailing" "long"     "-0.0007741"    "replaced"   "2002-10-20 22:06:00" ""     "sysMACD"         "0"      "movingStop"        ""           
    # 2002-10-20 22:06:00.00001 "all"     "1.5478259"  "stoptrailing" "long"     "-0.0007741"    "replaced"   "2002-10-20 22:20:00" ""     "sysMACD"         "0"      "movingStop"        ""           
    # 2002-10-20 22:20:00.00001 "all"     "1.5479259"  "stoptrailing" "long"     "-0.0007741"    "replaced"   "2002-10-20 22:21:00" ""     "sysMACD"         "0"      "movingStop"        ""           
    # 2002-10-20 22:21:00.00001 "all"     "1.5482259"  "stoptrailing" "long"     "-0.0007741"    "replaced"   "2002-10-20 22:21:00" ""     "sysMACD"         "0"      "movingStop"        ""           
    # 2002-10-20 22:21:00.00001 "all"     "1.5482259"  "stoplimit"    "long"     "-0.0007741"    "replaced"   "2002-10-20 23:06:00" ""     "sysMACD"         "0"      "HARDSTOP"          ""           
    # 2002-10-20 23:06:00.00010 "all"     "1.549"      "market"       "long"     NA              "closed"     "2002-10-20 23:07:00" ""     "sysMACD"         "0"      "exitL"             ""           
    # 2002-10-20 23:38:00.00010 "1000"    "1.5489"     "market"       "long"     NA              "closed"     "2002-10-20 23:39:00" ""     NA                "0"      "enterL"            ""           
    # 2002-10-20 23:39:00.00010 "trigger" "1.54967445" "limit"        "long"     "0.00077445"    "canceled"   "2002-10-20 23:45:00" ""     "sysMACD.augment" "0"      "updateStopTrigger" ""   
    
    # As a check on the strategy logic, let's examine the position opened at 2002-10-20 22:04
    # and closed at 2002-10-20 23:07, because we can see the stoptrailing order was
    # converted to a stoplimit in the orderbook during the life of this position.
    
    # The stoptrailing converted to a stoplimit at 2002-10-20 22:21:00.
    
    # The transaction price on entry was 1.548200 @ 22:04.   And we expect conversion when the market price reaches
    1.548200 * (1 + entryThreshold)
    # 1.548974
    
    # Let's look at the market data during this period, and check when the price first touches 1.548974:
    mktdata["2002-10-20 22"]
    
    # Open   High    Low  Close Volume     macd.co     signal.co signal.gt.zero signal.lt.zero
    # 2002-10-20 22:00:00 1.5480 1.5480 1.5480 1.5480      0 0.001132692 -0.0042646426              0              0
    # 2002-10-20 22:01:00 1.5480 1.5480 1.5480 1.5480      0 0.003498427 -0.0027120286              0              0
    # 2002-10-20 22:02:00 1.5479 1.5480 1.5479 1.5480      0 0.005311960 -0.0011072309              0              0
    # 2002-10-20 22:03:00 1.5482 1.5482 1.5482 1.5482      0 0.007703042  0.0006548237              1              0
    # 2002-10-20 22:04:00 1.5481 1.5482 1.5481 1.5482      0 0.009488476  0.0024215542              0              0
    # 2002-10-20 22:05:00 1.5481 1.5482 1.5481 1.5482      0 0.010779080  0.0040930594              0              0
    # 2002-10-20 22:06:00 1.5484 1.5486 1.5483 1.5485      0 0.013213351  0.0059171177              0              0
    # 2002-10-20 22:07:00 1.5486 1.5486 1.5485 1.5485      0 0.014969758  0.0077276458              0              0
    # 2002-10-20 22:08:00 1.5485 1.5485 1.5485 1.5485      0 0.016175102  0.0094171370              0              0
    # 2002-10-20 22:09:00 1.5484 1.5484 1.5484 1.5484      0 0.016419726  0.0108176549              0              0
    # 2002-10-20 22:10:00 1.5483 1.5483 1.5482 1.5483      0 0.015908934  0.0118359108              0              0
    # 2002-10-20 22:11:00 1.5484 1.5484 1.5483 1.5484      0 0.015842678  0.0126372642              0              0
    # 2002-10-20 22:12:00 1.5483 1.5484 1.5483 1.5484      0 0.015610180  0.0132318473              0              0
    # 2002-10-20 22:13:00 1.5484 1.5484 1.5484 1.5484      0 0.015250094  0.0136354967              0              0
    # 2002-10-20 22:14:00 1.5482 1.5483 1.5482 1.5483      0 0.014278923  0.0137641819              0              0
    # 2002-10-20 22:15:00 1.5484 1.5484 1.5484 1.5484      0 0.013870539  0.0137854534              0              0
    # 2002-10-20 22:16:00 1.5484 1.5484 1.5484 1.5484      0 0.013392491  0.0137068610              0              0
    # 2002-10-20 22:17:00 1.5484 1.5484 1.5484 1.5484      0 0.012865315  0.0135385518              0              0
    # 2002-10-20 22:18:00 1.5485 1.5485 1.5485 1.5485      0 0.012820874  0.0133950162              0              0
    # 2002-10-20 22:19:00 1.5485 1.5485 1.5485 1.5485      0 0.012639919  0.0132439967              0              0
    # 2002-10-20 22:20:00 1.5486 1.5487 1.5486 1.5487      0 0.013384461  0.0132720896              0              0
    # 2002-10-20 22:21:00 1.5490 1.5490 1.5487 1.5487      0 0.013815191  0.0133807099              0              0
    # 2002-10-20 22:22:00 1.5487 1.5487 1.5487 1.5487      0 0.013995162  0.0135036003              0              0
    # 2002-10-20 22:23:00 1.5486 1.5491 1.5486 1.5491      0 0.016037197  0.0140103195              0              0
    # 2002-10-20 22:24:00 1.5492 1.5494 1.5492 1.5494      0 0.018999415  0.0150081387              0              0
    # 2002-10-20 22:25:00 1.5496 1.5496 1.5496 1.5496      0 0.022133478  0.0164332065              0              0
    # 2002-10-20 22:26:00 1.5500 1.5501 1.5500 1.5500      0 0.026396277  0.0184258206              0              0
    # 2002-10-20 22:27:00 1.5498 1.5498 1.5497 1.5497      0 0.027889711  0.0203185987              0              0
    # 2002-10-20 22:28:00 1.5495 1.5495 1.5493 1.5493      0 0.026681891  0.0215912573              0              0
    # 2002-10-20 22:29:00 1.5495 1.5495 1.5494 1.5494      0 0.025946416  0.0224622889              0              0
    # 2002-10-20 22:30:00 1.5493 1.5493 1.5493 1.5493      0 0.024559503  0.0228817318              0              0
    # 2002-10-20 22:31:00 1.5492 1.5492 1.5492 1.5492      0 0.022678056  0.0228409967              0              0
    # 2002-10-20 22:32:00 1.5494 1.5496 1.5493 1.5493      0 0.021460473  0.0225648918              0              0
    # 2002-10-20 22:33:00 1.5493 1.5493 1.5492 1.5492      0 0.019747018  0.0220013171              0              0
    # 2002-10-20 22:34:00 1.5491 1.5491 1.5489 1.5490      0 0.017149670  0.0210309877              0              0
    # 2002-10-20 22:35:00 1.5492 1.5492 1.5491 1.5491      0 0.015434221  0.0199116344              0              0
    # 2002-10-20 22:36:00 1.5491 1.5491 1.5491 1.5491      0 0.013914325  0.0187121724              0              0
    # 2002-10-20 22:37:00 1.5490 1.5490 1.5487 1.5489      0 0.011535059  0.0172767497              0              0
    # 2002-10-20 22:38:00 1.5492 1.5492 1.5492 1.5492      0 0.011084377  0.0160382752              0              0
    # 2002-10-20 22:39:00 1.5492 1.5492 1.5492 1.5492      0 0.010604952  0.0149516105              0              0
    # 2002-10-20 22:40:00 1.5496 1.5496 1.5496 1.5496      0 0.012168207  0.0143949299              0              0
    # 2002-10-20 22:41:00 1.5495 1.5496 1.5495 1.5496      0 0.013254194  0.0141667827              0              0
    # 2002-10-20 22:42:00 1.5497 1.5497 1.5496 1.5496      0 0.013953900  0.0141242062              0              0
    # 2002-10-20 22:43:00 1.5495 1.5495 1.5495 1.5495      0 0.013828134  0.0140649917              0              0
    # 2002-10-20 22:44:00 1.5496 1.5497 1.5495 1.5495      0 0.013571982  0.0139663898              0              0
    # 2002-10-20 22:45:00 1.5495 1.5495 1.5495 1.5495      0 0.013216603  0.0138164325              0              0
    # 2002-10-20 22:46:00 1.5495 1.5495 1.5495 1.5495      0 0.012787536  0.0136106532              0              0
    # 2002-10-20 22:47:00 1.5494 1.5494 1.5492 1.5492      0 0.010761044  0.0130407315              0              0
    # 2002-10-20 22:48:00 1.5493 1.5493 1.5492 1.5492      0 0.009050703  0.0122427258              0              0
    # 2002-10-20 22:49:00 1.5494 1.5495 1.5494 1.5495      0 0.009152182  0.0116246171              0              0
    # 2002-10-20 22:50:00 1.5494 1.5494 1.5494 1.5494      0 0.008612505  0.0110221948              0              0
    # 2002-10-20 22:51:00 1.5495 1.5495 1.5494 1.5494      0 0.008091531  0.0104360620              0              0
    # 2002-10-20 22:52:00 1.5494 1.5495 1.5494 1.5494      0 0.007591147  0.0098670789              0              0
    # 2002-10-20 22:53:00 1.5494 1.5494 1.5494 1.5494      0 0.007112597  0.0093161825              0              0
    # 2002-10-20 22:54:00 1.5494 1.5494 1.5494 1.5494      0 0.006656609  0.0087842677              0              0
    # 2002-10-20 22:55:00 1.5492 1.5493 1.5492 1.5492      0 0.005193756  0.0080661654              0              0
    # 2002-10-20 22:56:00 1.5493 1.5494 1.5493 1.5494      0 0.005018204  0.0074565731              0              0
    # 2002-10-20 22:57:00 1.5494 1.5494 1.5493 1.5493      0 0.004308602  0.0068269789              0              0
    # 2002-10-20 22:58:00 1.5494 1.5494 1.5492 1.5492      0 0.003188666  0.0060993163              0              0
    # 2002-10-20 22:59:00 1.5493 1.5493 1.5492 1.5492      0 0.002274880  0.0053344290              0              0
    
    # We can see the price first touches 1.5490 on the 2002-10-20 22:21:00 bar, which is the timestamp at which the stoptrailing is closed and the stoplimit is opened in the orderbook.
    

    【讨论】:

      【解决方案2】:

      我通过更改quantstrat::ruleOrderProc的来源找到了一个临时解决方案

      你可以在这里找到master分支--->quantstrat::ruleOrderProc

      一些注意事项: 我正在使用 OHLC 每日数据。这不适用于 BBO 或刻度数据。也没有办法恢复到永久追踪止损。每当我的stoptrailing 订单达到我的入场价时,我的更改就会下一个stoplimit 订单。

      347 &gt; elseif(isOHLCmktdata) {github 主分支上的第 347 行附近

      我做了以下更改:

                 else if(isOHLCmktdata)
                 {
                   # check to see if price moved through the limit THE IS A "CLOSED" ORDER
      
                   order.side <- ordersubset[ii, "Order.Side"]
      
                   if(order.side == 'long'  && as.numeric(Lo(mktdataTimestamp)[,1]) < orderPrice
                      || order.side == 'short' && as.numeric(Hi(mktdataTimestamp)[,1]) > orderPrice)
                   {
                     txnprice <- orderPrice
                     txntime <- timestamp
                   }
                   else
                   {
                     # THIS IS WHERE THE TRAILING STOP IS ADJUSTED
                     # Get order threshold
                     order.threshold <- as.numeric(ordersubset[ii, "Order.Threshold"])
                     order.qty <- ordersubset[ii, "Order.Qty"]   # if orderQty='all' we must recover it
      
                     # Get the fill price
                     transactions      <- getTxns(Portfolio = portfolio, Symbol = symbol)
                     last.transaction  <- tail(transactions, 1)
                     trans.price       <- last.transaction[,2]
      
      
                     if(order.side == 'long')
                       new.order.price <- max(orderPrice, as.numeric(Hi(mktdataTimestamp)[,1]) + order.threshold)
                     if(order.side == 'short')
                       new.order.price <- min(orderPrice, as.numeric(Lo(mktdataTimestamp)[,1]) + order.threshold)
      
                     if(new.order.price != orderPrice)
                     {
                       if (order.side == 'long' && new.order.price > trans.price || order.side == 'short' && new.order.price < trans.price) {
      
                         # Add an order with a stoplimit order type
                         neworder<-addOrder(portfolio=portfolio,
                                            symbol=symbol,
                                            timestamp=timestamp,
                                            qty=order.qty,
                                            price=new.order.price - order.threshold,
                                            ordertype='stoplimit',
                                            side=order.side,
                                            threshold=order.threshold,
                                            status="open",
                                            replace=FALSE, return=TRUE,
                                            orderset=ordersubset[ii,"Order.Set"],
                                            label=ordersubset[ii,"Rule"],
                                            ,...=..., TxnFees=txnfees)
      
                       } else {
                       # adjust trailing stop
                       neworder<-addOrder(portfolio=portfolio,
                                          symbol=symbol,
                                          timestamp=timestamp,
                                          qty=order.qty,
                                          price=new.order.price - order.threshold,
                                          ordertype=orderType,
                                          side=order.side,
                                          threshold=order.threshold,
                                          status="open",
                                          replace=FALSE, return=TRUE,
                                          orderset=ordersubset[ii,"Order.Set"],
                                          label=ordersubset[ii,"Rule"],
                                          ,...=..., TxnFees=txnfees)
                       }
      
                       ordersubset<-rbind(ordersubset, neworder)
      
                       ordersubset[ii,"Order.Status"]<-'replaced'
                       ordersubset[ii,"Order.StatusTime"]<-format(timestamp, "%Y-%m-%d %H:%M:%S")
      
                       next()
                     }
                   }
                 }
      
               } # end stoptrailing
      

      主要变化是获得成交价

          # Get the fill price
                 transactions      <- getTxns(Portfolio = portfolio, Symbol = symbol)
                 last.transaction  <- tail(transactions, 1)
                 trans.price       <- last.transaction[,2]
      

      然后添加这个if 语句

          if (order.side == 'long' && new.order.price > trans.price || order.side == 'short' && new.order.price < trans.price) { 
      

      下一个stoplimit 订单,而不是无限期地移动止损。到目前为止,它一直在正常工作。

      【讨论】:

        猜你喜欢
        • 2018-11-10
        • 1970-01-01
        • 2017-11-13
        • 1970-01-01
        • 2015-09-06
        • 2021-06-08
        • 1970-01-01
        • 2012-08-21
        • 2013-05-20
        相关资源
        最近更新 更多