周末的提示,不知今天诸君是否安好
做量化的朋友都知道,社区里跑出年化50+%、夏普2.5的回测一抓一大把,但一上实盘,很多“神话”就碎了一地。 为什么?因为回测只是实验室里的真空状态,实盘才是真刀真枪的工程学。
量化圈有个不成文的秘密:从“能跑通的回测代码”,到“敢实盘的交易系统”,中间隔着100个熬夜掉头发的坑。
如果你想少走点弯路,不妨关注一下这个公众号。号主是个普通业余量化玩家,算不上什么大神,也没有多专业多天才。就是平时记录下自己在量化路上踩过的一个个沟沟坎坎,分享出来,希望同路的你,能少掉几根头发。
最近再次研读 @O_iX 大佬的《多策略11:去伪存真,拥抱不择时的核心逻辑》,深感其底层设计的惊艳,代码极其优雅。
但好钢要用在刀刃上。为了让这个神级框架能够 “零缝隙”对接实盘,我花了一周时间对其进行了彻底的“工程化重构”。,咱们不谈故弄玄虚的圣杯,直接把这套 【买卖分离+虚拟账本+绝美可视化】 的实战级框架拆开了讲。更重要的是,我会手把手教你,如何把自己的策略像“搭乐高”一样,拔插式地接入这个顶级框架中。
01 实盘究竟有哪些“天坑”?
如果你把几个独立策略硬生生拼在一个账户里跑,实盘时一定会遇到这三个极其恶心的痛点:
- 资金踩踏(买卖互斥) :买卖同一时间的就不说了,之前框架是这样,回测验证没问题,但并不是特别适合实盘。还有一种多策略,A策略14:50发出买入信号,但B策略14:55才卖出腾出资金。结果就是A策略干瞪眼买不进去,直接错失行情。
- 账本一锅粥:账户总净值回撤了,到底是你的微盘股策略崩了,还是ETF轮动策略在回调?系统自带的持仓面板全混在一起,你根本分不清,最后只能凭感觉盲人摸象。
- 满屏的Warning警告:多策略频繁调仓时,稍微不注意底层逻辑,平台就会疯狂报错“空持仓卖出警告”。虽然不影响交易,但看着实在让人头皮发麻。
02 核心进化:为实盘而生
为了解决以上痛点,我在原版高内聚低耦合的基础上,植入了三大核心机制,将其打造成纯净的实盘底座。
进化一:严格的买卖分离调度(错峰出行)
我把所有的卖出和买入动作在时间轴上彻底割裂。所有策略先集中在11:00-11:03完成卖出清仓,资金回笼后,再在11:05-11:08执行各自的买入指令。
# 框架调度源码截取
if g.portfolio_value_proportion[0] > 0:
run_weekly(jsg_sell, 1, "11:00") # 先统一卖出腾出仓位
run_weekly(jsg_buy, 1, "11:05") # 资金到位再按权重买入
run_daily(jsg_check, "14:55") # 尾盘风控检查
大白话:大家排好队,先下车后上车,谁也别抢谁的座(资金)。
进化二:虚拟子账户与独立账本体系
这是整个框架最硬核的地方。我在底层重写了 order_target_value_ 函数。 所有的下单指令全部经过这个“收费站”。只要成交,系统会立刻拦截结算单,精准扣除手续费,并计算每一笔交易的已实现盈亏,然后分发记录到各自策略的“虚拟账本”中。
# === 核心账本拦截系统 ===
def order_target_value_(self, security, value):
# ... (前置风控拦截:ST/停牌过滤)
if adjustment != 0:
o = order(security, adjustment) # 发起真实交易
# 交易成功后,立刻拦截结算单,更新虚拟账本!
if o is not None and o.filled > 0:
commission_fee = getattr(o, 'commission', 0.0)
if o.is_buy:
g.strategy_realized_pnl[self.index] -= commission_fee
else:
# 卖出产生盈亏:(卖出价 - 成本价) * 数量 - 手续费
realized = (o.price - prev_avg_cost) * o.filled - commission_fee
g.strategy_realized_pnl[self.index] += realized
# ... (更新对应策略的虚拟持仓数量)
从此,四个策略互不干扰,谁赚谁亏一清二楚,每个策略都有自己的“真实权益净值”。并且通过严谨的 if security in positions 拦截,彻底消灭了底层的空持仓Warning报错。
进化三:强迫症福音——高颜值可视化持仓面板
基于虚拟账本,我接入了 PrettyTable。每天15:06收盘后,系统会自动打印一张多层级的持仓收益明细表。 这表有多爽?直接看实盘跑出来的真实效果:
+--------------------------+------------+------------+------------+------------+---------------+--------------+----------------+
| 策略分类/标的代码 | 标的名称 | 持仓数量 | 当前价格 | 持仓成本 | 浮动盈亏(%) | 浮动盈亏(元) | 持仓市值(元) |
+--------------------------+------------+------------+------------+------------+---------------+--------------+----------------+
| ▼ 【搅屎棍策略】 | 当日收益: | -3.21% | 累计收益: | -3.21% | 策略真实权益: | ——> | 29036.00 |
| ├─ 003017.XSHE | 大洋生物 | 200 | 18.290 | 18.960 | -3.53% | -134.00 | 3658.00 |
| ├─ 002205.XSHE | 国统股份 | 500 | 8.650 | 9.030 | -4.21% | -190.00 | 4325.00 |
| ------------------------ | ---------- | ---------- | ---------- | ---------- | ------------ | ------------ | -------------- |
| ▼ 【全天候策略】 | 当日收益: | -0.45% | 累计收益: | -0.45% | 策略真实权益: | ——> | 49776.87 |
| ├─ 511010.XSHG | 国债ETF | 100 | 141.411 | 141.561 | -0.11% | -15.00 | 14141.10 |
| ├─ 513100.XSHG | 纳指ETF | 6100 | 1.643 | 1.635 | +0.49% | +48.80 | 10022.30 |
| ------------------------ | ---------- | ---------- | ---------- | ---------- | ------------ | ------------ | -------------- |
| ▼ 【简单ROA策略】 | 当日收益: | -2.69% | 累计收益: | -2.69% | 策略真实权益: | ——> | 9731.00 |
| ├─ 600219.XSHG | 南山铝业 | 2400 | 3.910 | 4.020 | -2.74% | -264.00 | 9384.00 |
| ------------------------ | ---------- | ---------- | ---------- | ---------- | ------------ | ------------ | -------------- |
| ▼ 【核心资产轮动策略】 | 当日收益: | -0.03% | 累计收益: | -0.03% | 策略真实权益: | ——> | 9997.13 |
| ├─ 518880.XSHG | 黄金ETF | 800 | 5.977 | 5.974 | +0.04% | +2.13 | 4781.60 |
| ------------------------ | ---------- | ---------- | ---------- | ---------- | ------------ | ------------ | -------------- |
+--------------------------+------------+------------+------------+------------+---------------+--------------+----------------+
2025-01-02 15:06:00 - INFO - 💰 【资金汇总】 总资产: 98541.00 | 账户余额: 11088.40 | 持仓总市值: 87452.60
2025-01-02 15:06:00 - INFO - 📈 【全局表现】 今日总资产涨跌: -1.46% | 账户累计净收益: -1.46%
如果某策略被风控清仓,面板还会极客地显示“└─[ 空仓防守避险中 ]”。每天复盘看一眼这张表,情绪极其稳定。
03 内置四大王牌策略,开箱即用
框架里我配置了4个实战表现优秀的子策略,互相做对冲与互补(回测数据综合表现:年化30%+,夏普近2,最大回撤13%):
- 搅屎棍策略 (30%仓位):主攻中小盘/微盘弹性,严格过滤了ST和退市风险,并加入审计意见排雷。
- 全天候策略 (50%仓位):作为大仓位底仓,利用国债、黄金、纳指、红利低波进行大类资产配置,极度抗跌。
- 简单ROA策略 (10%仓位):价值投资基本面玩法,买入低PB且高ROA的优质核心公司。
- 核心资产轮动策略 (10%仓位):在长短周期动量之间寻找强势ETF资产进行轮动捕捉。
这四个策略各司其职,而面向对象的基类设计让你可以随时“拔插”你自己的新策略。你只需继承 Strategy 基类,重写 filter 选股和 select 逻辑,即可瞬间拥有上述所有的买卖分离与独立账本功能!
05 降维打击:如何把你的策略“拔插式”融入本框架?
很多小白拿到这套源码会问:“框架看着牛逼,但我怎么把自己的‘双均线策略’或者‘小盘价值策略’放进去跑呢?”
这就体现出面向对象(OOP)基类的威力了! 在传统的“屎山代码”里,加一个策略你得重写一遍买卖逻辑、持仓判定、风控拦截……而在本框架下,底层的脏活累活全被 Strategy 基类包揽了(包括停牌剔除、ST过滤、涨跌停规避、独立账本核算),你只需要专注写你的“选股Alpha逻辑”即可。
只需简单3步,就能将你的野路子变成正规军:
第一步:新建一个类,继承框架的 Strategy 基类
假设你要加入一个“我的神级Alpha策略”(选出你心仪的股票等权买入):
# 继承基类 Strategy
class My_Alpha_Strategy(Strategy):
def __init__(self, context, index, name, display_name):
super().__init__(context, index, name, display_name)
# 设定该策略最大持股数
self.stock_sum = 3
def select(self):
# 【核心逻辑区】:写你的神奇选股逻辑
# 比如经过一顿操作,你选出了下面这3只股票
return['000001.XSHE', '600000.XSHG', '600519.XSHG']
def sell(self, context):
self.context = context
targets = self.select()
# 自动计算等权权重(比如3只股,每只占该策略资金的33.3%)
self.current_targets = {stock: round(1/len(targets), 3) for stock in targets} if targets else {}
# 呼叫基类的 _sell 机器,自动去完成实盘卖出、算账、打印!
self._sell(self.current_targets)
def buy(self, context):
self.context = context
if self.current_targets:
# 呼叫基类的 _buy 机器,自动根据剩余资金买入!
self._buy(self.current_targets)
(看懂了吗?你一行 order() 都不用写,底层全帮你干了!)
第二步:去引擎里注册你的新策略(分配资金与名字)
找到源码里的 initialize 和 process_initialize 函数。
# 1. 重新分配一下资金比例(假设原来4个策略,现在加上你的,变成5个)
g.portfolio_value_proportion =[0.2, 0.4, 0.1, 0.1, 0.2] # 给你分配20%的资金
# 2. 在 process_initialize 里给策略上户口
g.strategys = {
name: cls(context, index=idx, name=name, display_name=display_name)
for display_name, name, cls, idx in[
("搅屎棍策略", "jsg_strategy", JSG_Strategy, 0),
("全天候策略", "all_day_stragety", All_Day_Strategy, 1),
("简单ROA策略", "simple_roa_stragegy", Simple_ROA_Strategy, 2),
("核心资产轮动策略", "etf_rotation_strategy", Etf_Rotation_Strategy, 3),
# ▼ 加上你的新策略,分配索引号为 4
("我的神级Alpha", "my_alpha_strategy", My_Alpha_Strategy, 4),
]
}
第三步:给新策略安排一个专属的交易时间
为了错开买卖,我们在 initialize 里写好调度:
# 设定买卖分离时间:11:04卖出,11:09买入,完美避开其他策略!
if g.portfolio_value_proportion[4] > 0:
run_daily(my_alpha_sell, "11:04")
run_daily(my_alpha_buy, "11:09")
# 别忘了在最外层加两个调度小函数:
def my_alpha_sell(context): g.strategys["my_alpha_strategy"].sell(context)
def my_alpha_buy(context): g.strategys["my_alpha_strategy"].buy(context)
大功告成! 明天开盘,你的策略就会自动融合进总账户,并且在尾盘15:06的打印表格里,完美展示出 ▼ 【我的神级Alpha】 的专属盈亏账本!这就是工程化框架的降维打击!
06 结语
量化不是拿着完美的历史回测自我催眠,而是用严谨的系统工程去应对未来的不确定性。 量化交易走到深水区,比拼的绝不是某一个神奇的均线参数,而是资金管理、多策略对冲与底层的工程化能力。
一套高内聚低耦合、买卖分离、账本清晰的实盘框架,就像是一台精密的越野车底盘。你随时可以往上面搭载各种不同排量的发动机(子策略)。不赚钱的策略,直接抽离注销;表现好的策略,一键加大资金权重。
这份代码是我近期计划自己实盘用的底座,内置了 【搅屎棍微盘+全天候+ROA价值+ETF轮动】 4大王牌基准策略(回测综合年化30%+,最大回撤13%),去除了所有的冗余逻辑,极其纯粹,更便于识别各策略表现。建议大家拿去后,熟悉代码和交易调度流,再尝试把自己珍藏实盘策略“拔插”进去。
🎁 源码获取
为了方便大家直接二次开发,我把包含:底层调度器 + 虚拟账本OOP基类 + PrettyTable可视化面板 + 4大内置策略 的完整Python源码打包,可以直接在聚宽编译运行。
关注公众号: 【量化学习实战笔记】 ,**********************************
免责声明: 本账号所有量化策略和量化技术仅作技术交流和量化思路分享,文中提及的股票、ETF不构成任何投资建议,代码仅供策略底层逻辑测试使用。金融市场千变万化,据此操作风险自负,本人不承担任何直接或间接责任。入市有风险,投资需谨慎!