首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Quantstrat订单修改

Quantstrat订单修改
EN

Stack Overflow用户
提问于 2016-08-11 23:15:29
回答 1查看 624关注 0票数 2

您好,我有一个chain类型的rule,它将在输入头寸时提交限价订单利润目标。到目前为止都是非常标准的东西,但是我以后如何修改这个开放的订单呢?具体地说,如果(在某个时间延迟之后)最初生成rulesignal再次被触发,我希望修改利润目标的未平仓订单的价格。

从文档中,我认为我应该使用order类型的rule来实现这一点,但是我似乎找不到任何使用这种类型的规则及其工作原理的文档或示例。

EN

回答 1

Stack Overflow用户

发布于 2018-05-16 20:41:35

“从文档中,我认为我应该使用order类型的规则来实现这一点,但我似乎找不到任何使用这种类型的规则及其工作原理的文档或示例。”

如果您使用开箱即用的quantstrat函数ruleOrderProc来处理打开的订单,则规则类型"order“用于处理打开的订单(这是quantstrat中处理打开订单的默认函数,但您也可以插入您自己的"order”处理函数来取代ruleOrderProc)。例如,ruleOrderProc不提供移动限价指令的能力,就像它处理止损指令那样。

要回答您的问题,您可以创建一个更新限制订单的自定义规则函数。下面是它如何使用一个简单的策略来工作。

  • 仪器是英镑兑美元,数据来自quantstrat。
  • 当MACD信号从下方越过0时,该策略进入多头位置。
  • 增加了获利回吐指令,设定为高于交易价格0.25%的水平。
  • 还包括了一个停止单,以使示例更现实一些(对于纯定向交易),它被设置为低于交易价格的0.5%。
  • 如果出现另一个从下方越过0的MACD信号,并且多头头寸处于打开状态,并且自上次更新此获利以来,至少已经过去了60分钟,那么限制指令将移动到当前价格的0.5%的新水平。(你在问题中没有具体说明如何对时间延迟建模,所以我合理地猜测了你想如何做)。

请注意,更新限制订单的规则类型设置为"risk“,因此在使用ruletype == "order"处理订单之前会评估此自定义规则(如果不清楚,请参阅quantstrat中的applyRules源代码)。这意味着,如果在当前条形上触发了更新限价指令的信号,并且如果价格碰巧也触及了现有的获利限制指令,那么头寸将不会退出并获利,而是会更新到新的获利水平。(因为处理是否触发获利限制指令是在我们检查是否触发了更新限价指令的信号之后进行的)。

我希望这个例子能帮助我们了解定制规则是如何让生活变得更容易的。

代码语言:javascript
复制
library(quantstrat)

from <- "2002-10-20"
to <- "2002-10-24"

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 <- "switchOrderSignal"
portfolio.st <- "switchOrderSignal"
account.st <- "switchOrderSignal"

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"

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"
)


add.signal(strategy.st,name="sigThreshold",
           arguments = list(column="signal.co",
                            relationship="lt",
                            threshold=0,
                            cross=TRUE),
           label="signal.lt.zero"
)

add.rule(strategy.st,name='ruleSignal', 
         arguments = list(sigcol="signal.gt.zero",
                          sigval=TRUE, 
                          orderqty=tradeSize, 
                          ordertype='market', 
                          orderside='long', 
                          osFUN = "osMaxPos",
                          threshold=NULL),
         type='enter',
         label='enterL',
         storefun=FALSE
)

targetThres <- 0.0025
add.rule(strategy.st,name='ruleSignal', 
         arguments = list(sigcol="signal.gt.zero",
                          sigval=TRUE, 
                          orderqty="all", 
                          ordertype='limit', 
                          orderside='long', 
                          threshold= targetThres,
                          tmult = TRUE,
                          orderset='sysMACD',
                          replace = FALSE),
         type='chain',
         label='profitTarget',
         parent = "enterL"
)



# 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',
#          enable = FALSE
# )

stopThreshold <- 0.005
add.rule(strategy.st,name='ruleSignal', 
         arguments = list(sigcol="signal.gt.zero", 
                          sigval=TRUE, 
                          orderqty='all', 
                          ordertype='stoptrailing', 
                          orderside='long', 
                          threshold=-stopThreshold, 
                          tmult=TRUE, 
                          orderset='sysMACD',
                          replace = FALSE),
         type='chain', 
         parent='enterL', 
         label='movingStop')

# If a position is on, update the limit order price (the take profit) if another
# entry signal is fired (macd signal crosses above 0 again), but only if more
# than the holding.period.secs has passed.  Define a custom rule function to handle this logic:

update_profit_target <- 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='',
                                 holding.period.secs
) {

  # First, we do not process this "ruleSignal" function if the position quantity
  # is not 0, because its purpose is only to modify the stoptrailing on a
  # position already open:
  if (ruletype!='risk' || getPosQty(portfolio.st, symbol, timestamp) == 0) {
    return()
  }

  if(hasArg(curIndex))
    curIndex <- eval(match.call(expand.dots=TRUE)$curIndex, parent.frame())
  else
    curIndex <- mktdata[timestamp,which.i=TRUE]

  if(hasArg(prefer)) prefer=match.call(expand.dots=TRUE)$prefer
  else prefer = NULL


  if (!is.na(mktdata[curIndex,sigcol]) && mktdata[curIndex,sigcol] == sigval) {

    #browser()
    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="limit", 
                    side = orderside,
                    which.i = TRUE)
    if (length(ii) > 0) {
      # Check first condition, that a specific amount of time has passed:
      end.of.holding <- index(ordersubset[ii, ]) + holding.period.secs
      if (timestamp < end.of.holding) return()

      if (length(ii) > 1) 
        stop("Have not got logic for handling case with more than one open limit order on orderside of the open position.")

      ordersubset[ii, "Order.Status"] <- 'replaced' 
      ordersubset[ii, "Order.StatusTime"] <- format(timestamp, "%Y-%m-%d %H:%M:%S")

      price <- mktdata[curIndex, "Close"]

      orderSide <- ordersubset[ii,"Order.Side"]
      # Calculate the new limit order price:
      if(isTRUE(tmult))
      {
        threshold = price*threshold
        if (orderSide == "long" && threshold < 0)
          threshold <- -threshold
        else if (orderSide == "Short" && threshold > 0)
          threshold <- -threshold
      }

      price <- price + 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"],
                           price= price - threshold,
                           ordertype="limit",
                           prefer=prefer,
                           side=ordersubset[ii,"Order.Side"],
                           threshold = threshold,
                           status="open",
                           replace=FALSE, 
                           return=TRUE,
                           orderset=ordersubset[ii,"Order.Set"],
                           label=label,
                           ...=..., 
                           TxnFees=TxnFees)
      # ^ Do not 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 = 'update_profit_target', 
         arguments = list(sigcol="signal.gt.zero", 
                          sigval=TRUE, 
                          orderqty='all', 
                          ordertype='limit', 
                          orderside='long', 
                          threshold=targetThres,
                          tmult=TRUE, 
                          orderset='sysMACD',
                          # Set the minimum amount of time that must pass before the current active limit order can be updated again:
                          holding.period.secs = 3600),
         # Setting type as risk means we will update the limit order price on the current bar before processing whether the take profit price (limit price) was touched on this bar.
         type = 'risk',  # process and update this order after processing whether the trailing stop was touched, any chain exit and entry orders
         label='movingProfitTarget')


out<-applyStrategy(strategy.st, portfolios=portfolio.st, verbose=TRUE)

tx <- getTxns(portfolio.st, "GBPUSD")

sum(tx$Net.Txn.Realized.PL)

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.0000
# 2002-10-20 21:31:00    1000  1.547700        0  1547.700     1.547700              0.0000
# 2002-10-21 05:10:00   -1000  1.542361        0 -1542.361     1.542361             -5.3385
# 2002-10-21 06:22:00    1000  1.542600        0  1542.600     1.542600              0.0000
# 2002-10-22 22:39:00   -1000  1.548863        0 -1548.862     1.548863              6.2625
# 2002-10-22 23:40:00    1000  1.549000        0  1549.000     1.549000              0.0000
# 2002-10-24 09:28:00   -1000  1.552271        0 -1552.271     1.552271              3.2710
# 2002-10-24 11:33:00    1000  1.554200        0  1554.200     1.554200              0.0000

ob <- getOrderBook(portfolio.st)

# Print part of the order book:
ob$switchOrderSignal$GBPUSD[1:20, ]

#                            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 "all"     "1.55156925" "limit"        "long"     "0.00386925"    "replaced"   "2002-10-20 23:38:00" ""     "sysMACD" "0"      "profitTarget"       ""           
# 2002-10-20 21:31:00.00010 "all"     "1.5399615"  "stoptrailing" "long"     "-0.0077385"    "replaced"   "2002-10-20 21:33:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-20 21:33:00.00001 "all"     "1.5400615"  "stoptrailing" "long"     "-0.0077385"    "replaced"   "2002-10-20 21:34:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-20 21:34:00.00001 "all"     "1.5403615"  "stoptrailing" "long"     "-0.0077385"    "replaced"   "2002-10-20 22:03:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-20 22:03:00.00001 "all"     "1.5404615"  "stoptrailing" "long"     "-0.0077385"    "replaced"   "2002-10-20 22:06:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-20 22:06:00.00001 "all"     "1.5408615"  "stoptrailing" "long"     "-0.0077385"    "replaced"   "2002-10-20 22:20:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-20 22:20:00.00001 "all"     "1.5409615"  "stoptrailing" "long"     "-0.0077385"    "replaced"   "2002-10-20 22:23:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-20 22:23:00.00001 "all"     "1.5413615"  "stoptrailing" "long"     "-0.0077385"    "replaced"   "2002-10-20 22:24:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-20 22:24:00.00001 "all"     "1.5416615"  "stoptrailing" "long"     "-0.0077385"    "replaced"   "2002-10-20 22:25:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-20 22:25:00.00001 "all"     "1.5418615"  "stoptrailing" "long"     "-0.0077385"    "replaced"   "2002-10-20 22:26:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-20 22:26:00.00001 "all"     "1.5423615"  "stoptrailing" "long"     "-0.0077385"    "closed"     "2002-10-21 05:10:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-20 23:38:00.00001 "all"     "1.55277225" "limit"        "long"     "0.00387225"    "replaced"   "2002-10-21 01:58:00" ""     "sysMACD" "0"      "movingProfitTarget" ""           
# 2002-10-21 01:58:00.00001 "all"     "1.551469"   "limit"        "long"     "0.003869"      "replaced"   "2002-10-21 03:09:00" ""     "sysMACD" "0"      "movingProfitTarget" ""           
# 2002-10-21 03:09:00.00001 "all"     "1.5508675"  "limit"        "long"     "0.0038675"     "canceled"   "2002-10-21 05:10:00" ""     "sysMACD" "0"      "movingProfitTarget" ""           
# 2002-10-21 06:21:00.00010 "1000"    "1.5427"     "market"       "long"     NA              "closed"     "2002-10-21 06:22:00" ""     NA        "0"      "enterL"             ""           
# 2002-10-21 06:22:00.00010 "all"     "1.5464565"  "limit"        "long"     "0.0038565"     "replaced"   "2002-10-21 08:46:00" ""     "sysMACD" "0"      "profitTarget"       ""           
# 2002-10-21 06:22:00.00010 "all"     "1.534887"   "stoptrailing" "long"     "-0.007713"     "replaced"   "2002-10-21 07:01:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-21 07:01:00.00001 "all"     "1.534987"   "stoptrailing" "long"     "-0.007713"     "replaced"   "2002-10-21 07:02:00" ""     "sysMACD" "0"      "movingStop"         ""           
# 2002-10-21 07:02:00.00001 "all"     "1.535387"   "stoptrailing" "long"     "-0.007713"     "replaced"   "2002-10-21 07:04:00" ""     "sysMACD" "0"      "movingStop"         ""    

# Reasonablness checks:  Let's check the results make sense.  Consider first trade entered at 2002-10-20 21:30:00.  Here is what the signals look like after the trade has been on for 2 hours:

mktdata["2002-10-20 23:36/2002-10-21 00:10"]

#                       Open   High    Low  Close Volume       macd.co     signal.co signal.gt.zero signal.lt.zero
# 2002-10-20 23:36:00 1.5489 1.5492 1.5489 1.5492      0  1.414846e-03 -9.644645e-04              0              0
# 2002-10-20 23:37:00 1.5492 1.5492 1.5492 1.5492      0  3.160196e-03 -1.395325e-04              0              0
# 2002-10-20 23:38:00 1.5489 1.5489 1.5489 1.5489      0  2.946509e-03  4.776759e-04              1              0  **
# 2002-10-20 23:39:00 1.5489 1.5489 1.5489 1.5489      0  2.745513e-03  9.312433e-04              0              0
# 2002-10-20 23:40:00 1.5488 1.5488 1.5488 1.5488      0  2.041720e-03  1.153339e-03              0              0
# 2002-10-20 23:41:00 1.5487 1.5487 1.5487 1.5487      0  9.520094e-04  1.113073e-03              0              0
# 2002-10-20 23:42:00 1.5487 1.5487 1.5487 1.5487      0  8.738715e-05  9.079357e-04              0              0
# 2002-10-20 23:43:00 1.5487 1.5487 1.5487 1.5487      0 -5.910279e-04  6.081430e-04              0              0
# 2002-10-20 23:44:00 1.5484 1.5484 1.5484 1.5484      0 -2.661021e-03 -4.568975e-05              0              1
# 2002-10-20 23:45:00 1.5484 1.5484 1.5484 1.5484      0 -4.252555e-03 -8.870627e-04              0              0
# 2002-10-20 23:46:00 1.5485 1.5485 1.5485 1.5485      0 -4.935972e-03 -1.696845e-03              0              0
# 2002-10-20 23:47:00 1.5484 1.5484 1.5484 1.5484      0 -5.930296e-03 -2.543535e-03              0              0
# 2002-10-20 23:48:00 1.5484 1.5484 1.5484 1.5484      0 -6.641779e-03 -3.363184e-03              0              0
# 2002-10-20 23:49:00 1.5483 1.5483 1.5483 1.5483      0 -7.638686e-03 -4.218284e-03              0              0
# 2002-10-20 23:50:00 1.5483 1.5483 1.5483 1.5483      0 -8.332735e-03 -5.041174e-03              0              0
# 2002-10-20 23:51:00 1.5483 1.5483 1.5483 1.5483      0 -8.781583e-03 -5.789256e-03              0              0
# 2002-10-20 23:52:00 1.5483 1.5483 1.5483 1.5483      0 -9.033199e-03 -6.438045e-03              0              0
# 2002-10-20 23:53:00 1.5483 1.5483 1.5482 1.5482      0 -9.642596e-03 -7.078955e-03              0              0
# 2002-10-20 23:54:00 1.5485 1.5486 1.5485 1.5486      0 -7.949460e-03 -7.253056e-03              0              0
# 2002-10-20 23:55:00 1.5486 1.5486 1.5486 1.5486      0 -6.532340e-03 -7.108913e-03              0              0
# 2002-10-20 23:56:00 1.5486 1.5486 1.5486 1.5486      0 -5.347620e-03 -6.756654e-03              0              0
# 2002-10-20 23:57:00 1.5486 1.5486 1.5486 1.5486      0 -4.358482e-03 -6.277020e-03              0              0
# 2002-10-20 23:58:00 1.5486 1.5486 1.5486 1.5486      0 -3.533847e-03 -5.728385e-03              0              0
# 2002-10-20 23:59:00 1.5489 1.5492 1.5489 1.5492      0  2.432916e-04 -4.534050e-03              0              0
# 2002-10-21 00:00:00 1.5492 1.5492 1.5492 1.5492      0  3.199644e-03 -2.987311e-03              0              0
# 2002-10-21 00:01:00 1.5493 1.5493 1.5493 1.5493      0  5.994337e-03 -1.190982e-03              0              0
# 2002-10-21 00:02:00 1.5493 1.5493 1.5492 1.5492      0  7.600410e-03  5.672967e-04              1              0 **
# 2002-10-21 00:03:00 1.5492 1.5492 1.5492 1.5492      0  8.772034e-03  2.208244e-03              0              0
# 2002-10-21 00:04:00 1.5491 1.5491 1.5491 1.5491      0  9.074934e-03  3.581582e-03              0              0
# 2002-10-21 00:05:00 1.5490 1.5490 1.5490 1.5490      0  8.693797e-03  4.604025e-03              0              0
# 2002-10-21 00:06:00 1.5490 1.5490 1.5490 1.5490      0  8.296106e-03  5.342441e-03              0              0
# 2002-10-21 00:07:00 1.5489 1.5489 1.5489 1.5489      0  7.374970e-03  5.748947e-03              0              0
# 2002-10-21 00:08:00 1.5488 1.5488 1.5488 1.5488      0  6.054223e-03  5.810002e-03              0              0
# 2002-10-21 00:09:00 1.5487 1.5487 1.5487 1.5487      0  4.435429e-03  5.535087e-03              0              0
# 2002-10-21 00:10:00 1.5488 1.5488 1.5487 1.5487      0  3.116584e-03  5.051387e-03              0              0

#  See that the limit order was updated on a `signal.gt.zero` signal fired at 2002-10-20
#  23:38:00. Then you can see there was another `signal.gt.zero``  signal at 2002-10-21 00:02:00
#  which, as expected, did not result in updating the limit order again.  The limit
#  order updates at 2002-10-21 01:58:00, 2 hours and 20 minutes after the previous limit order update (at 2002-10-20 23:38:00).
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38900239

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档