简体   繁体   English

当orderPrice在quantstrat中高于/低于收盘价时止损订单?

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

I am trying put a stoplimit order to close my position when a specific order price crosses above or below the Close of the candle.当特定订单价格高于或低于蜡烛收盘价时,我正在尝试设置止损订单以关闭我的 position。

My rule function as follows:我的规则 function 如下:

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)

I tried to change the related part in source file of ruleOrderProc.R:我尝试更改 ruleOrderProc.R 源文件中的相关部分:

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

to

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

And I also tried to add "prefer" argument to my rule but it didn't work.而且我还尝试在我的规则中添加“首选”参数,但没有奏效。 Rule still triggers according to Low/High prices of the bar.规则仍然根据柱的低/高价格触发。

Thank you.谢谢你。

Edit for a minimum reproducible example:编辑一个最小可重现的例子:

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)

When we look at the last transaction closed by stop-loss rule, "Close" price of the bar is not below my stop-loss order price which is 47.13 although I add prefer="Close" argument to my stoplimit rule:当我们查看通过止损规则关闭的最后一笔交易时,柱的“平仓”价格不低于我的止损订单价格 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

Normally, I expect that the position should not be closed until the end of the dataset.通常,我希望 position 不应该在数据集结束之前关闭。

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

You need to make one more modification in rules.R (on approximately lines 580-590), setting posQty and negQty to the close prices for the stoplimit order type (instead of High and Low prices):您需要在 rules.R 中再做一次修改(大约在第 580-590 行),将posQtynegQty设置为stoplimit订单类型的收盘价(而不是 High 和 Low 价格):

  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

This section of the rules.R code is about speeding up the simulation by only checking rows of the market data where there might be an update to an open order.规则的这一部分。R 代码是关于通过仅检查可能对未结订单进行更新的市场数据行来加速模拟。 So what you are doing by making this change is effectively saying, find all the rows where the Close price (as opposed to the Low price) for a long stop limit order might cross (below) the stop order price.因此,您通过进行此更改所做的实际上是在说,找到多头止损限价单的收盘价(相对于最低价)可能与止损单价格交叉(低于)的所有行。

With this change the stop order is not triggered on 2018-07-30.通过此更改,止损单不会在 2018 年 7 月 30 日触发。

Note that if you go through the code carefully in rules.R you'll see prefer="Close" does not matter in finding the market data rows where the stoplimit might be triggered.请注意,如果您仔细检查 rules.R 中的代码 go,您将看到在查找可能触发止损限价的市场数据行时, prefer="Close"无关紧要。 prefer can come into play when you're not working with OHLC bar data.当您不使用 OHLC 条形数据时, prefer可以发挥作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM