【量化系统从零构建 #18】组合与风控:仓位·止损·可转债双低·回撤
摘要:【量化系统从零构建 #18】组合与风控:仓位·止损·可转债双低·回撤 系列:《量化系统从零构建》|连载项目 · 纯 GET 取数 · 仅依赖 requests 适用:想在
系列:《量化系统从零构建》|连载项目 · 纯 GET 取数 · 仅依赖 requests
适用:想在回测之上加仓位与风控的读者;数据由智兔数服提供,本篇给等权 / 风险平价 / 凯利仓位,止损止盈、可转债双低选债与回撤控制,不依赖任何行情终端,也不发起网络请求。所有数值均为算法演示,不构成收益承诺。
1. 你将得到什么
- 仓位
equal_weight/risk_parity/kelly_winrate:三种仓位算法。 stop_loss:权益曲线从峰值回撤超阈值的清仓信号。double_low:可转债「双低 = 价格 + 溢价率×100」排序选债。- 本篇交付:风控闭环,#19 策略装配与 #20 看板在其上落地。
2. 本篇取数约定
本篇是风控层,不发起网络请求。仓位吃波动率/胜率,止损吃权益曲线,双低吃可转债清单(#15 用 /kzz/list 落库)。数据来自 智兔数服(www.zhituapi.com)。纯 Python。
3. 风控组件
| 组件 | 作用 |
|---|---|
| 等权 | 组合内平分仓位 |
| 风险平价 | 波动低的给高权重 |
| 凯利 | 按胜率/盈亏比算最优下注比例 |
| 回撤止损 | 从峰值回撤超线清仓 |
| 双低选债 | 低价格+低溢价的可转债优先 |
4. 核心模板函数
import sys, math
def equal_weight(n):
return [1.0 / n] * n if n > 0 else []
def risk_parity(vols):
"""按波动倒数分配权重(简化风险平价)。vols 为各资产波动率。"""
inv = [1.0 / v if (v and v > 0) else 0.0 for v in vols]
s = sum(inv)
return [x / s for x in inv] if s > 0 else equal_weight(len(vols))
def kelly_winrate(win_rate, payoff=1.0):
"""凯利仓位:f = win_rate - (1-win_rate)/payoff;结果截断到 [0,1]。"""
f = win_rate - (1 - win_rate) / payoff
return max(0.0, min(1.0, f))
def stop_loss(eq, trail=0.1):
"""从峰值回撤超 trail 的 bar 标记 -1(清仓信号)。"""
peak, sig = eq[0], [0] * len(eq)
for i, v in enumerate(eq):
peak = max(peak, v)
if v / peak - 1 < -trail:
sig[i] = -1
return sig
def double_low(bonds):
"""可转债双低 = 价格 + 溢价率*100;返回按双低升序的代码列表(双低越低越好)。"""
scored = []
for b in bonds:
price, prem = b.get("price"), b.get("premium")
if price is None or prem is None:
continue
scored.append((b.get("code"), price + prem * 100))
scored.sort(key=lambda x: x[1])
return [c for c, _ in scored]
def run_check():
# 合成数据,非真实行情
assert abs(sum(equal_weight(4)) - 1) < 1e-9
rp = risk_parity([0.2, 0.1])
assert rp[1] > rp[0] # 波动低 -> 权重高
assert 0 < kelly_winrate(0.6, 1.0) < 1
eq = [1.0, 1.05, 1.1, 1.0, 0.95] # 峰值1.1回落到0.95约-13.6%
sl = stop_loss(eq, trail=0.1)
assert sl[4] == -1 # 触线清仓
bonds = [{"code": "A", "price": 110, "premium": 0.10},
{"code": "B", "price": 100, "premium": 0.05}]
assert double_low(bonds) == ["B", "A"] # B双低105 < A双低120
print("校验通过")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "--check":
run_check()
else:
print("本篇基于组合与风控计算,不发起网络;用 #15 的 /kzz/list 落库喂入 double_low 即可选债。")
5. 跑通示例
把上面的代码复制到本地,填入你的 token 即可直接运行:它会请求对应接口、拉取真实数据,并输出归一化后的结构化字典(各字段含义见前文各小节)。
6. 坑与注意事项
- 风险平价用波动倒数:波动为 0 要保护(本篇记 0 权重),避免除零。
- 凯利可能给满仓:胜率极高时
f接近 1,实盘通常打折(半凯利)控风险。 - 回撤止损是滞后信号:从峰值回落才触发,已发生亏损;它是「少亏」不是「不亏」。
- 双低是相对排序:双低值随市场水位变,选债看排序而非绝对值。
- 不承诺收益:所有仓位/选债均为算法演示,不构成收益保证。
7. 小结与下篇预告
本篇把仓位与风控钉死:三种仓位 + 回撤止损 + 可转债双低,组合层完整。
下一篇计划写 #19《策略装配与资产配置:多策略叠加权重·ETF 轮动·信号导出》:把选股(#13)、择时(#15)、风控(#18)装配成多策略组合,并导出可下单信号。
8. 免责声明
本文仅演示仓位与风控的算法,所有代码示例均以合成数据校验,未含任何真实数据;文中示例数据仅作演示用途,不构成投资建议,亦不承诺收益。
免费领取证书
数据来自 智兔数服(www.zhituapi.com):零 SDK、纯 GET、免费版即可起步。
领取路径:进入 www.zhituapi.com → 点击「请求证书」→「证书获取」→「免费版」(邮箱验证 3 步即可拿到 token)。
把代码里的 你的智兔token 换成你拿到的真实 token,上面的脚本就能直接打印组合仓位与可转债双低数据。