You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用DataFrame与DatetimeIndex实现滚动12月计算及年化指标求解?

Pandas滚动12个月数据处理与业绩指标计算

一、用DataFrame和DatetimeIndex获取滚动12个月数据

如果你的DataFrame索引是月度频率的DatetimeIndex,优先用时间窗口而非固定行数,能精准匹配日历上的12个月,避免缺失数据导致窗口错位:

  • 使用rolling(window='12M')指定滚动窗口为12个日历月
  • 配合聚合函数(如mean()/sum())即可得到对应指标

示例代码:

import pandas as pd
import numpy as np

# 生成月度时序数据
dates = pd.date_range(start='2020-01-31', periods=24, freq='M')
df = pd.DataFrame({'value': np.random.randn(24)}, index=dates)

# 滚动12个月均值(可替换为其他聚合逻辑)
rolling_12m_avg = df.rolling(window='12M').mean()

对比:如果用window=12,当数据存在缺失月份时,窗口会取连续12行(可能跨13个日历月),而'12M'会严格筛选过去12个完整日历月的有效数据。

二、滚动12个月年化阿尔法与跟踪误差计算

针对包含「Manager Returns」和「Benchmark Returns」的月度DataFrame,直接基于滚动窗口实现指标计算,以下是完整函数:

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression

def calculate_rolling_12m_metrics(df):
    # 确保索引为月度频率DatetimeIndex
    df = df.asfreq('M')

    def get_annualized_alpha(window):
        # 对窗口内的月度收益做线性回归,得到月度阿尔法后年化
        X = window['Benchmark Returns'].values.reshape(-1, 1)
        y = window['Manager Returns'].values
        reg = LinearRegression(fit_intercept=True).fit(X, y)
        # 月度阿尔法 * 12 转换为年化值
        return reg.intercept_ * 12

    def get_annualized_tracking_error(window):
        # 计算月度超额收益的标准差,再年化(乘以sqrt(12))
        excess_returns = window['Manager Returns'] - window['Benchmark Returns']
        return excess_returns.std() * np.sqrt(12)

    def get_annualized_return(window, col_name):
        # 滚动12个月累计收益(因为是12个月,直接等于年化收益)
        cumulative_return = (1 + window[col_name]).prod() - 1
        return cumulative_return

    # 定义滚动窗口:12个日历月,仅当有完整12个月数据时计算
    rolling_window = df.rolling(window='12M', min_periods=12)

    # 计算各项指标
    df['Annualized Alpha'] = rolling_window.apply(get_annualized_alpha, raw=False)
    df['Annualized Tracking Error'] = rolling_window.apply(get_annualized_tracking_error, raw=False)
    df['Manager Annualized Return'] = rolling_window.apply(lambda w: get_annualized_return(w, 'Manager Returns'), raw=False)
    df['Benchmark Annualized Return'] = rolling_window.apply(lambda w: get_annualized_return(w, 'Benchmark Returns'), raw=False)

    return df

# 生成测试数据
dates = pd.date_range(start='2020-01-31', periods=24, freq='M')
test_df = pd.DataFrame({
    'Manager Returns': np.random.normal(0.01, 0.03, 24),  # 经理月度收益均值1%,标准差3%
    'Benchmark Returns': np.random.normal(0.008, 0.025, 24)  # 基准月度收益均值0.8%,标准差2.5%
}, index=dates)

# 计算并查看结果
result = calculate_rolling_12m_metrics(test_df)
print(result.tail())

关键说明

  1. 滚动窗口逻辑:用window='12M'替代固定行数,保证每个窗口对应真实的12个日历月;min_periods=12过滤掉数据不足12个月的前期窗口。
  2. 年化阿尔法:通过线性回归得到每个窗口内的月度阿尔法(CAPM模型截距),再乘以12转换为年化值。
  3. 年化跟踪误差:先计算窗口内月度超额收益的标准差,再乘以√12完成年化转换(月度转年化的标准操作)。
  4. 滚动收益计算:你的原始代码用rolling.apply(np.prod)的思路是对的,这里扩展到了多列场景,通过(1+月度收益).prod()-1计算累计收益,因窗口是12个月,直接等于年化收益。

内容的提问来源于stack exchange,提问作者NickTheCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:01:06