基于日度DataFrame生成周期数据及30日滚动收益可视化问题
解决方案:金融时间序列的时段提取、收益率计算与可视化
一、解决月末交易日数据缺失/NA问题
你用resample('M').asfreq()出现NA是因为该方法取日历月末日期,若当天不是交易日则返回空值。要获取每个月实际最后一个交易日的数据,改用resample('M').last():
import yfinance as yf import pandas as pd import matplotlib.pyplot as plt # 下载标普500数据 s1 = yf.download("^GSPC", start="2005-02-01", end="2007-12-31") # 提取月度最后交易日数据(无NA) monthly_data = s1.resample('M').last()
如果需要强制用日历月末日期(非交易日则用前一个交易日数据填充),追加ffill():
monthly_calendar_end = s1.resample('M').asfreq().ffill()
二、生成30天/60天间隔的数据
固定天数间隔的提取,直接用resample('30D').last(),会从起始日期开始,每30天取最近的最后一个交易日数据:
# 30天间隔数据 data_30d = s1.resample('30D').last() # 60天间隔数据 data_60d = s1.resample('60D').last()
三、计算时段收益率并绘制柱状图
收益率公式为:(当前时段收盘价 / 上一时段收盘价) - 1,计算后用柱状图展示:
# 计算月度收益率 monthly_data['Return'] = (monthly_data['Close'] / monthly_data['Close'].shift(1)) - 1 # 计算30天间隔收益率 data_30d['Return'] = (data_30d['Close'] / data_30d['Close'].shift(1)) - 1 # 绘制月度收益率柱状图 plt.figure(figsize=(12, 6)) monthly_data['Return'].plot(kind='bar', color='steelblue', edgecolor='black') plt.title('S&P 500 月度收益率(2005-2007)') plt.xlabel('日期') plt.ylabel('收益率') plt.xticks(rotation=45) plt.tight_layout() plt.show()
四、计算含Stub Period的30日滚动收益率
要实现滚动窗口最多30天,不足30天时用实际窗口长度计算收益率(包含开头和末尾的stub period),用rolling配合min_periods=1即可,一行代码搞定:
# 计算滚动30日收益率,窗口不足30天时自动用现有数据计算 s1['Rolling_30D_Return'] = s1['Close'].rolling(window=30, min_periods=1).apply( lambda x: (x[-1] / x[0]) - 1, raw=False ) # 绘制滚动收益率曲线 plt.figure(figsize=(12, 6)) s1['Rolling_30D_Return'].plot(color='darkorange', linewidth=1.5) plt.title('S&P 500 30日滚动收益率(含Stub Period)') plt.xlabel('日期') plt.ylabel('收益率') plt.grid(alpha=0.3) plt.tight_layout() plt.show()
这个方法中,min_periods=1允许窗口最少1个数据点就计算收益率,lambda函数计算窗口内首尾收盘价的收益率,完美覆盖不足30天的情况。
内容的提问来源于stack exchange,提问作者Rampy sri
相关产品推荐
相关产品推荐

