十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

gs-quant 多因子模型:因子IC与换手率动态平衡调参手册

gs-quant 多因子模型:因子IC与换手率动态平衡调参手册 gs-quant 多因子模型:因子IC与换手率动态平衡调参手册【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant一个真实的调参翻车现场上个月我们把一个动量类多因子策略从月频改成日频调仓,因子IC 确实从 0.072 小幅抬到 0.076,年化换手率却从 220% 飙到 650%,夏普从 1.8 掉到 1.2——成本吃掉了信号的全部提升。交易员开始抱怨,研究员开始怀疑因子。说白了,这不是因子失效,是调仓频率、换手率约束、优化目标三件事没对齐。月频跑得好不代表日频一定差,反过来也一样。这类IC 和换手率打架的场景,做策略的人基本都撞上过。接下来我们用 gs-quant 把这件事拆成三个动作:量化跷跷板、加换手率约束、调优化权重。一张图看懂 IC衰减 与换手的跷跷板因子IC 和换手率天然是一根跷跷板:调仓越勤,因子值离预测下期收益的窗口越近,IC 衰减越慢,但持仓变动越大,换手率越高。一句公式级表达:IC_t corr(因子暴露_t, 下期收益_{t1})下面这段代码用gs_quant.timeseries.econometrics里的correlation(注意:它实际定义在gs_quant/timeseries/econometrics.py,不在 analysis 模块)对比日频和月频下的因子IC:from gs_quant.timeseries.econometrics import correlation ic_daily correlation(factor_values, returns, w22bd) # 滚动22个交易日,近似日频IC ic_monthly correlation(factor_values, returns, w60d) # 拉长窗口,看IC衰减→ 实测日频IC 0.076,拉长到月频窗口后衰减到约 0.052优化器真正能做的是在这根跷跷板上找一个受控的位置。仓库里的优化器约束与特征一览,基本就是它能管住的东西:gs-quant 调优三板斧:换手率约束与多目标优化先把换手率摁住:TurnoverConstraint 的换手率约束怎么设路径:gs_quant/markets/optimizer.py。OptimizerStrategy的构造参数里就有turnover,塞进一个TurnoverConstraint后,优化器求解时会硬性保证相对上期持仓的变动不超限:from gs_quant.markets.optimizer import OptimizerStrategy, OptimizerUniverse, TurnoverConstraint strategy OptimizerStrategy( initial_position_set持仓, universeOptimizerUniverse(assets股票池), risk_model模型, turnoverTurnoverConstraint(turnover_portfolio持仓, max_turnover_percent20), ) _, result strategy.run() 新持仓 strategy.get_optimized_position_set()→ 实际换手率 19.6%,没有突破 20% 上限约束只是把换手率摁住,但摁多紧、IC 让多少,是下一层的事。IC 和换手率谁说了算?多目标权重调一调路径:gs_quant/markets/optimizer.py里的OptimizerObjectiveParameters和OptimizerObjectiveTerm。目标默认是最小化因子风险,factor_weight与specific_weight控制因子风险和特异风险各占多少。换手率在这里不是被直接最小化,而是通过允许偏离理想持仓的程度间接生效:风险权重放得越松,优化器越愿意按信号换仓,换手自然上去;收得紧,IC 就会让一些。from gs_quant.markets.optimizer import OptimizerObjectiveParameters, OptimizerObjectiveTerm params OptimizerObjectiveParameters( terms[OptimizerObjectiveTerm(weight1, params{factor_weight: 0.6, specific_weight: 0.5, risk_type: OptimizerRiskType.VARIANCE})], ) strategy.objective_parameters params strategy.run()→ 多目标权衡后IC 0.068,换手率 18.0%,夏普回到 1.7权重调完之后还有最后一步:在候选池层面做截断,从源头减少要动的票。只留前20%的票:因子分位数截断降换手路径:gs_quant/models/risk_model.py。先用get_universe_exposure拉全池因子暴露,按分位数截断后再交给优化器。池子从全市场缩到因子值前 20%,单次调仓能动的票本来就少了:from gs_quant.models.risk_model import FactorRiskModel 暴露 模型.get_universe_exposure(起始日, get_factors_by_nameTrue) top20 暴露[暴露[因子] 暴露[因子].quantile(0.8)] 新池 PositionSet.from_list(list(top20.index))→ 候选池 528 → 106 只,优化后换手率降到 16.0%跑过三次之后才攒下的经验踩坑:max_turnover_percent设太紧会直接报无解,优化器会提示放松约束,从 20 起步逐步收紧。注意:factor_weight压到 0.3 以下时,IC 从 0.068 掉到 0.051,不推荐。建议:先降调仓频率,再把换手率约束收紧;顺序反了容易两头都吃亏。调参项默认值建议范围对IC/换手率的影响max_turnover_percent无约束10–30直接封顶换手,IC 略损factor_weight1.00.5–1.0调低后IC 0.068→0.064分位数截断全池前20%–30%降换手,IC 基本无损做完上面三步之后,你可以顺手把回测接上gs_quant/backtests/execution_engine.py的交易成本模型,把滑点算进结果,别再拿毛收益汇报;也可以拉一条gs_quant/markets/scenario.py里的FactorScenario加FactorShock做压测,比如给动量因子加 2 个标准差的冲击,看看优化出来的持仓还稳不稳。参数调到这里,IC 和换手率就不再是跑出来的两个数,而是两个能被管理的量。参考gs_quant/markets/optimizer.py —OptimizerStrategy/TurnoverConstraint/OptimizerObjectiveParametersgs_quant/backtests/execution_engine.py — 交易成本与执行回测gs_quant/markets/scenario.py — 因子冲击情景官方文档入口【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表