跳到主要内容

重采样与对齐

直觉

不同资产、不同来源的数据,往往频率不同、日期不对齐(A 股和美股交易日不同,股和债有各自停牌)。把它们塞进同一个回测前,必须先统一频率、对齐到共同的时间轴

重采样

  • 降采样(高频→低频):日→周/月,用 .resample().last() 或聚合;
  • 升采样(低频→高频):月→日,会产生缺失,常配 .ffill()(把月度值延续到每日)。

对齐

两个 Series 相除/相加时,pandas 会按索引自动对齐——索引不一致的格子变成 NaN。多资产场景通常:

  1. 取所有资产的共同交易日df.dropna() 或交集);
  2. 或对齐后 ffill 补齐。

可运行案例:多资产降采样 + 对齐收益矩阵

读取 multi_asset_daily.csv,算各资产周频收益,并对齐成一张表,确认它们已共时间轴。

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

df = pd.read_csv('/data/multi_asset_daily.csv', parse_dates=['date']).set_index('date')
assets = ['equity', 'bond', 'commodity', 'reit']

# 日频收益(自动按索引对齐) — 4 列同时相除
daily_ret = np.log(df[assets] / df[assets].shift(1))
print("日频收益缺失(首行):"); print(daily_ret.isna().sum().to_dict())
daily_ret = daily_ret.dropna()

# 降采样到周频收益: 周内累乘的对数 = 周内对数收益求和
weekly_ret = daily_ret.resample('W').sum()
monthly_ret = daily_ret.resample('ME').sum()
print(f"\n日频行数={len(daily_ret)}  周频行数={len(weekly_ret)}  月频行数={len(monthly_ret)}")

# 确认已对齐: 每行(同一周)四资产都有值
print("周频仍有缺失的周数:", int(weekly_ret.isna().any(axis=1).sum()))

# 看看各资产周收益的相关(对齐后才能算)
print("\n周频收益相关:"); print(weekly_ret.corr().round(2))

weekly_ret.cumsum().plot(figsize=(8, 3.6))
plt.title("四类资产累计对数收益(周频, 对齐)"); plt.ylabel("累计对数收益")
plt.tight_layout(); plt.show()

小结

  • 降采样.resample().last()(价格)或 .sum()(对数收益);
  • pandas 运算会按索引自动对齐,不一致处变 NaN
  • 多资产回测前,先统一频率并取共同时间轴。