Pandas TA
是一个强大的 Python 库,旨在与流行的 Pandas
库无缝集成,轻松地为金融时间序列数据(如股票价格)计算各种技术分析指标。它提供了大量的内置指标,并允许用户通过简单的接口将它们应用于 Pandas DataFrame。
.ta
访问器df.ta.strategy()
批量计算ta.Strategy
类定义复杂策略Pandas TA 是一个 Python 包,它利用 Pandas DataFrame 的强大功能来计算技术分析指标。它提供了一个简单直观的 API,可以轻松地将超过 130 种技术指标和实用函数添加到你的金融数据分析流程中。
.ta
) 使用,代码简洁。Numpy
或优化的 Pandas 操作,性能较好。使用 pip 可以方便地安装:
pip install pandas_ta --upgrade
同时,我们通常需要 pandas
和获取数据的库(如 yfinance
)。
pip install pandas yfinance
Pandas TA 主要操作的对象是包含 OHLCV(开盘价 Open, 最高价 High, 最低价 Low, 收盘价 Close, 成交量 Volume)数据的 Pandas DataFrame。重要的是,列名通常需要是小写的 open
, high
, low
, close
, volume
。如果你的列名不是这样,需要先进行重命名。
import pandas as pd
import pandas_ta as ta
import yfinance as yf
# 1. 获取示例数据 (例如:苹果 AAPL 股票)
ticker = "AAPL"
data = yf.download(ticker, start="2023-01-01", end="2024-01-01")
print("原始数据 (yfinance 下载):")
print(data.head())
# 2. 检查和准备列名 (Pandas TA 默认需要小写)
# yfinance 下载的数据列名通常是首字母大写,需要转换
data.columns = data.columns.str.lower() # 将所有列名转为小写
# 确保包含所需的列 (通常 yfinance 会包含)
required_cols = ['open', 'high', 'low', 'close', 'volume']
if not all(col in data.columns for col in required_cols):
raise ValueError(f"DataFrame 缺少必要的列: {required_cols}")
print("\n准备好的数据 (小写列名):")
print(data.head())
.ta
访问器安装 Pandas TA 后,Pandas DataFrame 对象会增加一个名为 .ta
的访问器 (accessor)。所有技术指标的计算都通过这个访问器来调用。
# 检查 .ta 访问器是否存在
print(f"\nDataFrame 是否有 .ta 属性: {'ta' in dir(data)}")
你可以像调用 DataFrame 的方法一样,通过 .ta
调用指标函数。
# 计算 10 日简单移动平均线 (SMA)
sma_10 = data.ta.sma(length=10)
print("\n计算得到的 10 日 SMA (Pandas Series):")
print(sma_10.head(15)) # 前面会有 NaN 值,因为需要 10 天数据才能计算第一个 SMA
# 计算 14 日相对强弱指数 (RSI)
rsi_14 = data.ta.rsi(length=14)
print("\n计算得到的 14 日 RSI:")
print(rsi_14.head(20)) # 同样,前面会有 NaN
默认情况下,调用指标函数会返回一个 Pandas Series,其索引与原始 DataFrame 相同。
每个指标函数都有其特定的参数。最常见的参数是 length
(计算周期),但其他指标可能有更多参数(例如 MACD 有 fast
, slow
, signal
周期)。你可以通过 help()
函数查看具体指标的参数。
# 查看 SMA 指标的帮助文档
help(ta.sma)
# 计算 MACD (指数平滑移动平均线)
# macd() 函数返回一个包含 MACD 线、信号线 (signal) 和柱状图 (histogram) 的 DataFrame
macd_data = data.ta.macd(fast=12, slow=26, signal=9)
print("\n计算得到的 MACD 数据 (DataFrame):")
print(macd_data.tail())
默认情况下,指标计算返回一个新的 Series 或 DataFrame。通常我们希望将计算结果直接添加到原始 DataFrame 中。这可以通过设置 append=True
参数实现。
# 计算 20 日 EMA 并直接附加到原始 DataFrame
# 注意:这会直接修改 data DataFrame
data.ta.ema(length=20, append=True) # 默认列名为 EMA_20
# 计算 ATR(14) 并附加,自定义列名后缀
data.ta.atr(length=14, append=True, col_names=('ATR_14',)) # 使用 col_names 指定列名
print("\n附加了 EMA 和 ATR 的 DataFrame:")
print(data.tail())
# 检查新添加的列
print("\nDataFrame 的列名:")
print(data.columns)
# 输出会包含 'ema_20' 和 'ATR_14' (注意大小写可能根据 col_names)
当 append=True
时,Pandas TA 会自动生成列名(例如 SMA_10
, RSI_14
, MACD_12_26_9
等),除非你使用 col_names
参数显式指定。对于返回多列的指标(如 MACD, Bollinger Bands),它会添加多列。
Pandas TA 将指标大致分为几类,方便查找和理解:
# 重新加载数据,避免之前附加的列干扰
data = yf.download(ticker, start="2023-01-01", end="2024-01-01")
data.columns = data.columns.str.lower()
# --- 3.2.1 移动平均线 ---
# SMA (Simple Moving Average)
data.ta.sma(length=50, append=True) # SMA_50
# EMA (Exponential Moving Average)
data.ta.ema(length=20, append=True) # EMA_20
# --- 3.2.2 动量指标 ---
# RSI (Relative Strength Index)
data.ta.rsi(length=14, append=True) # RSI_14
# MACD (Moving Average Convergence Divergence)
# 返回多列: MACD_12_26_9, MACDh_12_26_9 (Histogram), MACDs_12_26_9 (Signal)
data.ta.macd(fast=12, slow=26, signal=9, append=True)
# Stochastic Oscillator (%K, %D)
# 返回多列: STOCHk_14_3_3, STOCHd_14_3_3
data.ta.stoch(k=14, d=3, smooth_k=3, append=True)
# --- 3.2.3 波动率指标 ---
# Bollinger Bands (布林带)
# 返回多列: BBL_20_2.0 (下轨), BBM_20_2.0 (中轨/SMA), BBU_20_2.0 (上轨), BBB_20_2.0 (带宽), BBP_20_2.0 (位置百分比)
data.ta.bbands(length=20, std=2, append=True)
# ATR (Average True Range)
data.ta.atr(length=14, append=True) # ATR_14
# --- 3.2.4 成交量指标 ---
# OBV (On Balance Volume)
data.ta.obv(append=True) # OBV
# MFI (Money Flow Index)
data.ta.mfi(length=14, append=True) # MFI_14
# --- 3.2.5 趋势指标 ---
# ADX (Average Directional Movement Index)
# 返回多列: ADX_14, DMP_14 (+DI), DMN_14 (-DI)
data.ta.adx(length=14, append=True)
# --- 3.2.6 其他指标 ---
# Z-Score (标准化分数)
data.ta.zscore(length=30, append=True) # Z_30
# --- 3.2.7 K线形态 ---
# 查找 Doji K线 (注意:K线形态通常返回 0 或 100/-100/特定值,表示是否出现)
data.ta.cdl_doji(append=True) # CDL_DOJI
print("\n计算并附加了多个指标后的 DataFrame (尾部):")
print(data.tail())
print("\n所有列名:")
print(data.columns)
# 1. 获取单个指标的帮助
help(ta.rsi)
help(ta.bbands)
# 2. 列出所有可用指标
all_indicators = ta.indicators(as_list=True)
print(f"\nPandas TA 支持的总指标数: {len(all_indicators)}")
print("部分指标名称示例:")
print(all_indicators[::10]) # 每隔 10 个显示一个
# 3. 按类别搜索指标
# momentum_indicators = ta.momentum() # Pandas TA 版本更新可能改变此接口
# 查找包含 'macd' 的指标
# print("\n包含 'macd' 的指标:")
# print([ind for ind in all_indicators if 'macd' in ind.lower()])
# 最新版本可能推荐直接查阅文档或使用 help(ta)
# 4. 检查 ta 对象本身的方法
# print(dir(ta)) # 可以看到所有直接可用的指标函数
当需要一次性计算多个预定义的指标组合时,使用“策略”功能会非常高效和方便。
在 Pandas TA 中,策略本质上是一个预定义的指标计算列表。你可以将常用的指标及其参数组合成一个策略,然后一次性应用到 DataFrame 上。
df.ta.strategy()
批量计算df.ta.strategy()
方法允许你传入一个策略定义(或策略名称,如果库内置了的话),然后批量计算并(可选地)附加结果。
最简单的策略定义方式是使用一个列表,列表中的每个元素可以是一个指标名称字符串(使用默认参数),或者是一个包含 kind
(指标名称) 和其他参数的字典。
# 重新加载干净的数据
data = yf.download(ticker, start="2023-01-01", end="2024-01-01")
data.columns = data.columns.str.lower()
# 定义一个简单的策略列表
my_strategy_list = [
"sma", # 计算 SMA,使用默认 length=10
{"kind": "sma", "length": 50}, # 计算 SMA(50)
{"kind": "rsi", "length": 14}, # 计算 RSI(14)
{"kind": "bbands", "length": 20, "std": 2.0}, # 计算 Bollinger Bands(20, 2)
"macd" # 计算 MACD,使用默认参数 12, 26, 9
]
# 将策略应用到 DataFrame,结果会自动附加
data.ta.strategy(my_strategy_list)
print("\n使用列表策略计算后的 DataFrame (尾部):")
print(data.tail())
print("\nDataFrame 列名:")
print(data.columns) # 会包含 SMA_10, SMA_50, RSI_14, BBL_20_2.0 等
ta.Strategy
类定义复杂策略对于更复杂或需要复用的策略,可以使用 ta.Strategy
类来定义。
# 重新加载干净的数据
data = yf.download(ticker, start="2023-01-01", end="2024-01-01")
data.columns = data.columns.str.lower()
# 定义一个 Strategy 对象
MyCoolStrategy = ta.Strategy(
name="CoolTechIndicators",
description="SMA(20/50), RSI(14), and MACD(12/26/9)",
ta=[
{"kind": "sma", "length": 20},
{"kind": "sma", "length": 50},
{"kind": "rsi", "length": 14},
{"kind": "macd", "fast": 12, "slow": 26, "signal": 9}
]
)
print(f"\n创建的策略对象: {MyCoolStrategy}")
# 应用策略实例到 DataFrame
data.ta.strategy(MyCoolStrategy)
print("\n使用 Strategy 类计算后的 DataFrame (尾部):")
print(data.tail())
print("\nDataFrame 列名:")
print(data.columns) # 包含 SMA_20, SMA_50, RSI_14, MACD_12_26_9 等
使用 ta.Strategy
类的好处是:
上面两个例子已经展示了如何应用自定义策略。核心就是调用 df.ta.strategy()
并传入你的策略定义(列表或 ta.Strategy
对象)。
大多数技术指标都需要一定的历史数据才能开始计算(例如,SMA(20) 需要前 20 天的数据)。因此,计算结果的开头部分会出现 NaN
(Not a Number) 值。
在进行后续分析或模型训练时,通常需要处理这些 NaN 值:
df.dropna()
删除包含 NaN 的行。这是最简单的方法,但会损失一部分初始数据。df.fillna()
方法填充 NaN 值(例如用 0、前一个值 method='ffill'
或均值填充),但这对于技术指标通常不太合适,可能引入偏差。data_with_nan = yf.download(ticker, start="2023-01-01", end="2024-01-01")
data_with_nan.columns = data_with_nan.columns.str.lower()
data_with_nan.ta.sma(length=50, append=True)
print(f"\n计算 SMA(50) 后包含 NaN 的行数: {data_with_nan['SMA_50'].isna().sum()}")
print("前几行数据,显示 NaN:")
print(data_with_nan.head(5))
# 删除包含 NaN 的行
data_no_nan = data_with_nan.dropna()
print(f"\n删除 NaN 后的数据行数: {len(data_no_nan)}")
print(f"删除 NaN 后 SMA(50) 列的 NaN 数量: {data_no_nan['SMA_50'].isna().sum()}")
print("删除 NaN 后的前几行数据:")
print(data_no_nan.head(5))
再次强调,Pandas TA 默认期望 DataFrame 的列名为小写的 open
, high
, low
, close
, volume
。如果你的数据源提供的列名不同(例如 Open
, High
, Last
, Vol.
),你需要在使用 .ta
之前进行重命名。
# 假设你的 DataFrame 列名是这样的
df_bad_names = pd.DataFrame({
'Date': pd.to_datetime(['2023-01-01', '2023-01-02']),
'Price Open': [100, 101],
'Highest Price': [102, 103],
'Lowest Price': [99, 100],
'Last Price': [101, 102],
'Volume Traded': [10000, 12000]
})
df_bad_names = df_bad_names.set_index('Date')
# 重命名以符合 Pandas TA 的要求
# 方法一:手动指定
df_renamed = df_bad_names.rename(columns={
'Price Open': 'open',
'Highest Price': 'high',
'Lowest Price': 'low',
'Last Price': 'close', # 注意:通常用 'close' 而不是 'Last Price'
'Volume Traded': 'volume'
})
# 方法二:如果只是大小写问题,可以统一转换
# df_bad_names.columns = df_bad_names.columns.str.lower().str.replace(' ', '_') # 示例性转换
# 现在可以在 df_renamed 上使用 .ta
# df_renamed.ta.sma(append=True)
print("\n重命名后的 DataFrame:")
print(df_renamed)
虽然 Pandas TA 有时会尝试智能地识别列,但显式地将列名设置为标准的小写格式是最可靠的方式。
df.ta.strategy()
通常比在循环中逐个调用指标函数要快,因为它可以在内部进行优化。Numba
或其他加速库的技术分析实现(但这通常需要更多编程工作)。Pandas TA 计算出的指标可以直接用常见的 Python 可视化库绘制出来。
import matplotlib.pyplot as plt
# 获取数据并计算布林带
data = yf.download(ticker, start="2023-06-01", end="2024-01-01")
data.columns = data.columns.str.lower()
data.ta.bbands(length=20, std=2, append=True) # 计算并附加 BBands
# 绘制收盘价和布林带
plt.figure(figsize=(12, 6))
plt.plot(data.index, data['close'], label='Close Price', color='blue', alpha=0.6)
plt.plot(data.index, data['BBU_20_2.0'], label='Upper Band', color='red', linestyle='--', alpha=0.7)
plt.plot(data.index, data['BBM_20_2.0'], label='Middle Band (SMA20)', color='orange', linestyle='--', alpha=0.7)
plt.plot(data.index, data['BBL_20_2.0'], label='Lower Band', color='green', linestyle='--', alpha=0.7)
# 填充布林带区域
plt.fill_between(data.index, data['BBL_20_2.0'], data['BBU_20_2.0'], color='grey', alpha=0.1)
plt.title(f'{ticker} Stock Price with Bollinger Bands (20, 2)')
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend()
plt.grid(True)
plt.show()
# 绘制 RSI
plt.figure(figsize=(12, 4))
data.ta.rsi(length=14, append=True) # 计算 RSI
plt.plot(data.index, data['RSI_14'], label='RSI (14)', color='purple')
plt.axhline(70, linestyle='--', alpha=0.5, color='red', label='Overbought (70)') # 超买线
plt.axhline(30, linestyle='--', alpha=0.5, color='green', label='Oversold (30)') # 超卖线
plt.title(f'{ticker} Relative Strength Index (RSI)')
plt.xlabel('Date')
plt.ylabel('RSI Value')
plt.legend()
plt.grid(True)
plt.show()
Pandas TA 是一个非常实用的 Python 库,极大地简化了在 Pandas DataFrame 中计算技术分析指标的过程。关键要点包括:
open
, high
, low
, close
, volume
列的 DataFrame。.ta
访问器调用指标函数(如 df.ta.sma()
, df.ta.rsi()
, df.ta.macd()
)。append=True
将计算结果直接添加到 DataFrame 中。df.ta.strategy()
或 ta.Strategy
类可以高效地批量计算多个指标。NaN
值。要深入学习,建议:
ta.indicators()
查看完整列表,并尝试计算不熟悉的指标。希望这个深度解析教程能帮助你有效地使用 Pandas TA 进行金融数据分析!