这个“星际战舰框架”(面向对象+资金轮转框架)对于中高阶的策略管理具有极大的实战意义。开篇我就说了“策略框架和策略一样值钱系列”,所以请不要仅仅关注它的策略的优秀表现(但对于睁眼闭眼要年收益100%+的小白,的确不算亮眼),它是一个代码模板,更是一种“工程化”的量化系统设计思维。
以下我将从“架构价值”和“如何快速接入新策略”两个维度为您深度解析。
第一部分:这个架构对策略管理有意义吗?
结论:意义巨大。它解决了量化实盘从“单兵作战”到“军团作战”的三个核心痛点。
1. 彻底的“物理隔离”(防止策略互殴)
- 传统痛点:你有一个“低吸策略”刚买入万科A,结果另一个“追涨策略”因为万科A没涨停触发了止损卖出。两个策略共用一个账户,互相干扰。
- 本架构价值:通过
g.positions[self.index]建立了独立逻辑账本。策略A只能看到并操作自己的仓位,策略B的操作绝不会影响策略A。这让你可以放心地把完全相反逻辑的策略(如动量+反转)放在一起跑。
2. 极致的“资金利用率”(拒绝资金站岗)
- 传统痛点:你的小市值策略在1月、4月空仓避险,这30%的资金就躺在账上吃0收益。
- 本架构价值:通过
Allocator(资金分配器)和is_empty接口,实现了**“进攻资金”自动流向“防守水池”**。空仓期的资金会自动去买国债或全天候ETF,年化收益率直接提升 3%~5%。
3. 标准化的“执行引擎”(降低开发门槛)
- 传统痛点:写新策略时,每次都要重复写:怎么算买入股数?怎么防止买不够一手?怎么处理停牌?怎么分批买入?
- 本架构价值:基类
Strategy封装了_adjust、get_adjusted_stocks(缓冲池)、min_money(最小交易额)。 - 你只需要告诉框架: “我要买谁,买多少比例”。
- 框架负责: 算钱、剔除停牌、保留老仓位(缓冲)、下单、记账。
第二部分:如何将您的其他策略快速融入架构?
只需遵循**“三步走”标准作业程序 (SOP)**,任何策略都可以像“U盘”一样插入这个系统。
🛠️ 接入模版(请保存备用)
假设您手头有一个简单的**“均线策略”**(金叉买,死叉卖),想融入框架。
第一步:封装策略类(继承 Strategy)
将您的核心逻辑(选股+择时)放入一个新类中:
class My_MA_Strategy(Strategy):
"""
您的自定义策略:均线策略
"""
def __init__(self, context, index, name, display_name):
# 1. 初始化父类
super().__init__(context, index, name, display_name)
# 2. 定义自己的参数
self.stock = "000300.XSHG" # 比如只做沪深300ETF
self.ma_short = 5
self.ma_long = 20
def is_empty(self):
"""
[可选] 宏观择时接口。
如果返回 True,资金会被没收给防守策略;
如果返回 False,资金保留。
"""
# 例如:大盘跌破250日线,申请全额防守
# price = get_current_data()['000300.XSHG'].last_price
# ma250 = ...
# return price < ma250
return False
def adjust(self):
"""
[核心] 调仓逻辑
目标:计算出 target = {标的代码: 目标权重}
"""
# 0. 安全拦截(必写)
if g.portfolio_value_proportion[self.index] == 0: return
# 1. 获取数据 & 计算信号
hist = attribute_history(self.stock, self.ma_long + 2, '1d', ['close'])
ma_s = hist['close'][-self.ma_short:].mean()
ma_l = hist['close'][-self.ma_long:].mean()
target = {}
# 2. 生成目标字典
# 如果短均线 > 长均线 -> 金叉持有
if ma_s > ma_l:
# 权重 1.0 表示占满本策略分配到的资金
target = {self.stock: 1.0}
else:
# 死叉空仓,target 为空字典
target = {}
# 3. 呼叫基类引擎执行交易
# 引擎会自动处理:卖出不在target里的、买入在target里的
self._adjust(target)
第二步:在 initialize 中注册
找到 g.strategy_configs 列表,加一行:
g.strategy_configs =[
# ... 原有策略 ...
# (显示名, 内部ID, 类名, 资金占比, 是否是防守水池)
("我的均线策略", "my_ma_strategy", My_MA_Strategy, 0.2, False),
]
# 注意:所有策略的资金占比加起来最好等于 1.0 (或 >1.0 带杠杆)
第三步:添加调度任务
在 initialize 的 run_daily 区域,添加一行调度:
# 定义包装函数
def run_my_ma(context): g.strategys["my_ma_strategy"].adjust()
# 设定运行时间
run_daily(run_my_ma, "09:45") # 比如每天 09:45 运行
💡 接入时的“思维转换”清单
为了确保无缝接入,请在写代码时转换一下思维:
-
不再关注
context.portfolio.cash:- 以前你写:
if context.portfolio.cash > 1000: order(...) - 现在你不用管钱够不够,基类
_adjust会自动计算属于你的配额。你只管算出 “我要持有谁”。
- 以前你写:
-
不再使用
order_target:- 以前你写:
order_target_value(stock, 10000) - 现在你写:
target = {stock: 1.0}然后调用self._adjust(target)。让框架去下单。
- 以前你写:
-
不再使用全局
g.xxx存变量:- 以前你写:
g.my_stock_list = [...] - 现在请写成类成员:
self.my_stock_list = [...](在__init__里定义)。这样不同策略的变量不会冲突。
- 以前你写:
掌握了这个套路,你可以把聚宽广场(我的号内策略优秀亿点点)上任何优秀的策略(比如微盘股、次新股、可转债轮动)在 5分钟内改装成一个“插件”,插到你的这艘“星际战舰”上,让它们协同作战。好好搜集,假以时日,成为你真正的星际战舰,届时,你就是量化巨人,还会羡慕其他量化机构吗?