Balanced Portfolio 是开源的风险平价组合管理与回测项目。本工具仅供研究,不构成投资建议。

GitHub 源代码
© 2026 Balanced Portfolio contributors|粤ICP备2024174552号-2
BP
Balanced Portfolio
风险平价回测股指期货看板加密货币看板场外衍生品定价方法论

方法论 Methodology

Balanced Portfolio 是基于桥水基金风险平价理论的投资组合管理与回测系统,包括中金所股指期货描述性统计和场外期权自动敲入敲出产品(autocallables)结构化产品定价功能,供广大投资者参考和交流学习。

项目仓库:github.com/hxlog/balanced-portfolio

Demo测试账户和密码都是test1

介绍与说明(长文):我全栈开发的第一个产品:Balanced Portfolio 多资产风险平价全天候策略回测系统

本项目基于桥水基金创始人达利欧(Ray Dalio)的风险平价框架,把全球大类资产按宏观周期放入四象限,以历史波动率与协方差为风险度量,构建长期夏普比率大于 1 的全天候指数投资组合。

本文将讲清风险平价(Risk Parity)、四象限、四种优化约束收敛方法、回测机制、数据治理与交易成本的全部细节。

风险平价

传统组合常按资金等额或主观比例配置,结果是少数高波动资产贡献了组合绝大部分风险——典型的"看似分散、实则集中"。风险平价反其道而行:让每个资产(或每个象限)对组合总波动率的边际贡献相等,从而在风险维度上真正分散。

形式上,资产 iii 的边际风险贡献为

MRCi=(Σw)iσp\text{MRC}_i = \frac{(\Sigma w)_i}{\sigma_p}MRCi​=σp​(Σw)i​​

其中 Σ\SigmaΣ 为协方差阵、www 为权重、σp\sigma_pσp​ 为组合波动率。等风险贡献(ERC)即 MRCi=MRCj\text{MRC}_i = \text{MRC}_jMRCi​=MRCj​ 对所有 i,ji,ji,j 成立。我们用过去 N个交易日(默认156)的日收益方差/协方差作为风险因子,覆盖约大半年市场状态,既足够估计二阶矩,又不至于把过时的相关性或过拟合近期的噪音混入决策。

风险平价不追求最大化历史收益,而是追求风险调整后收益的稳健性,所以我们最终都是最大化夏普或Sortino指标。

在不同象限间平衡风险预算,使组合穿越宏观周期而非押注单一环境。

经济情景四象限

经济环境沿"增长"与"通胀"两个维度循环,两两组合得到四种宏观象限。不同资产在不同象限表现占优:增长上行利于权益与商品,通胀上行利于商品,通胀下行利于债券与成长股,经济下行的占优配置无理论支撑,故因人而异。

在四象限中各放一类"在该象限占优"的资产,再用风险平价分配风险预算,即可获得对单一环境不敏感的全天候组合。

如果你认为债券和黄金是永远都要持有的,那么在每个象限内都加入它们,这不会影响结果,相反,如果象限内的投资品样本过少或严重的多重共线性,可能会引发协方差退化(破坏正定性),从而无法收敛至所有投资品加总权重=1。

同一资产可出现在多个象限(例如商品同时用于过热与滞胀对冲)。系统允许一个标的被放入多个象限,优化器在象限层面做风险平价时自然体现这种重叠暴露。

过热(通胀↑ 增长↑)
国内宽基、商品
滞胀(通胀↑ 增长↓)
黄金、商品、海外宽基、红利
复苏(通胀↓ 增长↑)
国内宽基、商品、红利、债券
衰退(通胀↓ 增长↓)
红利、债券、海外宽基、黄金

将数个占优资产正确地放入四个象限是该策略最核心的假设和参数。

四种优化方法

每个组合可在以下四种方法中任选其一,事实上在后台异步任务中会同时计算这四种。

比率指标可在夏普比率与 Sortino 比率间切换(默认夏普)。约束统一为长仓 w≥0w \ge 0w≥0、∑w=1\sum w = 1∑w=1,可选单资产集中度 max_weight约束(默认33%,若投资品较多,可设置成公募基金一样20%)。

方法说明
象限内最大化优化指标,象限间风险平价(默认)先在每个象限内最大化所选优化指标(夏普/Sortino)得内部权重,再让各象限波动率贡献相等(ERC),两层权重相乘,兼顾象限内进取与象限间平衡。
所有投资品之间风险平价经典风险平价,忽略象限,让每个基础资产对组合波动率的边际贡献完全相等。问题是会重仓先天低波动的资产(如债券和黄金),低配高弹性的资产,适用于投资品数量较少的情形
全体最大化优化指标马科维茨均值-方差框架下,纯粹追求组合历史优化指标最大化,对历史样本非常敏感,适合自动跟踪趋势。
按优化指标²分配风险各资产风险预算 ∝\propto∝ 单资产指标²,给予历史表现更优者更高风险预算,动量与风险间的折中。

求解器实现

  • ERC / 风险预算用 Spinu 循环坐标下降(CCD)闭式迭代求解:每次固定其余权重,对单一资产权重有闭式更新公式,收敛快且精度高于通用规划器,无需求逆。
  • 最大比率用 SLSQP 约束规划求解,支持热启动(以上一交易日权重作 x0x_0x0​)与预算入参(回测逐日传入预计算的 cov/mean),使逐日调用仅需单次热启动求解。样本均值在进入目标前按 (1−λ)xˉ+λ rf(1-\lambda)\bar{x}+\lambda\,r_f(1−λ)xˉ+λrf​(λ=0.5\lambda=0.5λ=0.5)收缩以抑制短窗噪声导致的过拟合与角点解;ERC / 风险预算路径不依赖均值,不受影响。
  • 比率可选夏普(对称波动)或 Sortino(仅下行波动),影响最大比率目标与单资产风险预算的计算口径。

回测系统

回测采用单位净值法,逐交易日推进,无未来函数:

  • 决策与结算的时序隔离:每个交易日 ttt 先用滚动 156 日窗口(仅 ≤t\le t≤t 的数据)重算最优目标权重;当日 NAV 用当日收益 rtr_trt​ 更新;新权重自 t+1t+1t+1 起生效。即"今日决策、明日执行",决策与收益结算不共享未来信息。
  • 成分逐步纳入:effective_start=max⁡(用户start, 首个≥1 资产满足 min_window 历史的交易日)effective\_start = \max(用户start,\ 首个\ge1\ 资产满足\ min\_window\ 历史的交易日)effective_start=max(用户start, 首个≥1 资产满足 min_window 历史的交易日)。历史不足的品种权重暂为 0,不拖后全体起点;随其历史累积到 min_window(默认 60 日)后自动纳入。
  • 再平衡触发:任一品种的实际(漂移)权重与当日最优目标偏离超过 rebalance_band(默认 5 个百分点,绝对值)时,整体再平衡回当日最优。
  • 性能:用前缀和滚动预算每日窗口的均值/协方差(S1,S2S_1, S_2S1​,S2​ 加减),将逐日成本从 O(window⋅n2)O(window \cdot n^2)O(window⋅n2) 降为 O(n2)O(n^2)O(n2);优化器以上一交易日权重热启动,避免重复求解。
避免未来函数

就算回测日期之后的未来价格发生变化,不会改变该日之前的 NAV 与历史权重——即无未来函数可被验证。

再平衡规则

每个交易日系统都用滚动 156 个交易日窗口重算最优目标权重。当任一品种的实际(漂移)权重与当日最优目标偏离超过 5 个百分点时,整体再平衡回当日最优,确保调整后无任一品种偏离超 5%。默认 100% 满仓,若有剩余资金按目标补足,分红通过复权序列实现再投资。

基准口径

组合净值的对比基准分两类收益口径,对比时需注意一致性:

  • 价格指数(不含派息):沪深300 / 中证A500 / 中证500(cn_index_em,fqt=0)、恒生指数(hk_index_em)——只反映价格变动,成分股派息不计入。
  • 总收益指数(含票息/派息再投资):中债国债财富指数(bond_csi_treasury,"财富"口径);组合里的 ETF 走后复权(etf_em,hfq),已将派息折回净值。
  • 60/40经典股债 = 60% 中债国债财富(总收益)+ 40% 沪深300(价格),混合口径。

若组合资产为 ETF(后复权,含派息)而基准选价格指数,基准年化会被系统性低估约指数股息率(沪深300约 2%、恒生约 3%),超额收益与信息比率会被同向高估。Dashboard 在基准下拉下方标注了每个基准的口径,含派息组合与价格指数基准的对比请按此口径理解。

交易成本

回测支持按组合设定三项费率,仅在触发再平衡时扣费,按比例从当日单位净值中扣除:

费率默认缴纳方
手续费0.015%(万1.5)双边(买 + 卖)
滑点0.015%(万1.5)双边(买 + 卖)
印花税0.05%单边(仅卖出)

设再平衡日权重变化 Δw=目标−漂移\Delta w = 目标 - 漂移Δw=目标−漂移,记 turnover=∑∣Δw∣turnover = \sum |\Delta w|turnover=∑∣Δw∣(买 + 卖双边绝对值之和)、sell_turnover=∑max⁡(0,−Δw)sell\_turnover = \sum \max(0, -\Delta w)sell_turnover=∑max(0,−Δw)(净减仓)。则:

cost=turnover×(手续费+滑点)+sell_turnover×印花税\text{cost} = turnover \times (\text{手续费} + \text{滑点}) + sell\_turnover \times \text{印花税}cost=turnover×(手续费+滑点)+sell_turnover×印花税

即建仓/买入缴手续费 + 滑点;卖出缴手续费 + 滑点 + 印花税。这是比例换手模型,用于研究级摩擦近似,不含印花税分档、最低佣金等非线性规则。

基于Brinson的绩效归因

Dashboard「绩效归因」将区间总收益拆解为四个可加桶。本实现受 Brinson 业绩归因启发,但不是经典 Brinson-Fachler 的"相对基准行业配置 / 选股 / 交互"三分法;此处"截面选择"指按组合自身平均权重静态持有时的结构贡献,请勿与研报中的选股 Alpha 划等号。

桶日度含义如何理解
系统性 Betaβ⋅rb\beta \cdot r_bβ⋅rb​组合对所选基准的线性暴露;β=Cov(rp,rb)/Var(rb)\beta = \text{Cov}(r_p, r_b)/\text{Var}(r_b)β=Cov(rp​,rb​)/Var(rb​),全区间估计一个常数 β。
截面选择∑wˉiri,t−β⋅rb\sum \bar{w}_i r_{i,t} - \beta \cdot r_b∑wˉi​ri,t​−β⋅rb​若每天都按平均配置持有,相对"纯 Beta"多赚/少赚多少——体现选了哪些资产、结构如何。
时序调仓∑(wi,t−wˉi)ri,t\sum (w_{i,t} - \bar{w}_i) r_{i,t}∑(wi,t​−wˉi​)ri,t​实际权重偏离平均权重的动态部分——再平衡、漂移、N% 偏离带触发的调仓价值。风险平价赚的是截面和Beta的钱,时序调仓只要不大亏就是合格的
残差—实际净值总收益 − 上述三桶(Carino 链接后)。主要吸收手续费/滑点/印花税及无法以上三因素解释的口径差。

每个交易日(税前)恒等成立:Beta+截面选择+时序调仓=组合日收益\text{Beta} + \text{截面选择} + \text{时序调仓} = \text{组合日收益}Beta+截面选择+时序调仓=组合日收益。跨多日用 Carino 对数链接将日度效应累加为几何总收益,使各桶可加且合计贴近区间总收益。若设置了手续费/滑点/印花税,残差会明显反映交易成本;未设成本时残差应接近 0。

Dashboard 图表:收益拆解瀑布四桶逐步累加到组合总收益;各资产收益贡献可拆为静态(选品)与调仓(择时)两列;逐次调仓贡献展示每次再平衡持有区间的几何收益及对总收益的链接贡献。

相关性与协方差矩阵

Dashboard 展示近回溯窗口(默认 156 日)内各成分日收益率的相关系数与年化协方差。相关系数 ∈[−1,1]\in [-1, 1]∈[−1,1],衡量收益同向/反向程度,分散化时追求低相关或负相关(相关 ≠ 因果)。协方差绝对值越大,共同波动越强;风险平价优化器直接使用协方差阵。成分较多时可勾选子集查看,默认展示跨类别(指数、ETF、债券、商品等)的多样化样本。

股指期货升贴水分析

本平台独立提供中金所(CFFEX)四大股指期货 IF(沪深300)、IH(上证50)、IC(中证500)、IM(中证1000) 的收盘数据监控与历史升贴水量化分析。

该功能受Alpha/多空策略/期权对冲管理启发,交易员需盯准基差和贴水决定交易哪个合约,尽可能减少对冲成本,所以这里除了有基本行情,还会计算年化升贴水率、综合升贴水率、分位值等描述性统计指标。

升贴水率的定义

升贴水率反映期货价格对现货指数的偏离程度:

升贴水率=期货价格−现货指数现货指数×100%\text{升贴水率} = \frac{\text{期货价格} - \text{现货指数}}{\text{现货指数}} \times 100\%升贴水率=现货指数期货价格−现货指数​×100%
  • 正值 = 升水:期货价格高于现货指数,市场预期未来上涨
  • 负值 = 贴水:期货价格低于现货指数(如 IC、IM 长期处于深贴水),持有期货多头可获得展期收益

基差(Basis)= 现货指数 − 期货价格,与升贴水率互为相反数。年化升贴水率按实际剩余天数折年:

年化升贴水率=升贴水率×365距离交割天数\text{年化升贴水率} = \text{升贴水率} \times \frac{365}{\text{距离交割天数}}年化升贴水率=升贴水率×距离交割天数365​

合成升贴水率

为规避当月合约临近交割日价格异常波动的干扰,平台采用加权合成口径:

合成年化升贴水率=0.6×次月年化+0.4×当季年化\text{合成年化升贴水率} = 0.6 \times \text{次月年化} + 0.4 \times \text{当季年化}合成年化升贴水率=0.6×次月年化+0.4×当季年化

即只看次月与当季合约,完全排除当月权重。该加权方案在保留市场期限结构信息的同时,消除了到期日前后基差剧烈波动带来的噪声。

合约类型映射

CFFEX 每个品种同时挂牌 4 个合约,按交割月份距离当前交易日自动归类:

类型含义示例(假设当前为 2026-03-07)
当月最近到期月份合约IF2603
次月次近到期月份合约IF2604
当季最近季月合约(3/6/9/12)IF2606
次季次近季月合约IF2609

合约到期日为到期月份的第三个星期五。若当前日期已过到期日,则该合约不再作为当月候选。

数据更新机制

  • bp_ingest 调度器每 BP_CFFEX_SYNC_HOURS 小时(默认 1h)通过 akshare get_futures_daily 增量拉取 CFFEX 日行情;有新交易日则落库并重算升贴水率,无增量则跳过
  • 前端读最新交易日收盘快照,标注"已收盘"与数据日期时间;页面挂载即拉取一次,无轮询
  • 后端以 Redis 30min TTL 缓存收盘快照,多客户端并发时只读一次 DB
  • 前端 ECharts 动态图表支持时间轴拖拽缩放、叠加指数价格双轴对比

场外结构化产品定价

本平台提供独立的场外(OTC)结构化产品定价与簿记模块,覆盖雪球、凤凰、气囊、障碍四类常见结构。

观测与日历

  • 敲入(KI):按 A 股交易日路径逐日观测(离散)。
  • 敲出(KO):仅在月度敲出观察日收盘判定;观察日之间上穿敲出线不构成敲出。锁定期内不安排敲出观察。
  • 非交易日观察日按下一交易日递延。路径步长 t_step_per_year = 252,与 Bus/252 折现口径一致。

票息与计息

雪球采用双票息约定:

  • 敲出票息(coupon_out):在敲出观察日触发敲出时按 ACT/365 应计支付。
  • 红利 / 期末票息(coupon_div):存续至到期且未敲出、未敲入时支付。

折现采用 Bus/252。凤凰为条件派息结构;气囊 / 障碍按参与率与障碍类型结算。

估值状态与终止

估值日根据已实现路径判定状态:alive / knocked_in / knocked_out / expired。

  • 已敲出:合约终止,现值记为 0,当前盈亏锁定为已实现敲出票息;示意图截断至敲出观察日。
  • 已敲入未敲出:按敲入后条款继续估值。
本页内容
  • 风险平价
  • 四种优化方法
  • 回测系统
  • 再平衡规则
  • 基准口径
  • 交易成本
  • 基于Brinson的绩效归因
  • 相关性与协方差矩阵
  • 股指期货升贴水分析
  • 场外结构化产品定价