第 1 章 · 03 四层架构总览


文档摘要

第 1 章 · 03 四层架构总览 本节摘要:本节是全教程的「地图」,把 PyPortfolioOpt 的所有功能抽象成一张贯穿全书的「四层可替换架构」——收益模型、风险模型、目标函数、优化器。前两层负责「估输入」(给出来自历史数据的 μ 与 Σ),后两层负责「定目标 + 求解」(把 μ、Σ 喂进凸优化问题求出 w)。这四层互不耦合:任意一层都可以独立替换,例如把样本协方差换成 Ledoit-Wolf 收缩、把 maxsharpe 换成 minvolatility、甚至把整个方差目标换成 CVaR,框架照常运转。理解这张地图,后续 9 章就只是「逐层深入填充细节」。本节还讲清为何这种 scikit-learn 风格的模块化设计是 PyPortfolioOpt 的核心竞争力。

第 1 章 · 03 四层架构总览

本节摘要:本节是全教程的「地图」,把 PyPortfolioOpt 的所有功能抽象成一张贯穿全书的「四层可替换架构」——收益模型、风险模型、目标函数、优化器。前两层负责「估输入」(给出来自历史数据的 μ 与 Σ),后两层负责「定目标 + 求解」(把 μ、Σ 喂进凸优化问题求出 w)。这四层互不耦合:任意一层都可以独立替换,例如把样本协方差换成 Ledoit-Wolf 收缩、把 max_sharpe 换成 min_volatility、甚至把整个方差目标换成 CVaR,框架照常运转。理解这张地图,后续 9 章就只是「逐层深入填充细节」。本节还讲清为何这种 scikit-learn 风格的模块化设计是 PyPortfolioOpt 的核心竞争力。

内容来源:原项目源码 README.mddocs/UserGuide.rstdocs/index.rst 概念流程图,汉化并套用体系化模板。

学习目标

阅读完本节,你应当能够:

  1. 画出 PyPortfolioOpt 的四层架构图,说出每层的职责。
  2. 解释模块化设计为何是这个库的核心竞争力。
  3. 区分「输入」与「优化」两个阶段。
  4. 在四层坐标上定位书中后续每个章节(收益模型→第 2 章、风险模型→第 3 章……)。
  5. 描述一条完整的工作流:从价格 DataFrame 到最优权重。

一、为什么是「四层」

回顾上一节的三行代码:

mu = expected_returns.mean_historical_return(df) # 收益 S = risk_models.sample_cov(df) # 风险 ef = EfficientFrontier(mu, S) ef.max_sharpe() # 目标 + 优化器

这三行其实暗含四个角色,只是最后一步把「目标」和「优化器」揉在一起了。把它们拆开,就是 PyPortfolioOpt 全部功能围绕的四个抽象层:

模块 输入 输出 职责
① 收益模型 pypfopt.expected_returns 价格 DataFrame μ 向量 估每只资产的期望收益
② 风险模型 pypfopt.risk_models 价格 DataFrame Σ 矩阵 估协方差/相关性
③ 目标函数 pypfopt.objective_functions w(+μ/Σ) 凸表达式 定义「什么是最优」
④ 优化器 pypfopt.efficient_frontier μ、Σ、目标 w 字典 求解凸问题

💡 核心心法:前两层是「估输入」——把不可知的未来收益与风险,用历史数据估出来;后两层是「求最优」——把估出来的 μ、Σ 喂进凸优化问题,求出权重。PyPortfolioOpt 的卖点不是某层做得最好,而是让你自由换层:你可以用自研因子模型估 μ,再喂进它的优化器;也可以保留它的 μ、Σ,换上自己的目标函数。

二、第一层:收益模型

定义:把价格序列转成「每只资产未来一期期望收益」的估计。模块是 pypfopt.expected_returns,提供三种内置实现:

  • mean_historical_return:历史均值(算术/几何)。
  • ema_historical_return:指数加权,对近期更敏感。
  • capm_return:资本资产定价模型,基于市场 beta。

按约定,这些函数输出年化期望收益(默认 frequency=252,即一年交易日数)。统一后,后续优化器不必关心时间频率。

⚠️ 作者反复警告:供给错误收益比不给收益更糟。若你没有自研预测模型,文档建议干脆放弃 μ,只跑 min_volatility() 或用 HRP。第 7 章 Black-Litterman 会给出更稳的替代方案。详见第 2 章。

三、第二层:风险模型

定义:估协方差矩阵 Σ,它编码了每只资产的波动率以及它们两两之间的联动程度。模块是 pypfopt.risk_models,提供:

  • sample_cov:样本协方差,教科书默认,但噪声大。
  • semicovariance:只惩罚下行偏差。
  • exp_cov:指数加权,对近期联动更敏感。
  • CovarianceShrinkage(Ledoit-Wolf / OAS):收缩估计,生产推荐
  • min_cov_determinant:MCD,抗异常值。

💡 生产默认值:作者在 UserGuide 里点名——risk_models.CovarianceShrinkage(df).ledoit_wolf() 是默认推荐,而非 sample_cov。原因是样本协方差在「资产数接近样本数」时严重失真,收缩能显著降噪。详见第 3 章。

四、第三层:目标函数

定义:把「最优」用数学语言写下来——一个关于权重 w 的函数,求它的最小(或最大)就是优化目标。模块是 pypfopt.objective_functions,内置:

函数 数学形式 用途
portfolio_variance wᵀ Σ w 最小方差
portfolio_return wᵀ μ 最大收益
sharpe_ratio (wᵀ μ - R_f) / σ 最大夏普
quadratic_utility wᵀ μ - ½ δ wᵀ Σ w 二次效用
L2_reg γ wᵀ w 正则,减少零权重
transaction_cost k‖w - w_prev‖₁ 换手成本
ex_ante_tracking_error (w-w_b)ᵀ Σ (w-w_b) 跟踪误差

💡 目标与约束可互换:从优化角度看,「最小化风险 + 收益≥目标」与「最大化收益 + 风险≤目标」是同一类问题——风险与收益的角色互换。PyPortfolioOpt 因此把目标函数设计成「既能当目标,也能当约束」。这是第 4、5 章的核心思路。

五、第四层:优化器

定义:把目标函数 + 约束喂给凸优化求解器(cvxpy 后端),解出 w。主入口是 EfficientFrontier 类,提供五个内置方法:

EfficientFrontier 外,还有针对不同风险度量的优化器(第 6 章详讲):

  • EfficientSemivariance:半方差,只惩罚下行。
  • EfficientCVaR:条件风险价值,关注尾部。
  • EfficientCDaR:条件回撤,关注亏损期。
  • HRP:层次风险平价,绕开 Σ 估计。
  • CLA:临界线算法,马科维茨原版。

所有优化器都继承自 BaseOptimizer/BaseConvexOptimizer,共享 add_constraintadd_objectiveclean_weightsportfolio_performance 等接口。这是 scikit-learn 风格「统一 API」的体现。

六、模块化的价值

README 把「易替换组件」列为头号设计原则。其工程价值体现在三个场景:

  1. A/B 比较风险模型:同一 μ、目标,换不同 Σ,看权重如何变化。
  2. 拼入自研模型:你的因子模型产出 μ,直接喂进 EfficientFrontier;无需 fork 库。
  3. 逐步升级:从 sample_cov 起步,数据足够后切到 Ledoit-Wolf,再切到 Black-Litterman——其余三行代码不变。
# 同一优化器,换不同风险模型 mu = expected_returns.capm_return(df) S1 = risk_models.sample_cov(df) S2 = risk_models.CovarianceShrinkage(df).ledoit_wolf() w1 = EfficientFrontier(mu, S1).max_sharpe() w2 = EfficientFrontier(mu, S2).max_sharpe() # 只换 S

这种「接口稳定、实现可换」的设计,让 PyPortfolioOpt 既适合教学(每层都简单),也适合生产(每层都能定制)。

七、完整工作流

把四层串起来,一条端到端工作流如下:

后续章节就是逐节填充这张图的每一格:

  • 第 2 章:第 ② 格(收益模型三种实现)。
  • 第 3 章:第 ③ 格(风险模型五种实现)。
  • 第 4 章:第 ④⑥ 格(EfficientFrontier 与五种目标)。
  • 第 5 章:第 ⑤ 格(约束、L2 正则、自定义目标)。
  • 第 6 章:换风险度量(CVaR/SV/CDaR)。
  • 第 7 章:Black-Litterman 替代第 ② 格。
  • 第 8 章:HRP、CLA 等其他优化器替代第 ④ 格。
  • 第 9 章:第 ⑧ 格(离散分配)。
  • 第 10 章:可视化与扩展开发。

本节要点回顾

  1. 四层架构:收益模型(expected_returns)、风险模型(risk_models)、目标函数(objective_functions)、优化器(EfficientFrontier 等)。
  2. 两阶段:前两层「估输入」(μ、Σ),后两层「求最优」(目标 + 求解)。
  3. 可替换性:任意一层都可独立换,接口稳定——这是 PyPortfolioOpt 的核心竞争力。
  4. 统一 API:所有优化器继承 BaseOptimizer,共享 add_constraint/clean_weights 等方法,scikit-learn 风格。
  5. 生产默认:Ledoit-Wolf 收缩 > 样本协方差;若无自研 μ,放弃收益只跑 min_volatility 更稳。
  6. 工作流:九步,从价格 DataFrame 到实盘下单,后续 9 章逐节填充。

下一章,我们深入第一层——收益模型,从最朴素的 mean_historical_return 开始。


发布者: 作者: 灏天文库 转发
评论区 (0)
U