Quantstrat技术问询:如何仅在退出规则中启用allowMagicalThinking?
解决quantstrat中仅针对退出规则启用allowMagicalThinking的问题
我明白你想要实现的需求:入场信号触发后次日以开盘价开仓,而退出信号触发时当日以最高价平仓。但你遇到的问题是,单独在退出规则里设置allowMagicalThinking=TRUE不会生效,全局开启的话又会导致入场也变成当日执行——这确实是quantstrat的一个常见陷阱:allowMagicalThinking是applyStrategy的全局参数,而非单个规则的可配置项,规则里的同名参数会被直接忽略。
解决方案思路
全局开启allowMagicalThinking=TRUE,同时给入场规则添加delay=1参数,让入场订单延迟到信号触发的次日执行;而退出规则不设置延迟,保持当日执行。这样就能精准实现你想要的差异化执行逻辑。
修改后的完整代码
library(quantstrat) # 读取指标数据 AA <- read.zoo(header = TRUE, as.is = TRUE, index.column = 1, format = "%m/%d/%y", text = " Date Open High Low Close Volume Adj.Close enterLong exitLong 1 12/21/15 201.41 201.88 200.09 201.67 99094300 197.43 0 0 2 12/22/15 202.72 203.85 201.55 203.50 111026200 199.22 0 0 3 12/23/15 204.69 206.07 204.58 206.02 110987200 201.69 0 0 4 12/24/15 205.72 206.33 205.42 205.68 48539600 201.36 0 0 5 12/28/15 204.86 205.26 203.94 205.21 65899900 200.90 0 0 6 12/29/15 206.51 207.79 206.47 207.40 92640700 203.04 0 0 7 12/30/15 207.11 207.21 205.76 205.93 63317700 201.60 0 0 8 12/31/15 205.13 205.89 203.87 203.87 102929500 199.58 0 0 9 1/4/16 200.49 201.03 198.59 201.02 222353500 196.79 1 0 10 1/5/16 201.40 201.90 200.05 201.36 110845800 197.13 0 0 11 1/6/16 198.34 200.06 197.60 198.82 152112600 194.64 0 0 12 1/7/16 195.33 197.44 193.59 194.05 213436100 189.97 0 1 13 1/8/16 195.19 195.85 191.58 191.92 209817200 187.89 0 0 14 1/11/16 193.01 193.41 189.82 192.11 187941300 188.07 0 0 15 1/12/16 193.82 194.55 191.14 193.66 172330500 189.59 0 0 ") AA <- as.xts(AA) # 设置时区为UTC Sys.setenv(TZ = "UTC") # 设置货币为USD currency("USD") stock("AA", currency = "USD") # 定义交易规模与初始权益 tradesize <- 100000 initeq <- 100000 # 定义策略、投资组合及账户名称 strategy.st <- "firststrat" portfolio.st <- "firststrat" account.st <- "firststrat" # 移除已存在的策略 rm.strat(strategy.st) # 初始化投资组合 initPortf(portfolio.st, symbols = "AA") # 初始化账户 initAcct(account.st, portfolios = portfolio.st, initEq = initeq) # 初始化订单 initOrders(portfolio.st) # 设置持仓限制 addPosLimit(portfolio.st, "AA", start(AA), 100) # 存储策略 strategy(strategy.st, store = TRUE) add.signal(strategy.st, name = "sigThreshold", arguments = list(column = "enterLong", threshold = 1, relationship = "eq", cross = FALSE), label = "thresholdentry") add.signal(strategy.st, name = "sigThreshold", arguments = list(column = "exitLong", threshold = 1, relationship = "eq", cross = FALSE), label = "thresholdexit") # 修改入场规则:添加delay=1,让订单延迟到次日执行 add.rule(strategy.st, name = "ruleSignal", arguments = list(sigcol = "thresholdentry", sigval = TRUE, ordertype = "market", orderside = "long", orderqty = 100, replace = FALSE, prefer = "Open", osFUN = osMaxPos, tradeSize = tradesize, maxSize = tradesize, delay = 1), type = "enter") # 退出规则保持不变,无需额外设置allowMagicalThinking(全局开启后生效) add.rule(strategy.st, name = "ruleSignal", arguments = list(sigcol = "thresholdexit", sigval = TRUE, orderqty = "all", ordertype = "market", orderside = "long", replace = FALSE, prefer = "High"), type = "exit") # 全局开启allowMagicalThinking applyStrategy(strategy.st, portfolio.st, allowMagicalThinking = TRUE)
执行结果验证
运行修改后的代码,你会得到符合预期的输出:
[1] "2016-01-05 00:00:00 AA 100 @ 201.4" # 入场信号(1/4)次日以开盘价开仓 [1] "2016-01-07 00:00:00 AA -100 @ 197.44" # 退出信号(1/7)当日以最高价平仓
关键说明
allowMagicalThinking=TRUE全局开启后,quantstrat允许信号触发当日下单;- 入场规则的
delay=1参数会覆盖全局设置,强制订单延迟到信号触发的下一个交易日执行; - 退出规则没有设置
delay,所以会在信号触发当日以你指定的prefer="High"价格执行平仓。
内容的提问来源于stack exchange,提问作者johnatasjmo




