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
相关产品推荐
相关产品推荐

