如何计算log和pct change?使用yfinance提取Adj Close出现KeyError如何解决
报错原因分析
- 缩进错误:
df[i] = data['Adj Close'].pct_change().dropna()这行没有缩进进入for循环,只有最后一个标的的收益率会被写入df,且整个df中从未存入Adj Close字段,后续直接调用df['Adj Close']自然触发KeyError - 逻辑错误:你的需求是计算两个标的各自的对数收益率和百分比收益率,原代码既没有把两个标的的复权收盘价存入df,后续取字段、绘图调用的字段也都是不存在的字段,完全不符合需求逻辑
- 参数误用:代码中同时定义了start/end和period参数,yfinance会优先使用period参数覆盖你设置的时间区间,show_errors参数应为布尔值
True而非字符串"True"
修复后的完整代码
import datetime import pandas as pd import numpy as np import yfinance as yf # 定义时间区间 start = datetime.datetime(2017, 10, 1) end = datetime.datetime.now() symbols = ['BTC-USD', 'ETH-USD'] # 先存储所有标的的复权收盘价 adj_close_df = pd.DataFrame() for i in symbols: data = yf.download(i, start=start, end=end, show_errors=True, interval="1mo") adj_close_df[i] = data['Adj Close'] # 计算每个标的的百分比收益率和对数收益率 returns_df = pd.DataFrame() for col in adj_close_df.columns: # 百分比收益率 returns_df[f'{col}_pct_change'] = adj_close_df[col].pct_change() # 对数收益率 returns_df[f'{col}_log_change'] = np.log(adj_close_df[col] / adj_close_df[col].shift(1)) # 去除空值后绘图 returns_df.dropna().plot(figsize=(12,6), title='BTC-USD vs ETH-USD 收益率对比')
代码说明
- 先单独拉取两个标的的Adj Close数据存入同一个DataFrame,避免后续重复请求数据
- 分别计算每个标的的百分比和对数收益率,字段名带标的标识,方便区分
- 绘图时自动区分不同标的和收益率类型,直接实现对比需求
内容的提问来源于stack exchange,提问作者john
相关产品推荐
相关产品推荐

