使用yfinance导入Python数据时Adj Close字段失效问题
解决yfinance调用'Adj Close'字段报错的问题
问题诊断
你遇到的核心问题是:使用yfinance 0.2.55获取部分全球指数的周频数据时,data['Adj Close']会触发KeyError,但Open/Close字段正常。这是因为部分指数的周频数据中,yfinance并未返回调整收盘价(Adj Close)字段——虽然日频数据通常包含该字段,但周频聚合数据可能因数据源限制缺失。
验证方法
在get_weekly_returns函数中添加一行代码,打印下载数据的列名,确认是否存在Adj Close:
def get_weekly_returns(ticker, start_date, end_date): try: data = yf.download(ticker, start=start_date, end=end_date, interval='1wk') # 新增:打印列名,排查字段是否存在 print(f"Columns for {ticker}: {data.columns.tolist()}") data['Weekly_Return'] = data['Adj Close'].pct_change() data = data.dropna() return data['Weekly_Return'] except Exception as e: print(f"Error downloading data for {ticker}: {e}") return pd.Series(dtype='float64')
运行后你会发现,部分指数(比如FTSE MIB)的周数据列中没有Adj Close,只有Open/High/Low/Close/Volume。
解决方案
针对这个问题,有两种可靠的处理方式:
方案1:优先使用Adj Close,缺失时降级到Close
修改函数逻辑,先检查Adj Close是否存在,不存在则用Close替代——对于指数来说,两者的差异极小,不会显著影响收益率计算:
def get_weekly_returns(ticker, start_date, end_date): try: data = yf.download(ticker, start=start_date, end=end_date, interval='1wk') # 选择可用的价格字段 price_col = 'Adj Close' if 'Adj Close' in data.columns else 'Close' data['Weekly_Return'] = data[price_col].pct_change() data = data.dropna() return data['Weekly_Return'] except Exception as e: print(f"Error downloading data for {ticker}: {e}") return pd.Series(dtype='float64')
方案2:启用yfinance的自动调整参数
调用yf.download时添加auto_adjust=True,此时返回的Close字段会自动替换为调整后收盘价,无需再调用Adj Close:
def get_weekly_returns(ticker, start_date, end_date): try: # 添加auto_adjust=True,自动调整收盘价 data = yf.download(ticker, start=start_date, end=end_date, interval='1wk', auto_adjust=True) # 直接用Close字段(已自动调整) data['Weekly_Return'] = data['Close'].pct_change() data = data.dropna() return data['Weekly_Return'] except Exception as e: print(f"Error downloading data for {ticker}: {e}") return pd.Series(dtype='float64')
额外提示
- 如果你需要严格的调整收盘价,可以考虑先下载日频数据,手动计算周频调整收盘价(比如取每周最后一个交易日的Adj Close),再计算收益率。
- 不同指数的数据源差异可能导致字段缺失,建议始终添加字段存在性检查,避免代码崩溃。
内容的提问来源于stack exchange,提问作者Chris Cuny
相关产品推荐
相关产品推荐

