使用TA-Lib计算RSI与SMA时遇类型错误及参数缺失问题求助
问题修复方案
错误原因分析
- 首次报错:你错误地将DataFrame转成numpy数组传递给
indicators函数——numpy数组不支持df['rsi']这类列赋值操作,且TA-Lib的abstract模块本身可以直接处理DataFrame,完全不需要转数组。 - 二次报错:仅传入收盘价列(Series)时,
abstract.RSI无法识别输入数据对应的字段类型,导致缺少必填的'close'键标识。
修复步骤及代码修改
1. 移除无效提前调用
删除代码中这一行(此时data_prices还未定义,会引发NameError):
abstract.RSI(data_prices, 140)
2. 修改indicators函数调用
直接传入原始DataFrame,不要转成numpy数组:
df = indicators(data_prices, N)
3. 完善indicators函数逻辑
- 给RSI、SMA指定合理的周期参数(可根据需求调整,也可使用默认值)
- 确保FGI数据长度与DataFrame行数一致,避免赋值时长度不匹配
修改后的indicators函数:
def indicators(df, N): # RSI常用周期14,SMA常用周期20,可按需修改 df['rsi'] = abstract.RSI(df, timeperiod=14) df['sma'] = abstract.SMA(df, timeperiod=20) # 按DataFrame实际行数获取FGI数据,避免长度不匹配 fgi_values = parse_fgi(len(df)) df['fgi'] = fgi_values return df
4. (可选)优化FGI日期匹配
如果FGI数据和行情数据日期不完全对齐,可添加日期匹配逻辑,确保值对应正确日期:
def parse_fgi(N): url = "https://api.alternative.me/fng/?format=csv&date_format=us" parameters = { "limit": N, "format": "json" } response = requests.get(url, params=parameters) data = response.json()['data'] # 转换为带日期索引的Series fgi_df = pd.DataFrame(data) fgi_df['value'] = fgi_df['value'].astype(float) fgi_df['timestamp'] = pd.to_datetime(fgi_df['timestamp'], format='%Y-%m-%d') fgi_df = fgi_df.set_index('timestamp').sort_index() return fgi_df['value']
对应修改indicators函数:
def indicators(df, N): df['rsi'] = abstract.RSI(df, timeperiod=14) df['sma'] = abstract.SMA(df, timeperiod=20) fgi_series = parse_fgi(N) # 按行情数据索引对齐FGI值,缺失日期用NaN填充 df['fgi'] = df.index.map(lambda x: fgi_series.get(x, np.nan)) return df
完整修复后代码
import requests from datetime import datetime, timedelta import pandas as pd import talib import numpy as np from talib import abstract import yfinance as yf # 安装TA-Lib(仅首次运行需要) !wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz !tar -xzvf ta-lib-0.4.0-src.tar.gz %cd ta-lib !./configure --prefix=/usr !make !make install !pip install Ta-Lib N = 1400 def parse_fgi(N): url = "https://api.alternative.me/fng/?format=csv&date_format=us" parameters = { "limit": N, "format": "json" } response = requests.get(url, params=parameters) data = response.json()['data'] fgi_values = [float(i['value']) for i in data][::-1] return fgi_values def parse_dates(N): end_date = datetime.today() start_date = end_date - timedelta(days=N) dates = pd.date_range(start=start_date, end=end_date) us_dates = dates.strftime('%Y-%m-%d').tolist() return us_dates def parse_prices(coin, N): period = parse_dates(N) end_time = period[-1] start_time = period[0] data = yf.download(coin+"-USD", start_time, end_time) data.rename(columns = {'Open': 'open', 'High':'high', 'Low': 'low', 'Close': 'close', 'Volume': 'volume'}, inplace = True) return data data_prices = parse_prices("XRP", N) def indicators(df, N): df['rsi'] = abstract.RSI(df, timeperiod=14) df['sma'] = abstract.SMA(df, timeperiod=20) fgi_values = parse_fgi(len(df)) df['fgi'] = fgi_values return df df = indicators(data_prices, N) print(df.head())
内容的提问来源于stack exchange,提问作者aufloren
相关产品推荐
相关产品推荐

