Stoplimit order when orderPrice crosses above/below quantstrat 中柱线收盘?

Stoplimit order when orderPrice crosses above/below Close of the bar in quantstrat?

我正在尝试设置止损限价单以在特定订单价格高于或低于蜡烛收盘价时平仓。

我的规则功能如下:

add.rule(strategy = strategy.st, name = "ruleSignal",arguments = 
list(sigcol = "lenter", sigval = TRUE,TxnFees="fee",replace = FALSE, 
orderside = "long", TxnFees = "fee", ordertype = "stoplimit", 
orderqty = "all", tmult = TRUE, order.price=quote(myprice), 
orderset="ocolong", prefer="Close"), type = "chain", parent = 
"longbuy", path.dep=TRUE, label = "stop_loss_long", enabled=TRUE)

我试图更改 ruleOrderProc.R 源文件中的相关部分:

if ((orderQty > 0 && orderType != "stoplimit") || 
            (orderQty < 0 && (orderType == "stoplimit"))) {
            if ((has.Lo(mktdata) && orderPrice > 
as.numeric(Lo(mktdataTimestamp)[, 
              1])) 

 if ((orderQty > 0 && orderType != "stoplimit") || 
            (orderQty < 0 && (orderType == "stoplimit"))) {
            if ((has.Cl(mktdata) && orderPrice > 
as.numeric(Cl(mktdataTimestamp)[, 
              1]))

而且我还尝试在我的规则中添加“首选”参数,但没有成功。规则仍然根据柱的 Low/High 价格触发。

谢谢。

编辑最小可重现示例:

library(quantstrat)

start_date <- as.Date("2018-02-02")
end_date <- as.Date("2018-09-24")
init_date <- as.Date("2018-01-01")
init_equity <- "50000"
adjustment <- TRUE
symbol <- "AAPL"


getSymbols(symbol, src = "yahoo",
       from = start_date, to=end_date,
       adjust = adjustment)


portfolio.st <- "basic_port"
account.st <- "basic_account"
strategy.st <- "basic_strategy"


rm.strat(portfolio.st)
rm.strat(account.st)

stock(symbol, currency = currency("USD"), multiplier = 1)
initPortf(name = portfolio.st, symbols = symbol, initDate =init_date)

initAcct(name = account.st, portfolios = portfolio.st, 
         initDate = init_date, initEq =init_equity)
initOrders(portfolio.st, symbol, init_date)
strategy(strategy.st, store = TRUE)



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


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

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

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

#Add rules for entering positions
#enter long position
add.rule(strategy.st, 
         name = "ruleSignal", 
         arguments = list(sigcol = "longenter",
                          sigval = TRUE,
                          orderqty = 100,
                          ordertype = "market",
                          orderside = "long",
                          orderset= "ocolong",
                          prefer = "Close",
                          TxnFees = -.8,
                          replace = FALSE),
         type = "enter",
         label = "EnterLong")



#stoploss long
add.rule(strategy = strategy.st, 
         name = "ruleSignal",
         arguments = list(sigcol = "longenter",
                          sigval = TRUE,
                          TxnFees=-.8,
                          replace = FALSE, 
                          orderside = "long", 
                          ordertype = "stoplimit",
                          orderqty = "all", 
                          tmult = TRUE,
                          prefer = "Close",
         order.price=quote(as.numeric(mktdata$AAPL.Low[timestamp])),
                          orderset="ocolong"), 
         type = "chain", parent = "EnterLong", 
         path.dep=TRUE, 
         label = "stop_loss_long", 
         enabled=TRUE)


#Apply strategy
applyStrategy(strategy.st, portfolios = portfolio.st,debug = TRUE)
updatePortf(portfolio.st)
updateAcct(account.st)
updateEndEq(account.st)

当我们查看按止损规则关闭的最后一笔交易时,柱的“收盘价”不低于我的止损订单价格 47.13,尽管我将 prefer="Close" 参数添加到我的止损限价规则:

mktdata[, 1:4]["2018-07-30"]

           AAPL.Open AAPL.High AAPL.Low AAPL.Close
2018-07-30  47.80733  47.88207 47.10231   47.31158

通常情况下,我希望在数据集结束之前不应该平仓。

sessionInfo()

R version 4.1.1 (2021-08-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19044)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252 
[2] LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    
system code page: 1254

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

other attached packages:
[1] quantstrat_0.16.9          foreach_1.5.1             
[3] blotter_0.15.0             PerformanceAnalytics_2.0.6
[5] FinancialInstrument_1.3.0  quantmod_0.4.18           
[7] TTR_0.24.2                 xts_0.12.1.1              
[9] zoo_1.8-9                 

loaded via a namespace (and not attached):
 [1] magrittr_2.0.1    MASS_7.3-54       tidyselect_1.1.1 
 [4] lattice_0.20-44   R6_2.5.1          quadprog_1.5-8   
 [7] rlang_0.4.11      fansi_0.5.0       dplyr_1.0.7      
[10] tools_4.1.1       grid_4.1.1        data.table_1.14.0
[13] utf8_1.2.2        DBI_1.1.1         iterators_1.0.13 
[16] ellipsis_0.3.2    assertthat_0.2.1  tibble_3.1.4     
[19] lifecycle_1.0.0   crayon_1.4.1      purrr_0.3.4      
[22] codetools_0.2-18  vctrs_0.3.8       curl_4.3.2       
[25] glue_1.4.2        compiler_4.1.1    pillar_1.6.2     
[28] generics_0.1.0    boot_1.3-28       pkgconfig_2.0.3

您需要在 rules.R 中再做一项修改(大约在第 580-590 行),将 posQtynegQty 设置为 close stoplimit 订单类型的价格(而不是最高价和最低价):

  if(is.BBO(mktdata)) {
        mktPrices <- list(
          stoplimit = list(
              posQty = mktdata[,has.Ask(mktdata,which=TRUE)[1]],
              negQty = mktdata[,has.Bid(mktdata,which=TRUE)[1]]),
          limit = list(
              posQty = mktdata[,has.Ask(mktdata,which=TRUE)[1]],
              negQty = mktdata[,has.Bid(mktdata,which=TRUE)[1]]),
          stoptrailing = list(
              posQty = getPrice(mktdata, prefer='offer')[,1],
              negQty = getPrice(mktdata, prefer='bid')[,1]))
    } else if (is.OHLC(mktdata)) {
        mktPrices <- list(
          stoplimit = list(
              posQty = mktdata[,has.Cl(mktdata,which=TRUE)[1]], #modified to the close
              negQty = mktdata[,has.Cl(mktdata,which=TRUE)[1]]), #modified to the close

rules.R 代码的这一部分是关于通过仅检查可能有未结订单更新的市场数据行来加速模拟。因此,您通过进行此更改所做的实际上是在说,找到所有行,其中长期止损限价订单的收盘价(相对于最低价)可能超过(低于)止损订单价格。

通过此更改,停止订单不会在 2018 年 7 月 30 日触发。

请注意,如果您仔细查看 rules.R 中的代码,您会发现 prefer="Close" 在查找可能触发止损限价的市场数据行时并不重要。 prefer 可以在您不使用 OHLC 柱数据时发挥作用。