P
PipsGrowth
← Back to Libraries

pandas-ta for Trading

A feature-rich technical analysis library that extends pandas DataFrames with 130+ indicators, candlestick patterns, and performance metrics. The go-to library for efficient indicator calculations.

Difficulty: Beginner
Category: Technical Analysis
📊 130+ Indicators

Installation

Install pandas-ta with pip. It requires pandas and numpy which will be installed automatically.

# Install pandas-ta
$ pip install pandas-ta
# Install with data sources
$ pip install pandas-ta yfinance

Available Indicators

Overlap

SMA, EMA, WMA, DEMA, TEMA, VWAP, Bollinger Bands, Keltner Channels

Momentum

RSI, MACD, Stochastic, CCI, Williams %R, ROC, Ultimate Oscillator

Trend

ADX, Aroon, PSAR, Supertrend, Ichimoku, Pivot Points

Volatility

ATR, Bollinger Width, Keltner Width, Donchian Channels

Volume

OBV, CMF, MFI, VWAP, AD, Force Index

Candles

Doji, Hammer, Engulfing, Morning Star, Evening Star, Harami

Key Features

130+ Indicators

Comprehensive library covering momentum, trend, volatility, volume, and overlap indicators.

Native pandas Integration

Works directly with pandas DataFrames using df.ta syntax for seamless workflow.

Strategy Builder

Create custom indicator strategies and apply multiple indicators at once.

Performance Metrics

Built-in functions for returns, drawdown, and other trading performance analytics.

Code Examples

Add Multiple Indicators at Once

Apply common indicators with a single line

Python
import pandas as pd
import pandas_ta as ta
import yfinance as yf
# Download data
df = yf.download('EURUSD=X', period='1y', interval='1d')
# Add single indicator
df['RSI_14'] = ta.rsi(df['Close'], length=14)
df['SMA_50'] = ta.sma(df['Close'], length=50)
df['EMA_20'] = ta.ema(df['Close'], length=20)
# Or add multiple indicators using strategy
df.ta.strategy('AllSMA') # Adds all SMA variations
print(df.tail())

Create Custom Indicator Strategy

Define your own indicator combinations

Python
import pandas_ta as ta
# Create a custom strategy
CustomStrategy = ta.Strategy(
name="Forex Strategy",
description="Custom forex trading indicators",
ta=[
{"kind": "sma", "length": 20},
{"kind": "sma", "length": 50},
{"kind": "sma", "length": 200},
{"kind": "rsi", "length": 14},
{"kind": "macd", "fast": 12, "slow": 26, "signal": 9},
{"kind": "bbands", "length": 20, "std": 2},
{"kind": "atr", "length": 14},
{"kind": "adx", "length": 14},
]
)
# Apply strategy to dataframe
df.ta.strategy(CustomStrategy)
# Check new columns
print("Added columns:", [col for col in df.columns if col not in ['Open','High','Low','Close','Volume']])

Momentum Indicators Suite

RSI, MACD, Stochastic, and more

Python
import pandas_ta as ta
# RSI with overbought/oversold signals
df['RSI'] = ta.rsi(df['Close'], length=14)
df['RSI_Signal'] = 'Neutral'
df.loc[df['RSI'] > 70, 'RSI_Signal'] = 'Overbought'
df.loc[df['RSI'] < 30, 'RSI_Signal'] = 'Oversold'
# MACD
macd = ta.macd(df['Close'], fast=12, slow=26, signal=9)
df = pd.concat([df, macd], axis=1)
# Stochastic Oscillator
stoch = ta.stoch(df['High'], df['Low'], df['Close'], k=14, d=3)
df = pd.concat([df, stoch], axis=1)
# Williams %R
df['WILLR'] = ta.willr(df['High'], df['Low'], df['Close'], length=14)
# CCI - Commodity Channel Index
df['CCI'] = ta.cci(df['High'], df['Low'], df['Close'], length=20)
print(df[['Close', 'RSI', 'MACD_12_26_9', 'STOCHk_14_3_3', 'WILLR_14', 'CCI_20']].tail())

Trend & Volatility Indicators

ADX, ATR, Bollinger Bands, and more

Python
import pandas_ta as ta
# ADX - Average Directional Index
adx = ta.adx(df['High'], df['Low'], df['Close'], length=14)
df = pd.concat([df, adx], axis=1)
# ATR - Average True Range
df['ATR'] = ta.atr(df['High'], df['Low'], df['Close'], length=14)
# Bollinger Bands
bbands = ta.bbands(df['Close'], length=20, std=2)
df = pd.concat([df, bbands], axis=1)
# Keltner Channels
kc = ta.kc(df['High'], df['Low'], df['Close'], length=20)
df = pd.concat([df, kc], axis=1)
# Donchian Channels
donchian = ta.donchian(df['High'], df['Low'], lower_length=20, upper_length=20)
df = pd.concat([df, donchian], axis=1)
# Identify trend strength
df['Trend_Strength'] = 'Weak'
df.loc[df['ADX_14'] > 25, 'Trend_Strength'] = 'Strong'
df.loc[df['ADX_14'] > 50, 'Trend_Strength'] = 'Very Strong'
print(df[['Close', 'ADX_14', 'ATR_14', 'BBU_20_2.0', 'BBL_20_2.0', 'Trend_Strength']].tail())

Generate Trading Signals

Combine indicators for entry/exit signals

Python
import pandas_ta as ta
import numpy as np
# Calculate indicators
df['RSI'] = ta.rsi(df['Close'], length=14)
df['SMA_50'] = ta.sma(df['Close'], length=50)
df['SMA_200'] = ta.sma(df['Close'], length=200)
macd = ta.macd(df['Close'])
df = pd.concat([df, macd], axis=1)
# Generate signals
def generate_signals(row):
score = 0
# Trend condition (SMA crossover)
if row['SMA_50'] > row['SMA_200']:
score += 1
elif row['SMA_50'] < row['SMA_200']:
score -= 1
# Momentum condition (RSI)
if row['RSI'] < 30:
score += 1 # Oversold = potential buy
elif row['RSI'] > 70:
score -= 1 # Overbought = potential sell
# MACD condition
if row['MACD_12_26_9'] > row['MACDs_12_26_9']:
score += 1
else:
score -= 1
return score
df['Signal_Score'] = df.apply(generate_signals, axis=1)
df['Signal'] = 'HOLD'
df.loc[df['Signal_Score'] >= 2, 'Signal'] = 'BUY'
df.loc[df['Signal_Score'] <= -2, 'Signal'] = 'SELL'
# View signals
signals = df[df['Signal'] != 'HOLD'][['Close', 'RSI', 'MACD_12_26_9', 'Signal_Score', 'Signal']]
print(signals.tail(10))

Volume Indicators

OBV, CMF, MFI, and volume analysis

Python
import pandas_ta as ta
# On-Balance Volume
df['OBV'] = ta.obv(df['Close'], df['Volume'])
# Chaikin Money Flow
df['CMF'] = ta.cmf(df['High'], df['Low'], df['Close'], df['Volume'], length=20)
# Money Flow Index
df['MFI'] = ta.mfi(df['High'], df['Low'], df['Close'], df['Volume'], length=14)
# Volume Weighted Average Price
df['VWAP'] = ta.vwap(df['High'], df['Low'], df['Close'], df['Volume'])
# Accumulation/Distribution
df['AD'] = ta.ad(df['High'], df['Low'], df['Close'], df['Volume'])
# Volume SMA for comparison
df['Volume_SMA'] = ta.sma(df['Volume'], length=20)
df['Volume_Ratio'] = df['Volume'] / df['Volume_SMA']
# Volume breakout detection
df['High_Volume'] = df['Volume_Ratio'] > 1.5
print(df[['Close', 'Volume', 'OBV', 'MFI', 'CMF', 'High_Volume']].tail())

Candlestick Pattern Recognition

Detect candlestick patterns automatically

Python
import pandas_ta as ta
# Detect candlestick patterns
# Doji
df['DOJI'] = ta.cdl_doji(df['Open'], df['High'], df['Low'], df['Close'])
# Hammer
df['HAMMER'] = ta.cdl_hammer(df['Open'], df['High'], df['Low'], df['Close'])
# Engulfing
engulfing = ta.cdl_pattern(df['Open'], df['High'], df['Low'], df['Close'], name='engulfing')
if engulfing is not None:
df['ENGULFING'] = engulfing
# Morning/Evening Star
morning_star = ta.cdl_pattern(df['Open'], df['High'], df['Low'], df['Close'], name='morningstar')
if morning_star is not None:
df['MORNING_STAR'] = morning_star
# Filter days with patterns
pattern_cols = [col for col in df.columns if 'CDL' in col or col in ['DOJI', 'HAMMER', 'ENGULFING', 'MORNING_STAR']]
patterns_found = df[pattern_cols].apply(lambda x: x != 0).any(axis=1)
print(f"Days with patterns: {patterns_found.sum()}")
print(df[patterns_found][['Close'] + pattern_cols].tail())

Performance Metrics

Calculate trading performance statistics

Python
import pandas_ta as ta
# Calculate returns
df['Returns'] = df['Close'].pct_change()
df['Log_Returns'] = ta.log_return(df['Close'])
# Cumulative returns
df['Cumulative'] = (1 + df['Returns']).cumprod()
# Performance metrics using pandas_ta
# Drawdown
drawdown = ta.drawdown(df['Close'])
df = pd.concat([df, drawdown], axis=1)
# Calculate Sharpe-like metrics
returns = df['Returns'].dropna()
mean_return = returns.mean() * 252 # Annualized
std_return = returns.std() * (252 ** 0.5) # Annualized
sharpe = mean_return / std_return
# Win rate
wins = (returns > 0).sum()
losses = (returns < 0).sum()
win_rate = wins / (wins + losses)
print(f"Annualized Return: {mean_return:.2%}")
print(f"Annualized Volatility: {std_return:.2%}")
print(f"Sharpe Ratio: {sharpe:.2f}")
print(f"Win Rate: {win_rate:.2%}")
print(f"Max Drawdown: {df['DD_PCT'].min():.2%}")

Common Use Cases

Quick indicator calculation
Multi-indicator strategy building
Candlestick pattern detection
Volume analysis
Trend identification
Momentum screening
Volatility measurement
Performance analytics
Signal generation
Technical screening

Best Practices & Common Pitfalls

Use Strategies for Bulk Indicators

Create ta.Strategy() objects to apply multiple indicators efficiently instead of calling each separately.

Handle Column Names

pandas_ta auto-generates column names. Use df.columns to verify names before accessing (e.g., MACD_12_26_9).

Combine with pandas

Leverage pandas filtering and groupby with pandas_ta indicators for powerful analysis.

Check for NaN Values

Early rows will have NaN for indicators with lookback periods. Always handle these before backtesting.

Verify Indicator Parameters

Different sources may define indicators differently. Verify parameters match your expectations.

Candlestick Pattern Returns

Pattern functions return 0, 100, or -100 (bullish/bearish), not boolean. Handle accordingly.

Additional Resources

Related Libraries

  • TA-Lib - Alternative indicator library
  • finta - Financial indicator library
  • tulipy - Tulip Indicators wrapper

Next Steps

Now that you can calculate indicators, learn to backtest strategies and connect to live trading: