五福ETF轮动(五福闹新春):动态池、防御与调仓(QMT / PTrade)
五福闹新春是库里 ETF 轮动副本最多的一套(聚宽 / PTrade / QMT 都有 v4.3 对齐版)。和 七星 的差别:七星池子固定、一天换一只;五福用动态三层池,动量用 W² 加权回归,弱市和止损后会切防御 ETF。分数、量比、持仓天数都是示例,不是操作指令。不构成投资建议,不代操盘。
手册:get-market-data-ex · get_history · ss-vs-sh
逻辑简述
- 三层池。宽基 / 特别 / 普通分开,再和固定池、过滤后的动态池合并。成交额太小或新上市的先丢掉。
- 动量。回看约 25 日,W² 加权回归。震荡期会换滤波(拉普拉斯 / 高斯),不是一条直线打到底。
- 调仓。按得分阈值比例分步换仓,不是每天全清。先卖后买,实盘卖完往往要等几十秒到几分钟。
- 防御。候选太少且得分弱,切防御 / 避险 ETF;止损后还会挂一段短防御期。最短持仓日用来减换手。
- 时钟。常见 13:10 选股并卖、13:11 买。选股结果不要挂在
C上,定时器和handlebar可能不是同一个上下文。
QMT 版本
上交所用 .SH。实盘注册 run_time 每 60 秒看一次;回测走分钟 handlebar。日期戳、今日目标列表用模块级变量,不要写在 C 自定义属性上。

客户端回测截图(v3.2 一类)。区间、资金、滑点和成交假设跟你本机不会一样。不是实盘,不能当收益预期,不构成投资建议。
python
#encoding:gbk
def init(C):
A.acct = A.paras.get('acct', '')
A.acct_type = 'STOCK'
if A.acct:
C.set_account(A.acct)
A.lookback_days = 25
A.score_threshold_ratio = 0.9
A.defensive_etf = '511880.SH'
A.safe_haven_etf = '511660.SH'
# 固定池 + 动态池合并,完整名单见附件
if not C.do_back_test:
start = datetime.now().strftime('%Y-%m-%d 09:30:00')
C.run_time('wufu_timer_task', '60nSecond', start)
def wufu_timer_task(C):
# 13:10 打分并卖,13:11 按模块级 _wufu_target_etfs 买
pass买入资金要预留手续费和最小金额。passorder 返回不等于成交。
PTrade 版本
聚宽源码里的 .XSHG / .XSHE 先换成 .SS / .SZ。set_universe 覆盖固定池、动态池、防御和避险。定时常见 09:00 盘前、10:00 早盘卖、13:10 午后选股买入。

客户端回测截图(v4.3,约 2025)。只看曲线形态,不要对收益。不是实盘,不构成投资建议。
python
def initialize(context):
g.defensive_etf = '511880.SS'
g.lookback_days = 25
g.score_threshold_ratio = 0.9
g.fixed_etf_pool = ['518880.SS', '513100.SS'] # 示例
set_universe(g.fixed_etf_pool + [g.defensive_etf])
run_daily(context, morning_routine, time='09:00')
run_daily(context, morning_sell_routine, time='10:00')
run_daily(context, afternoon_routine, time='13:10')
def handle_data(context, data):
pass回测和实盘不要共用状态 json。ETF 限价三位,按股票两位取整会废单。
两边都容易踩的坑
- 五福和七星池子、分数口径不一样,不要把七星的短池直接塞进五福。
- 13:10 的价格要用当时点,不要偷懒拿昨收。
- 弱市切防御之后,最短持仓日没到不要当天再换回来。
- QMT 里
handlebar和run_time各走各的,目标列表必须放模块级。
完整源码见知识星球附件,这里只放逻辑和片段。
完整讨论和附件在 知识星球 Kimi量化研究所。
