在量化投资领域,如何科学地分配资产权重、管控下行风险,是每位Python量化研究者绕不开的核心课题。市面上虽有不少组合优化工具,但大多聚焦于经典的均值-方差模型,对尾部风险、多目标优化等高级场景的支持较为有限。
今天要介绍的 azapy,就是一个开源的、专注于风险导向型投资组合优化的 Python 库。它最大的亮点在于,内置了 10 种风险度量与 6 种优化策略的自由组合,总计提供了多达60种不同的组合构建方式。从数据获取、资产筛选、风险建模到回测可视化,它提供了一套完整的端到端工作流。无论你是刚接触量化的学习者,还是希望深入研究尾部风险与下行保护的进阶用户,azapy 都值得你将其纳入工具库。
一、azapy 是什么?
azapy 是一个专注于 风险导向型投资组合优化(Risk-based Portfolio Optimization) 的 Python 库。其核心哲学非常明确:投资决策不仅要追逐预期收益,更要量化和主动管理“当市场下行时,可能会亏损多少”这一尾部风险。
它的安装极其简单,一行命令即可搞定:
# 在 Notebook 或终端中安装 azapy
!pip install azapy
二、核心架构:7 步漏斗式工作流
azapy 将一个完整的组合优化过程抽象为7个清晰的步骤,形成一个漏斗式的工作流:
- 原始输入数据:接收股票或ETF的价格、收益率数据。
- 数据预处理:自动清洗缺失值、对齐时间序列、进行重采样。
- 分析器选择:根据输入选择对应的分析器,如
MVAnalyzer(基于价格)或 MVAnalyzerRtn(基于收益率)。
- 风险度量族选择:从支持的10种风险度量中,挑选适合当前市场环境和投资目标的一种。
- 组合构建类型:选择优化方法,如朴素等权、贪心算法或高级凸优化。
- 可选流水线:可在此环节加入滚动时间窗口、市场制度切换、多目标组合等高级模块。
- 输出结果:最终输出资产权重、各类风险收益绩效指标,并支持可视化和压力测试。
三、10 种风险度量一览
azapy 的强大之处在于其丰富的风险度量库,支持以下10种分散度度量,覆盖了从经典到前沿的各种风险建模需求:
| 缩写 |
全称 |
一句话说明 |
| mCVaR |
混合条件风险价值 |
融合多个置信水平的 CVaR,精细刻画尾部损失 |
| mSMCR |
混合二阶矩一致性风险 |
衡量不同压力情景下的波动率一致性 |
| mMAD |
多级平均绝对偏差 |
聚焦于最差的 m 个收益的下行风险 |
| mLSD |
多级下半偏差 |
仅关注低于预期收益的那部分波动 |
| mBTAD |
混合阈值绝对偏差 |
衡量收益偏离设定阈值的程度(上下均考虑) |
| mBTSD |
混合阈值半偏差 |
仅衡量低于阈值的偏差,是纯粹的下行风险度量 |
| mEVaR |
混合熵风险价值 |
基于熵理论的尾部风险度量方法 |
| GINI |
基尼指数 |
衡量投资组合收益分布的集中或不平等程度 |
| SD |
标准差 |
最经典的整体波动率度量 |
| VAR |
方差 |
传统均值-方差模型的基础 |
四、6 种优化策略
上述每一种风险度量,都可以与以下6种优化目标(通过 rtype 参数指定)灵活搭配,从而形成丰富的策略矩阵:
| 策略参数 |
含义 |
rtype='Risk' |
在给定预期收益约束下,最小化组合风险 |
rtype='MinRisk' |
求解全局最小风险组合(风险平价思想的基础) |
rtype='InvNrisk' |
在给定的风险水平上限下,最大化组合收益 |
rtype='RiskAverse' |
根据固定的风险厌恶系数,最大化风险调整后收益 |
rtype='Sharpe' |
最大化广义夏普比率 |
rtype='Sharpe2' |
最小化广义夏普比率的倒数(等价于最大化夏普比率) |
五、实战案例解析
案例 1:快速获取市场数据
首先,我们来看如何用 azapy 获取历史市场数据,这是所有分析的起点。
import numpy as np
import pandas as pd
import azapy as az
# 打印 azapy 版本
print(f"azapy version {az.version()}", flush=True)
# 设置参数
mktdir = 'MkTdata' # 数据存储目录
sdate = '2012-01-01' # 起始日期
edate = '2021-07-27' # 结束日期
symb = ['GLD', 'TLT', 'XLV', 'IHI', 'VGT'] # 资产列表(ETF)
# 获取历史市场数据
mktdata = az.readMkT(symb, sdate=sdate, edate=edate, file_dir=mktdir)
运行上述代码,azapy 会自动从 Yahoo Finance 下载指定资产在给定时间范围内的数据,并保存为本地 CSV 文件。函数返回一个包含 open, high, low, close, volume 等字段的 Pandas DataFrame,可直接用于后续分析。
案例 2:使用 CVaR 分析器评估随机组合
了解如何用 CVaRAnalyzer 来计算一个给定权重组合的混合条件风险价值(mCVaR)。
import numpy as np
import azapy as az
# 定义 mCVaR 的参数
alpha = np.array([0.95, 0.90, 0.85]) # 三个置信水平
coef = np.full(len(alpha), 1/len(alpha)) # 等权混合
# 构建 CVaR 分析器 (假设 mktdata 已从案例1获取)
cr1 = az.CVaRAnalyzer(
alpha, coef, mktdata,
hlength=3.25, # 收益聚合的时间跨度(年)
method='ecos' # 凸优化求解器
)
# 生成一个随机组合权重(所有权重和为1)
ww = np.random.dirichlet([0.5] * len(symb))
# 计算该随机组合的混合 CVaR 风险
risk = cr1.getRisk(ww)
# 输出结果
print(f"组合权重:{ww.round(4)}")
print(f"预期收益率:{cr1.RR:.4f}")
print(f"混合 CVaR 风险:{risk:.4f}")
print(f"各层级风险分量:{cr1.primary_risk_comp.round(6)}")
结果解读:
alpha=0.95 表示关注最差5%情况下的平均损失;设置多个 alpha 值意味着同时考虑轻度、中度、重度下行情景,使风险度量更稳健。
coef 设为等权,表示这三个尾部情景在当前风险模型中被视为同等重要。
- 最终输出的
risk 值是三个 CVaR 分量的加权平均,代表了资产组合在不同极端情景下的综合预期损失。
案例 3:使用 mEVaR 构建夏普最优组合
这个案例展示如何用熵风险价值(EVaR)作为风险度量,来构建一个旨在最大化夏普比率的投资组合。
import azapy as az
# 获取6只资产的市场数据
symb = ['GLD', 'TLT', 'XLV', 'IHI', 'VGT', 'OIH']
mktdata = az.readMkT(symb, sdate='2012-01-01', edate='today',
file_dir='../../MkTdata')
# 定义 mEVaR 参数
alpha = [0.75, 0.65] # 两个置信水平
coef = [1.] * len(alpha) # 等权混合
hlength = 1.25 # 历史回望窗口(年)
# 创建 Port_EVaR 组合对象
p4 = az.Port_EVaR(mktdata, pname='mEVaR')
# 以最大化夏普比率为目标构建组合
port4 = p4.set_model(
alpha=alpha,
coef=coef,
rtype='Sharpe', # 最大化广义夏普比率
mu0=0., # 无风险利率设为0
hlength=hlength
)
# 查看组合历史表现与基准对比图
_ = p4.port_view(title="mEVaR-Sharpe", ylabel="价格($)")
# 获取详细的绩效指标表
performance = p4.port_perf()
print(f"绩效概览:\n{performance.round(4)}")
在实际回测中,这样一个基于 mEVaR 风险度量、以夏普比率为优化目标的组合,可能实现约15.8%的年化收益率,其收益与最大回撤比率(RoMaD)可达0.65,最大回撤约24%,表现通常远优于同期单一资产(如 OIH, TLT 等)。
案例 4:动量选股 + CVaR 优化的全自动化流水线
azapy 最强大的功能之一是 ModelPipeline,它允许你将资产筛选、因子模型和组合优化器像乐高积木一样串联起来,形成一个自动化的投资策略流水线。
import numpy as np
import azapy as az
# 定义一个包含40只ETF和大盘股的资产池
symb = ['GLD', 'TLT', 'IHI', 'VGT', 'OIH',
'XAR', 'XBI', 'XHE', 'XHS', 'XLB',
'XLE', 'XLF', 'XLI', 'XLK', 'XLU',
'XLV', 'XLY', 'XRT', 'SPY', 'ONEQ',
'QQQ', 'DIA', 'ILF', 'XSW', 'PGF',
'IDV', 'JNK', 'HYG', 'SDIV', 'VIG',
'SLV', 'AAPL', 'MSFT', 'AMZN', 'GOOG',
'IYT', 'IWM', 'BRK-B', 'ITA', 'VUG']
mktdata = az.readMkT(symb, sdate='2012-01-01', edate='today',
file_dir='../../MkTdata', verbose=False)
# 第 1 步:相关性聚类筛选器 —— 去除高度相关的冗余资产
ccs = az.CorrClusterSelector(corr_threshold=0.98, freq='Q')
# 第 2 步:双动量筛选器 —— 每期只保留动量最强的5只资产
nw = 5
ths = np.floor(len(symb) * 0.7) # 设定阈值:70%的资产有正动量时才满仓投资
dms = az.DualMomentumSelector(nw=nw, threshold=ths)
# 第 3 步:CVaR 优化器 —— 以最大化CVaR夏普比率为目标
cvar = az.CVaRAnalyzer(
alpha=[0.95, 0.9],
freq='Q', # 再平衡频率为季度
hlength=1., # 使用1年历史数据回望
rtype='Sharpe',
mu0=0.01 # 假设无风险利率为1%
)
# 将三个组件串联成一个完整的模型流水线
model = az.ModelPipeline([ccs, dms, cvar])
# 创建回测引擎并运行流水线策略
pp = az.Port_Generator(mktdata, freq='Q', fixoffset=-1, histoffset=1.)
port = pp.set_model(model)
# 查看最终策略绩效
print(f"年化收益率:{pp.port_perf(fancy=True).iloc[0]['RR']}")
print(f"最大回撤:{pp.port_perf(fancy=True).iloc[0]['DD']}")
该流水线策略在2013年至2026年的历史回测中,可能实现约10.85%的年化收益,最大回撤为-24.39%,RoMaD达到0.4446。策略会根据市场状态动态调整持仓,在动量不足时会自动降低风险仓位,体现了较好的下行保护能力。
六、azapy 与其他主流工具对比
为了更清晰地定位 azapy,我们将其与 Python 生态中其他几个流行的组合优化库进行简单对比(采用1-5分制评分):
| 维度 |
azapy |
PyPortfolioOpt |
cvxpy |
Riskfolio-Lib |
py-vAllocation |
| 风险度量丰富度 |
5 |
3 |
3 |
4 |
2 |
| 优化方法多样性 |
4 |
3 |
5 |
4 |
2 |
| API易用性 |
3 |
5 |
1 |
4 |
3 |
| 模型可扩展性 |
5 |
3 |
4 |
2 |
1 |
| 高级模型支持 |
5 |
3 |
4 |
4 |
1 |
| 生产就绪度 |
4 |
3 |
1 |
4 |
2 |
简单总结:
- azapy 在风险度量的全面性和端到端工作流的完整性上优势明显,特别适合想要深度研究和定制算法/数据结构化风险模型的用户。
- PyPortfolioOpt 凭借优雅的API设计最容易上手,是学习经典均值-方差理论的绝佳选择。
- cvxpy 作为一个通用的凸优化库,灵活性最高,但要求用户自行推导和编写数学公式,门槛较高。
- Riskfolio-Lib 在学术研究和成果可视化方面表现出色,提供了丰富的图表类型。
- py-vAllocation 功能相对基础,适合非常简单的场景。
七、当前局限与未来展望
当然,azapy 作为一个持续发展的项目,也存在一些当前版本尚未覆盖的领域:
- 尚未内置交易成本、滑点以及流动性约束的建模。
- 没有提供与盈透证券(Interactive Brokers)等实盘交易系统的直接对接接口。
- 对非凸风险公式、多周期路径依赖优化等更复杂模型的支持有待开发。
根据其开发路线图,这些功能有望在未来的版本中逐步加入。
总结
总而言之,azapy 是一个为 精细化风险管控 而生的 Python 投资组合优化库。对于正在成长中的 Python 量化开发者而言,它的价值体现在多个层面:
- 系统学习风险建模:其提供的10种风险度量本身就是一本活教材,是理解 CVaR、EVaR、下半偏差等核心概念的绝佳实践工具。
- 提升工程效率:它封装了从数据到回测的完整流水线,让你无需在数据清洗、接口对接、可视化等琐碎环节花费过多时间,能更专注于策略逻辑本身。
- 启发对比研究:你可以很方便地用 azapy 和 PyPortfolioOpt 对同一组资产进行优化,直观对比“最小化方差”和“最小化CVaR”两种哲学下产生的组合有何不同,深化对各类算法的理解。
- 贴近实战设计:内置的动量筛选、相关性聚类、滚动窗口回测等功能模块,直接对应了实际资产管理中的常见需求,使得策略研究更具现实意义。
如果你已经掌握了基础的均值-方差优化,并希望将你的组合管理能力提升到一个更注重尾部风险和下行保护的新层次,那么 azapy 无疑是一个值得你投入时间深入研究和尝试的强大工具。像这样的专业工具和深度讨论,在 云栈社区 的技术板块中经常能找到,与更多同行交流能帮助你更快地成长。