从 YouTube 上的定量分析课程中复制一些代码。复制了完全相同的代码,但在我的 Jupyter Notebook 中,弹出了标题中的错误。
from statsmodels.regression.rolling import RollingOLS
import pandas_datareader.data as web
import matplotlib.pyplot as plt
import statsmodels.api as sm
import pandas as pd
import numpy as np
import datetime as dt
import yfinance as yf
import pandas_ta
import warnings
warnings.filterwarnings('ignore')
sp500 = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')[0]
sp500['Symbol'] = sp500['Symbol'].str.replace('.','-')
symbols_list = sp500['Symbol'].unique().tolist()
end_date = '2024-10-9'
start_date = pd.to_datetime(end_date)-pd.DateOffset(365*8)
df = yf.download(tickers=symbols_list,
start=start_date,
end=end_date).stack()
df.index.names = ['date', 'ticker']
df.columns = df.columns.str.lower()
df['garman_klass_vol'] = ((np.log(df['high'])-np.log(df['low']))**2)/2-(2*np.log(2)-1)*((np.log(df['adj close'])-np.log(df['open']))**2)
df['rsi'] = df.groupby(level=1)['adj close'].transform(lambda x: pandas_ta.rsi(close=x, length = 20))
df['bb_low'] = df.groupby(level=1)['adj close'].transform(lambda x: pandas_ta.bbands(close=np.log1p(x), length=20).iloc[:,0]
df
错误指的是“pandas_ta.bbands(close=np.log1p(x), length=20).iloc[:,0]”。为什么这个错误只出现在我的电脑上?不同版本?我该如何解决这个问题?
尝试删除该行,其余代码运行得很好,但该表预计没有 bb_low 列。使用版本 Pandas-ta 0.3.14b0 和 Pandas 2.2.3。
我在可能相同的课程中遇到了同样的问题。错误的原因是一只或多只股票的“调整收盘”价格少于 20 天。这是因为
20
作为 length
传递给 bbands
函数。
如果您使用课程中提供的
end_date
- 2023-09-27
,则不会出现错误。这很可能是因为在 8 年范围内没有新股的数据少于 20 天。
我在下面添加了一些解决方案来解释这种可能性。
sp500 = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')[0]
sp500['Symbol'] = sp500['Symbol'].str.replace('.', '-')
symbols_list = sp500['Symbol'].unique().tolist()
end_date = '2024-08-01'
start_date = pd.to_datetime(end_date) - pd.DateOffset(365*8)
df = yf.download(tickers=symbols_list, start=start_date, end=end_date).stack()
df.index.names = ['date', 'ticker']
df.columns = df.columns.str.lower()
# Check for group sizes
group_sizes = df.groupby(level=1).size()
# Filter groups with size less than the length of the bbands (20)
small_groups = group_sizes[group_sizes < 20]
print("Groups with fewer than 20 rows:\n", small_groups)
length
默认
length
是 14,所以你可以这样做。
df['bb_low'] = df.groupby(level=1)['adj close'].transform(lambda x: pandas_ta.bbands(close=np.log1p(x)).iloc[:,0])
length
小于20df = df.groupby(level=1).filter(lambda x: len(x) >= 20)
df['bb_low'] = df.groupby(level=1)['adj close'].transform(lambda x: pandas_ta.bbands(close=np.log1p(x), length=20).iloc[:,0])
NaN
小于 20,则用 length
填充 bbands 结果df['bb_low'] = df.groupby(level=1)['adj close'].transform(lambda x: pandas_ta.bbands(close=np.log1p(x), length=20).iloc[:,0] if len(x) >= 20 else np.nan)