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

如何用Pandas批量计算13只ETF的3个月/1年/3年滚动回报并格式化输出

批量处理多只ETF滚动回报与市值计算方案

核心思路

把单只ETF的计算逻辑封装成可复用函数,通过遍历ETF代码列表批量执行计算,最后统一整合结果并输出指定格式表格。

实现步骤与代码示例

1. 数据结构准备

假设你已通过yfinance获取所有ETF的数据,将其整理为字典格式:etf_data,key为ETF代码(如'IVV'、'SPY'),value为包含月度收益率(列名monthly_return)和月度调整后价格(列名Adj Close)的DataFrame,索引为日期(DatetimeIndex)。

import pandas as pd
import yfinance as yf

# 定义13只ETF代码列表
etf_list = ['IVV', 'SPY', 'VOO', 'QQQ', 'IWM', 'EFA', 'EEM', 'AGG', 'BND', 'GLD', 'SLV', 'XLK', 'XLE']
etf_data = {}

# 批量拉取并预处理数据(若已完成数据获取可跳过此步)
for ticker in etf_list:
    df = yf.download(ticker, start='2017-01-31', end='2023-04-01', interval='1mo')
    df['monthly_return'] = df['Adj Close'].pct_change()
    etf_data[ticker] = df[['Adj Close', 'monthly_return']].dropna()

2. 封装单只ETF计算函数

创建函数处理单只ETF的滚动回报计算与市值推导(若有实际份额数据,可替换示例中的固定份额逻辑):

def calculate_etf_metrics(df):
    # 计算滚动回报(用复利方式避免误差)
    df['3mo_rolling_return'] = (1 + df['monthly_return']).rolling(window=3).apply(lambda x: x.prod() - 1, raw=True)
    df['1y_rolling_return'] = (1 + df['monthly_return']).rolling(window=12).apply(lambda x: x.prod() - 1, raw=True)
    df['3y_rolling_return'] = (1 + df['monthly_return']).rolling(window=36).apply(lambda x: x.prod() - 1, raw=True)
    
    # 计算市值(示例用初始固定份额,可替换为实际份额数据)
    initial_shares = 1000000  # 假设初始份额为100万份
    df['market_cap'] = df['Adj Close'] * initial_shares
    
    # 保留需要的输出列
    result = df[['market_cap', '3mo_rolling_return', '1y_rolling_return', '3y_rolling_return']]
    return result

3. 批量执行计算并整合结果

遍历所有ETF,调用函数计算后,将结果合并为带多层索引的统一DataFrame,方便后续格式化输出:

# 存储所有ETF的计算结果
all_results = {}
for ticker in etf_list:
    ticker_df = etf_data[ticker]
    all_results[ticker] = calculate_etf_metrics(ticker_df)

# 合并为多层列索引的DataFrame(行:日期,列:ETF代码+指标)
combined_df = pd.concat(all_results, axis=1)
combined_df.columns = pd.MultiIndex.from_tuples(
    [(ticker, col) for ticker in all_results for col in all_results[ticker].columns],
    names=['ETF', 'Metric']
)

4. 格式化输出表格

根据需求调整输出格式,可直接打印查看或导出为Excel:

# 打印前5行结果(保留4位小数)
print(combined_df.head().round(4))

# 导出为Excel文件(方便后续整理成指定表格格式)
combined_df.to_excel('etf_rolling_metrics.xlsx', freeze_panes=(1,2))

关键说明

  • 滚动回报计算:用(1+收益率).rolling().prod()-1的方式计算复利滚动回报,比直接求和更符合实际收益逻辑。
  • 市值计算:若能获取ETF的实时份额数据(可通过yfinance的ticker.info['sharesOutstanding']获取),替换示例中的固定份额即可得到真实市值。
  • 缺失值处理:滚动窗口计算会产生前N个周期的缺失值(如3年滚动回报前36个月无数据),可根据需求用dropna()或填充方式处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:02:36