3. 计算日收益率

任务目标

给定一组股票每日收盘价,计算相邻交易日的日收益率(百分比变化),并绘制收益率曲线图,直观观察每日涨跌幅度与波动聚集特征。

实现思路

使用 pandas 的 pct_change() 方法计算日收益率,该方法对每个元素计算相对于前一行的变化比例,天然对齐时间序列索引。收益率定义为 (当日收盘价 - 前日收盘价) / 前日收盘价,首日因无前值而得到 NaN,需剔除后再绘图。

完整代码

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# 构造示例数据:10个交易日的收盘价(模拟真实行情)
dates = pd.date_range('2024-01-02', periods=10, freq='B')  # 工作日频率
close_prices = [100.0, 102.5, 101.2, 104.8, 103.0,
                105.6, 107.2, 106.1, 108.9, 110.3]

df = pd.DataFrame({'close': close_prices}, index=dates)

# 核心计算:日收益率(百分比)
df['daily_return'] = df['close'].pct_change() * 100

# 剔除首日NaN值
returns = df['daily_return'].dropna()

# 输出计算结果
print("=== 日收益率序列 ===")
print(returns.round(4))

# 可视化:收益率曲线
plt.figure(figsize=(10, 4))
plt.plot(returns.index, returns.values, marker='o', linestyle='-', color='#1f77b4')
plt.axhline(y=0, color='gray', linestyle='--', linewidth=0.8)
plt.title('Daily Return (%)')
plt.xlabel('Date')
plt.ylabel('Return (%)')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

# 基础统计摘要
print("\n=== 收益率统计 ===")
print(f"均值: {returns.mean():.4f}%")
print(f"标准差: {returns.std():.4f}%")
print(f"最大涨幅: {returns.max():.4f}%")
print(f"最大跌幅: {returns.min():.4f}%")

运行方式

  1. 安装依赖:pip install pandas matplotlib
  2. 将上述代码保存为 daily_return.py,在终端执行 python daily_return.py

验证方法

程序运行后应输出9个非空收益率值(10个交易日产生9个收益率),且满足以下条件即判定通过:

  • 第一个收益率对应2024-01-03,值为 (102.5-100)/100*100 = 2.5%,与输出一致;
  • 所有收益率均落在合理区间(本例约-2%至+2%之间);
  • 弹出窗口显示收益率曲线,横轴为日期、纵轴为百分比,曲线围绕0轴上下波动。

预期输出(确定性结果)

=== 日收益率序列 ===
2024-01-03    2.5000
2024-01-04   -1.2683
2024-01-05    3.5573
2024-01-08   -1.7176
2024-01-09    2.5243
2024-01-10    1.5152
2024-01-11   -1.0261
2024-01-12    2.6381
2024-01-15    1.2856
Freq: B, Name: daily_return, dtype: float64

=== 收益率统计 ===
均值: 1.1120%
标准差: 1.8952%
最大涨幅: 3.5573%
最大跌幅: -1.7176%
日收益率序列可视化(示例数据) 0% +3% +2% +1% -1% -2% +2.50% +3.56% -1.72% +2.64% 01-03 01-05 01-09 01-11 01-15 日收益率

常见问题

  • 首日收益率为NaN:这是正常现象,因为第一天没有前收盘价可比较,使用 dropna() 剔除即可。
  • 若使用真实股票数据:将 close_prices 替换为从 yfinance 或 tushare 获取的收盘价列,代码其余部分无需改动。
  • 收益率单位:代码中乘以100转换为百分比,若需小数形式(如0.025)去掉 *100 即可。