1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| import matplotlib.pyplot as plt import matplotlib.ticker as mtick import pandas as pd import numpy as np
# 读取历史行情数据 df = pd.read_excel('2-1.xlsx')
# 保留要用的字段 df = df[['日期', '收盘']]
# 转换日期格式并设为index df['日期'] = pd.to_datetime(df['日期']) df.set_index('日期', inplace=True)
# 用对数收益来描述价格变动 df['对数收益'] = np.log(df['收盘']/df['收盘'].shift(1))
# 定义一个计算实现波动率的函数 def realized_volatility(x): return np.sqrt(np.sum(x**2))
# 将数据按照月度重组,并计算实现波动率 df_rv = ( df.groupby(pd.Grouper(freq="M")) .apply(lambda x: realized_volatility(x['对数收益'])) # 确保只处理对数收益列 .to_frame(name="月实现波动率") # 转换为DataFrame并命名列 )
# 计算年化实现波动率 = 月波动率 × √12 (年化转换因子)[2,3](@ref) df_rv['年化实现波动率'] = df_rv['月实现波动率'] * np.sqrt(12)
# 格式化为百分比字符串便于阅读 df_rv['年化实现波动率_pct'] = df_rv['年化实现波动率'].apply(lambda x: f"{x:.2%}")
#指定图像样式 plt.style.use('seaborn-v0_8') #指定字体,防止中文出现乱码,windows系统指定为‘SimHei’ plt.rcParams['font.sans-serif'] = ['SimHei'] #这行代码让中文的负号“-”可以正常显示 plt.rcParams["axes.unicode_minus"]=False
# 创建2行1列的子图布局 fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10), sharex=False)
# ===== 上方子图:每日对数收益率 ===== ax1.plot(df.index, df['对数收益'], color='blue', alpha=0.7, linewidth=1.2) ax1.set_title('每日对数收益率', fontsize=14, fontweight='bold') ax1.set_ylabel('对数收益率', fontsize=12) ax1.grid(True, linestyle='--', alpha=0.6)
# 添加零线参考 ax1.axhline(y=0, color='red', linestyle='--', alpha=0.5)
# ===== 下方子图:月度年化实现波动率 ===== # 计算柱状图的x位置(每月最后一天) x_pos = df_rv.index
# 绘制柱状图 bars = ax2.bar(x_pos, df_rv['年化实现波动率'], width=20, # 柱宽(根据日期调整) color='green', alpha=0.7)
# 设置波动率标签 ax2.set_title('月度年化实现波动率', fontsize=14, fontweight='bold') ax2.set_ylabel('波动率', fontsize=12) ax2.grid(True, linestyle='--', alpha=0.6)
# 将波动率格式化为百分比 ax2.yaxis.set_major_formatter(mtick.PercentFormatter(1.0))
# ===== 整体布局优化 ===== plt.xticks(rotation=45) # 旋转x轴标签防止重叠 plt.tight_layout() # 自动调整子图间距
# 添加整体标题 fig.suptitle('股价对数收益率与年化波动率对比分析', fontsize=16, fontweight='bold', y=0.98)
# 显示图表 plt.show()
|