如何在quantstrat布林带策略中优化最大仓位限制maxpos
解决quantstrat中maxpos参数优化的问题
你的核心问题是addPosLimit不属于策略(strategy)的组件,所以无法通过add.distribution直接针对它做参数优化。因为add.distribution只能优化策略内部的组件(比如指标、信号、规则、参数),而addPosLimit是给投资组合(portfolio)设置静态仓位限制,和策略是分离的。
下面是两种可行的优化方案:
方案一:将maxpos作为策略参数,通过自定义osFUN实现动态仓位限制
这种方法把仓位限制逻辑整合到策略规则中,让maxpos成为策略的可优化参数:
步骤1:移除全局的addPosLimit调用
删掉代码中的这一行:
addPosLimit(portfName, symbol, timestamp=initDate, maxpos=maxpos, minpos=0)
步骤2:给策略添加maxpos参数
在创建策略后,添加可优化的参数:
strategy(name = stratName, store=TRUE) # 添加maxpos参数,设置默认值 add.parameter(strategy = stratName, name = "maxpos", default = 5000)
步骤3:自定义仓位限制函数(osFUN)
这个函数会根据当前仓位和maxpos参数,计算实际可下单的数量:
osMaxPosCustom <- function(orderqty, portfolio, symbol, ruletype, ...) { # 获取当前策略的maxpos参数 strat_params <- getStrategy(portfolio)$parameters maxpos <- strat_params$maxpos # 获取当前持仓数量 current_pos <- getPos(portfolio, symbol)$pos # 计算目标持仓 target_pos <- current_pos + orderqty # 限制目标持仓不超过maxpos(多空都限制) if (target_pos > maxpos) { orderqty <- maxpos - current_pos } else if (target_pos < -maxpos) { orderqty <- -maxpos - current_pos } return(orderqty) }
步骤4:修改规则中的osFUN为自定义函数
把原来规则里的osFUN=osMaxPos替换成osFUN=osMaxPosCustom:
add.rule(strategy = stratName, name='ruleSignal', arguments=list(sigcol="Cl.gt.UpperBand",sigval=TRUE, orderqty=-nShs, ordertype='market', orderside=NULL, osFUN=osMaxPosCustom ),type='enter', label = "Enter.Short") add.rule(strategy = stratName, name='ruleSignal', arguments=list(sigcol="Cl.lt.LowerBand",sigval=TRUE, orderqty=nShs, ordertype='market', orderside=NULL, osFUN=osMaxPosCustom ),type='enter', label = "Enter.Long")
步骤5:用add.distribution优化策略参数
现在可以针对策略的maxpos参数做优化了:
.maxpos = seq(3000,8000,1000) add.distribution(stratName, paramset.label = 'PosOpt', component.type = 'parameter', component.label = 'maxpos', variable = list(maxpos = .maxpos), label = 'MaxPos')
方案二:在优化循环中动态设置addPosLimit
如果一定要保留addPosLimit的使用,可以手动遍历maxpos的取值,每次迭代重新初始化投资组合并设置对应的仓位限制:
.maxpos = seq(3000,8000,1000) results_list <- list() for (pos in .maxpos) { # 重置策略和账户 suppressWarnings(rm.strat(stratName)) initPortf(name = portfName, symbols = symbol, initDate = initDate, currency = 'USD') initAcct(name = acctName, portfolios = portfName, initDate=initDate, initEq=initEq) initOrders(portfolio = portfName, initDate = initDate) # 重新创建策略并添加组件 strategy(name = stratName, store=TRUE) # (这里复制原来的add.indicator、add.signal、add.rule代码) # 设置当前迭代的仓位限制 addPosLimit(portfName, symbol, timestamp=initDate, maxpos=pos, minpos=0) # 运行策略 out <- applyStrategy(strategy=stratName, portfolios=portfName) updatePortf(portfName) updateAcct(acctName) updateEndEq(acctName) # 保存结果 perf <- getPerformance(acctName) results_list[[as.character(pos)]] <- perf } # 后续可以对比不同maxpos的绩效
这种方法不需要修改策略逻辑,但代码冗余度高,运行效率较低,适合简单的优化场景。
内容的提问来源于stack exchange,提问作者Amethyst Feng
相关产品推荐
相关产品推荐

