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

Python新手求助:获取定制市场指数的两年历史数据

解决方法

1. 先明确核心问题

你当前的代码只能获取实时当前的股价和市值,而计算跨两年的每日指数需要的是时间序列历史数据,得换用专门获取历史行情的方法。下面用yfinance(你之前用的Ticker类大概率来自这个库)一步步实现。

先安装依赖(如果没装过):

pip install yfinance pandas matplotlib

2. 批量获取历史股价与市值数据

import yfinance as yf
import pandas as pd

# 设置时间范围(近2年)
start_date = pd.Timestamp.today() - pd.DateOffset(years=2)
end_date = pd.Timestamp.today()

# 批量拉取所有股票的历史数据
# auto_adjust=True 自动处理拆股、分红后的收盘价,适合指数计算
data = yf.download(
    tickers_list,
    start=start_date,
    end=end_date,
    auto_adjust=True,
    actions=False
)

# 提取调整后收盘价(核心计算用)
adj_close = data['Adj Close']

# 尝试获取每日市值(部分股票可能无此数据,做降级处理)
try:
    daily_market_cap = data['MarketCap']
except KeyError:
    print("部分股票无历史市值数据,将用最新市值计算固定权重")
    # 获取每只股票最新市值
    ticker_info = yf.Tickers(" ".join(tickers_list)).tickers
    latest_mcap = {}
    for ticker in tickers_list:
        try:
            latest_mcap[ticker] = ticker_info[ticker].info['marketCap']
        except:
            latest_mcap[ticker] = 0  # 处理获取失败的情况
    # 把最新市值转为和股价对齐的时间序列(每日固定值)
    daily_market_cap = pd.DataFrame(index=adj_close.index)
    for ticker in tickers_list:
        daily_market_cap[ticker] = latest_mcap[ticker]

3. 计算市值加权指数值

分两种常用方式,选适合你的:

方式一:固定权重(用最新市值,新手友好)

# 计算总市值
total_mcap = sum(latest_mcap.values())
# 单只股票权重 = 个股市值 / 总市值
weights = {t: m / total_mcap for t, m in latest_mcap.items()}

# 计算每日加权股价总和,再归一化到基准值100(第一天为起点)
weighted_daily = adj_close.multiply(pd.Series(weights), axis=1)
daily_index = weighted_daily.sum(axis=1)
normalized_index = (daily_index / daily_index.iloc[0]) * 100

方式二:浮动权重(每日更新市值,更精准)

# 每日总市值
daily_total_mcap = daily_market_cap.sum(axis=1)
# 每日个股权重
daily_weights = daily_market_cap.div(daily_total_mcap, axis=0)

# 计算每日指数并归一化
weighted_daily = adj_close.multiply(daily_weights, axis=1)
daily_index = weighted_daily.sum(axis=1)
normalized_index = (daily_index / daily_index.iloc[0]) * 100

4. 对标标普500并绘图

import matplotlib.pyplot as plt

# 获取标普500历史数据并归一化
spx_data = yf.download('^SPX', start=start_date, end=end_date, auto_adjust=True)['Adj Close']
spx_normalized = (spx_data / spx_data.iloc[0]) * 100

# 绘图对比
plt.figure(figsize=(12,6))
plt.plot(normalized_index.index, normalized_index, label='定制指数')
plt.plot(spx_normalized.index, spx_normalized, label='标普500')
plt.title('定制指数 vs 标普500(近2年)')
plt.xlabel('日期')
plt.ylabel('指数值(基准=100)')
plt.legend()
plt.grid(True)
plt.show()

补充说明你的原始代码问题

你用的Ticker(all_symbols).price是专门拉取实时快照数据的接口,只能拿到当前时刻的股价和市值,没有时间维度的历史数据,自然无法计算跨日期的指数。要做时间序列分析,必须用yf.download()或Ticker(ticker).history()这类获取历史行情的方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:47:32