🔴
入学要求
💯
能力测试
🛣️
课程安排
🕹️
研究资源

第33讲:投资组合分析 (Portfolio Analysis)

💡

查看全集:💎Quantopia量化分析56讲

投资组合分析是量化金融领域的核心学科,旨在通过科学的方法评估和管理投资组合的风险与收益。在当今复杂多变的金融市场中,投资者面临着资产价格波动、宏观经济不确定性以及日益增长的市场数据量等挑战。传统的经验判断已不足以应对这些问题,因此,数据驱动的投资组合分析工具成为优化资产配置、评估绩效并有效控制风险的关键。本章旨在为读者提供一个系统化的学习路径,通过现代Python工具的应用,帮助您从零开始掌握投资组合分析的理论与实践。

通过本章的学习,您将能够实现以下目标:

1. 环境准备与数据获取

在进行投资组合分析之前,我们需要搭建一个功能强大的Python环境,并获取可靠的金融市场数据。这一小节将详细介绍所需工具的安装和数据获取的完整流程。

1.1 安装必要库

为了完成本章的任务,您需要安装以下Python库。这些库各有其独特的功能,共同构成了投资组合分析的技术基础:

安装这些库的命令如下,在终端或命令行中运行:

bash

pip install yfinance pyfolio empyrical matplotlib

安装注意事项:

1.2 使用yfinance获取数据

以下是一个通过yfinance具体的示例,展示如何获取标普500指数(SPY)以及个股(如苹果AAPL和微软MSFT)的收盘价数据,并计算日收益率:

import yfinance as yf
import pandas as pd

# 获取标普500和个股数据
start = '2014-01-01'
end = '2015-01-01'
benchmark = yf.download('SPY', start=start, end=end)['Close']
assets = yf.download(['AAPL', 'MSFT'], start=start, end=end)['Close']

# 计算收益率
benchmark_rets = benchmark.pct_change().dropna()
portfolio_rets = assets.pct_change().mean(axis=1).dropna()  # 假设等权投资

数据检查与预处理:


2. 关键绩效指标解析

投资组合的绩效评估依赖于一系列关键指标,这些指标帮助我们量化收益与风险的关系。以下是对三个核心指标的详细解析,包括定义、公式、代码实现和解读。

2.1 夏普比率(Sharpe Ratio)

夏普比率是由诺贝尔经济学奖得主威廉·夏普提出的经典指标,用于衡量投资组合在承担单位风险时获得的超额收益。它是风险调整后收益的黄金标准。

公式

Sharpe=E(RpRf)σp Sharpe = \frac{E(R_p - R_f)}{\sigma_p} 
from empyrical import sharpe_ratio

# 计算夏普比率(假设无风险利率为0)
sharpe = sharpe_ratio(portfolio_rets)
print(f"夏普比率: {sharpe:.2f}")

解读:

2.2 最大回撤(Max Drawdown)

最大回撤衡量投资组合从历史最高点到随后最低点所经历的最大亏损幅度,是评估极端风险的重要指标。它直接反映了投资者可能面临的最坏情况。

公式:

最大回撤通常通过计算累积收益率曲线的高点与低点之差来确定:

Max Drawdown=PpeakPtroughPpeak\text{Max Drawdown} = \frac{P_{\text{peak}} - P_{\text{trough}}}{P_{\text{peak}}}

代码实现:

from empyrical import max_drawdown
dd = max_drawdown(portfolio_rets)
print(f"最大回撤: {abs(dd)*100:.1f}%")

解读:

2.3 市场贝塔(Beta)

市场贝塔衡量投资组合相对于市场(如标普500)的系统性风险,反映其对市场整体波动的敏感度。它是资本资产定价模型(CAPM)中的核心参数。

公式

β=Cov(rp,rm)Var(rm) \beta = \frac{Cov(r_p, r_m)}{Var(r_m)} 

其中:

β\beta 表示贝塔系数

Cov(rp,rm)Cov(r_p, r_m) 表示投资组合收益率与市场收益率的协方差

Var(rm)Var(r_m) 表示市场收益率的方差

rpr_p 表示投资组合收益率

rmr_m 表示市场收益率

from empyrical import beta
market_beta = beta(portfolio_rets, benchmark_rets)
print(f"市场贝塔: {market_beta:.2f}")

解读:

小练习:计算组合的年化波动率

任务:计算投资组合的年化波动率,并以百分比形式输出,作为风险的直观度量。
代码实现:

# 提示:使用empyrical.annual_volatility()

3. 可视化分析

可视化分析是将复杂数据转化为直观洞见的关键步骤。以下介绍三种常用的可视化方法,帮助您深入理解投资组合的表现和风险。

3.1 累积收益对比

通过绘制投资组合与基准(如标普500)的累积收益率曲线,评估其相对表现和长期趋势。

代码实现:

import pyfolio as pf
import matplotlib.pyplot as plt

# 创建双图布局
fig, ax = plt.subplots(2, 1, figsize=(10, 8))

# 绘制滚动累积收益率
pf.plotting.plot_rolling_returns(portfolio_rets, benchmark_rets, ax=ax[0])
ax[0].set_title("滚动累积收益率对比")

# 绘制日收益率
pf.plotting.plot_returns(portfolio_rets, ax=ax[1])
ax[1].set_title("日收益率")

plt.tight_layout()
plt.show()

说明:

3.2 月度收益热力图

通过热力图展示投资组合的月度收益分布,快速识别高收益或亏损月份,以及潜在的季节性模式。

pf.plot_monthly_returns_heatmap(portfolio_rets)
plt.title("月度收益热力图")
plt.show()

说明:

3.3 滚动指标分析

分析投资组合的滚动贝塔和滚动夏普比率,观察其风险和绩效随时间的变化:

fig, axes = plt.subplots(2, 1, figsize=(10, 8))

# 绘制滚动贝塔
pf.plot_rolling_beta(portfolio_rets, benchmark_rets, ax=axes[0])
axes[0].set_title("滚动贝塔")

# 绘制滚动夏普比率
pf.plot_rolling_sharpe(portfolio_rets, ax=axes[1])
axes[1].set_title("滚动夏普比率")

plt.tight_layout()
plt.show()

说明:

4. 高级风险分析

在掌握基本指标和可视化后,我们进一步探索高级风险分析技术,以更全面地评估投资组合。

4.1 回撤分析矩阵

识别投资组合历史上主要的回撤周期,分析其在不同市场环境下的损失特征:

pf.plot_drawdown_periods(portfolio_rets)
plt.title("回撤周期分析")
plt.show()

说明:

4.2 因子暴露分析

基于Fama-French三因子模型,分析投资组合对市场风险、规模因子(SMB)和价值因子(HML)的暴露,揭示其风格特征:

pf.plot_rolling_fama_french(portfolio_rets)
plt.title("Fama-French 三因子滚动暴露")
plt.show()

说明:

风险指标对比分析

指标适用场景优点局限性
夏普比率收益近似正态分布简单易用,广泛接受对尾部风险(如黑天鹅事件)不敏感
索提诺比率关注下行风险的投资者聚焦损失,适合风险厌恶者需定义最低可接受回报,计算复杂
最大回撤评估最坏情况下的损失直观反映极端风险只关注单一事件,忽略频率和恢复时间

选择建议:

5. 组合诊断练习

通过一个模拟案例,我们将理论应用于实践,强化您的分析能力:

案例数据集

生成一个模拟的投资组合收益率数据:

# 生成模拟数据
import numpy as np
dates = pd.date_range('2020-01-01', periods=500)
returns = pd.Series(np.random.normal(0.0005, 0.01, 500), index=dates)

诊断任务

  1. 任务1:计算年化夏普比率
from empyrical import sharpe_ratio

sharpe = sharpe_ratio(returns, annualization=252)
print(f"年化夏普比率: {sharpe:.2f}")
  1. 任务2:绘制滚动贝塔(对比沪深300)
  1. 任务3:识别最大回撤期
pf.plot_drawdown_periods(returns)
plt.title("最大回撤周期")
plt.show()

附:yfinance高级用法

# 多资产批量下载
data = yf.download(['AAPL', 'MSFT', 'TSLA'],
                   start='2020-01-01',
                   end='2023-01-01',
                   group_by='ticker')

# 数据重整
aapl = data['AAPL']['Close'].rename('AAPL')
msft = data['MSFT']['Close'].rename('MSFT')
portfolio = pd.concat([aapl, msft], axis=1)

通过本教程,您已掌握使用现代Python工具进行专业级组合分析的核心方法。建议在实践中逐步增加:

  1. 交易成本计算
  1. 组合优化模块
  1. 压力测试场景分析

附:练习合集