quantstrat回测时如何获取最新权益更新交易规模参数
quantstrat动态获取账户权益更新仓位失效修复
问题原因
你写的tradeSize=quote(last(getEndEq(acct,Date = timestamp)))不生效,核心是三个问题:
- 原生
osDollarATR不会对传入的tradeSize做逐bar动态求值,quote()包裹的表达式只会在规则初始化阶段执行一次,拿不到回测过程中实时变动的账户权益。 - 表达式里的
timestamp没有绑定到信号触发时的当前bar时间上下文,直接调用会出现取值错误,导致getEndEq返回结果不对。 tradeSize是osDollarATR的入参,不属于ruleSignal的原生参数,你把它写在ruleSignal的参数根层级,传递时会出现作用域丢失,os函数根本拿不到这个参数。
修复方案
不要硬在规则参数里塞延迟求值表达式,直接自定义一个适配动态权益的ATR订单大小函数,逻辑和原生osDollarATR完全对齐,只是把固定tradeSize改成逐bar取最新账户权益:
# 自定义适配动态账户权益的ATR美元仓位计算函数 osDollarATR_DynamicEq <- function(timestamp, orderqty, portfolio, symbol, acctname, pctATR, atrMod="X", TxnFees=0, ...) { # 获取当前信号时点的最新账户总资产 current_total_eq <- as.numeric(last(getEndEq(Acct = acctname, Date = timestamp))) # 读取当前bar的ATR指标值 atr_col_name <- paste0("atr", atrMod) current_atr_val <- as.numeric(mktdata[timestamp, atr_col_name]) # 获取当前持仓 current_pos <- getPosQty(Portfolio = portfolio, Symbol = symbol, Date = timestamp) # 计算目标仓位 逻辑和原生osDollarATR一致 target_position <- (pctATR * current_total_eq) / current_atr_val # 输出实际下单数量 if (is.character(orderqty) && orderqty == "all") { return(-current_pos) } if (orderqty > 0) { return(floor(target_position) - current_pos) } else { return(-ceiling(target_position) - current_pos) } }
之后修改你原来的开仓规则代码,替换osFUN为自定义函数,删掉原来无效的tradeSize传参,补上账户名参数即可:
# long entry add.rule(strat,name = "ruleSignal", arguments = list(sigcol='EntryLongSig', sigval=TRUE, orderside='long', ordertype='market', osFUN=osDollarATR_DynamicEq, acctname = acct, # 传入你初始化账户时用的账户名字符串 pctATR=pctATR, TxnFees=-300, replace=FALSE, prefer='Close', atrMod='X'), type = 'enter',enabled = TRUE, label = "enterLong")
注意:运行前确认你已经正确完成账户、组合的初始化,
acct变量存储的是你初始化时设置的账户名字符串,函数里用到的mktdata是quantstrat规则执行时自动注入的上下文变量,不需要手动赋值。
内容的提问来源于stack exchange,提问作者yangzhuogo
相关产品推荐
相关产品推荐

