Technical Analysis Library in Python for financial time series datasets with 43 indicators across Volume, Volatility, Trend, Momentum, and Others categories
Volatility-based technical indicators that measure the degree of price variation and market uncertainty. These indicators help traders assess market conditions, identify potential breakouts, determine support and resistance levels, and gauge the likelihood of significant price movements.
Provides an indication of the degree of price volatility by measuring the average range between high and low prices over a specified period.
class AverageTrueRange:
def __init__(self, high, low, close, window=14, fillna=False):
"""
Average True Range (ATR).
Parameters:
- high (Series): Dataset 'High' column
- low (Series): Dataset 'Low' column
- close (Series): Dataset 'Close' column
- window (int): Period for calculation (default: 14)
- fillna (bool): If True, fill NaN values (default: False)
"""
def average_true_range(self):
"""Returns: Series with Average True Range values"""
def average_true_range(high, low, close, window=14, fillna=False):
"""Functional interface for Average True Range"""Volatility bands placed above and below a moving average that expand and contract based on market volatility, useful for identifying overbought and oversold conditions.
class BollingerBands:
def __init__(self, close, window=20, window_dev=2, fillna=False):
"""
Bollinger Bands.
Parameters:
- close (Series): Dataset 'Close' column
- window (int): Period for moving average (default: 20)
- window_dev (int): Standard deviation factor (default: 2)
- fillna (bool): If True, fill NaN values (default: False)
"""
def bollinger_mavg(self):
"""Returns: Series with Bollinger Channel Middle Band (SMA)"""
def bollinger_hband(self):
"""Returns: Series with Bollinger Channel High Band (Upper)"""
def bollinger_lband(self):
"""Returns: Series with Bollinger Channel Low Band (Lower)"""
def bollinger_wband(self):
"""Returns: Series with Bollinger Channel Band Width"""
def bollinger_pband(self):
"""Returns: Series with Bollinger Channel Percentage Band (%B)"""
def bollinger_hband_indicator(self):
"""Returns: Series with Bollinger High Band Indicator (binary signal)"""
def bollinger_lband_indicator(self):
"""Returns: Series with Bollinger Low Band Indicator (binary signal)"""
def bollinger_mavg(close, window=20, fillna=False):
"""Functional interface for Bollinger Middle Band"""
def bollinger_hband(close, window=20, window_dev=2, fillna=False):
"""Functional interface for Bollinger High Band"""
def bollinger_lband(close, window=20, window_dev=2, fillna=False):
"""Functional interface for Bollinger Low Band"""
def bollinger_wband(close, window=20, window_dev=2, fillna=False):
"""Functional interface for Bollinger Band Width"""
def bollinger_pband(close, window=20, window_dev=2, fillna=False):
"""Functional interface for Bollinger Percentage Band"""
def bollinger_hband_indicator(close, window=20, window_dev=2, fillna=False):
"""Functional interface for Bollinger High Band Indicator"""
def bollinger_lband_indicator(close, window=20, window_dev=2, fillna=False):
"""Functional interface for Bollinger Low Band Indicator"""Trend-following indicator used to identify reversals with channel breakouts and closures, based on exponential moving average and Average True Range.
class KeltnerChannel:
def __init__(self, high, low, close, window=20, window_atr=10, fillna=False,
original_version=True, multiplier=2):
"""
Keltner Channel.
Parameters:
- high (Series): Dataset 'High' column
- low (Series): Dataset 'Low' column
- close (Series): Dataset 'Close' column
- window (int): Period for centerline calculation (default: 20)
- window_atr (int): Period for ATR calculation (default: 10)
- fillna (bool): If True, fill NaN values (default: False)
- original_version (bool): If True, use original version as centerline (default: False)
- multiplier (int): Multiplier for channel width (default: 2)
"""
def keltner_channel_mband(self):
"""Returns: Series with Keltner Channel Middle Band (centerline)"""
def keltner_channel_hband(self):
"""Returns: Series with Keltner Channel High Band (upper)"""
def keltner_channel_lband(self):
"""Returns: Series with Keltner Channel Low Band (lower)"""
def keltner_channel_wband(self):
"""Returns: Series with Keltner Channel Band Width"""
def keltner_channel_pband(self):
"""Returns: Series with Keltner Channel Percentage Band"""
def keltner_channel_hband_indicator(self):
"""Returns: Series with Keltner High Band Indicator (binary signal)"""
def keltner_channel_lband_indicator(self):
"""Returns: Series with Keltner Low Band Indicator (binary signal)"""
def keltner_channel_mband(high, low, close, window=20, window_atr=10, fillna=False,
original_version=False, multiplier=2):
"""Functional interface for Keltner Channel Middle Band"""
def keltner_channel_hband(high, low, close, window=20, window_atr=10, fillna=False,
original_version=False, multiplier=2):
"""Functional interface for Keltner Channel High Band"""
def keltner_channel_lband(high, low, close, window=20, window_atr=10, fillna=False,
original_version=False, multiplier=2):
"""Functional interface for Keltner Channel Low Band"""
def keltner_channel_wband(high, low, close, window=20, window_atr=10, fillna=False,
original_version=False, multiplier=2):
"""Functional interface for Keltner Channel Band Width"""
def keltner_channel_pband(high, low, close, window=20, window_atr=10, fillna=False,
original_version=False, multiplier=2):
"""Functional interface for Keltner Channel Percentage Band"""
def keltner_channel_hband_indicator(high, low, close, window=20, window_atr=10,
fillna=False, original_version=False, multiplier=2):
"""Functional interface for Keltner Channel High Band Indicator"""
def keltner_channel_lband_indicator(high, low, close, window=20, window_atr=10,
fillna=False, original_version=False, multiplier=2):
"""Functional interface for Keltner Channel Low Band Indicator"""Channel-based indicator that identifies the highest high and lowest low over a specified period, useful for breakout strategies and trend identification.
class DonchianChannel:
def __init__(self, high, low, close, window=20, offset=0, fillna=False):
"""
Donchian Channel.
Parameters:
- high (Series): Dataset 'High' column
- low (Series): Dataset 'Low' column
- close (Series): Dataset 'Close' column
- window (int): Period for calculation (default: 20)
- offset (int): Offset for calculation (default: 0)
- fillna (bool): If True, fill NaN values (default: False)
"""
def donchian_channel_hband(self):
"""Returns: Series with Donchian Channel High Band (highest high)"""
def donchian_channel_lband(self):
"""Returns: Series with Donchian Channel Low Band (lowest low)"""
def donchian_channel_mband(self):
"""Returns: Series with Donchian Channel Middle Band (midpoint)"""
def donchian_channel_wband(self):
"""Returns: Series with Donchian Channel Band Width"""
def donchian_channel_pband(self):
"""Returns: Series with Donchian Channel Percentage Band"""
def donchian_channel_hband(high, low, close, window=20, offset=0, fillna=False):
"""Functional interface for Donchian Channel High Band"""
def donchian_channel_lband(high, low, close, window=20, offset=0, fillna=False):
"""Functional interface for Donchian Channel Low Band"""
def donchian_channel_mband(high, low, close, window=10, offset=0, fillna=False):
"""Functional interface for Donchian Channel Middle Band"""
def donchian_channel_wband(high, low, close, window=10, offset=0, fillna=False):
"""Functional interface for Donchian Channel Band Width"""
def donchian_channel_pband(high, low, close, window=10, offset=0, fillna=False):
"""Functional interface for Donchian Channel Percentage Band"""Measures downside risk by calculating the percentage drawdown from the highest high over a specified period, focusing on the depth and duration of drawdowns.
class UlcerIndex:
def __init__(self, close, window=14, fillna=False):
"""
Ulcer Index.
Parameters:
- close (Series): Dataset 'Close' column
- window (int): Period for calculation (default: 14)
- fillna (bool): If True, fill NaN values (default: False)
"""
def ulcer_index(self):
"""Returns: Series with Ulcer Index values (downside risk measure)"""
def ulcer_index(close, window=14, fillna=False):
"""Functional interface for Ulcer Index"""from ta.volatility import *
import pandas as pd
def analyze_volatility(df):
# Basic volatility measures
df['ATR'] = average_true_range(df['High'], df['Low'], df['Close'])
df['Ulcer'] = ulcer_index(df['Close'])
# Bollinger Bands analysis
df['BB_Middle'] = bollinger_mavg(df['Close'])
df['BB_Upper'] = bollinger_hband(df['Close'])
df['BB_Lower'] = bollinger_lband(df['Close'])
df['BB_Width'] = bollinger_wband(df['Close'])
df['BB_Percent'] = bollinger_pband(df['Close'])
# Channel breakout indicators
df['Keltner_Upper'] = keltner_channel_hband(df['High'], df['Low'], df['Close'])
df['Keltner_Lower'] = keltner_channel_lband(df['High'], df['Low'], df['Close'])
df['Donchian_Upper'] = donchian_channel_hband(df['High'], df['Low'], df['Close'])
df['Donchian_Lower'] = donchian_channel_lband(df['High'], df['Low'], df['Close'])
return df
# Apply volatility analysis
df_volatility = analyze_volatility(df)from ta.volatility import BollingerBands
# Create Bollinger Bands indicator
bb_indicator = BollingerBands(
close=df['Close'],
window=20,
window_dev=2
)
# Calculate all Bollinger Band components
df['BB_Middle'] = bb_indicator.bollinger_mavg()
df['BB_Upper'] = bb_indicator.bollinger_hband()
df['BB_Lower'] = bb_indicator.bollinger_lband()
df['BB_Width'] = bb_indicator.bollinger_wband()
df['BB_Percent'] = bb_indicator.bollinger_pband()
# Generate trading signals
df['BB_Upper_Signal'] = bb_indicator.bollinger_hband_indicator()
df['BB_Lower_Signal'] = bb_indicator.bollinger_lband_indicator()
# Bollinger Band squeeze detection (low volatility)
df['BB_Squeeze'] = df['BB_Width'] < df['BB_Width'].rolling(20).quantile(0.2)
# Bollinger Band expansion (high volatility)
df['BB_Expansion'] = df['BB_Width'] > df['BB_Width'].rolling(20).quantile(0.8)
# Trading signals based on band position
df['BB_Buy_Signal'] = (df['Close'] <= df['BB_Lower']) & (df['BB_Percent'] < 0.05)
df['BB_Sell_Signal'] = (df['Close'] >= df['BB_Upper']) & (df['BB_Percent'] > 0.95)from ta.volatility import KeltnerChannel, DonchianChannel
# Multi-channel breakout system
def channel_breakout_analysis(df):
# Keltner Channels
keltner = KeltnerChannel(
high=df['High'],
low=df['Low'],
close=df['Close'],
window=20,
window_atr=10,
multiplier=2
)
# Donchian Channels
donchian = DonchianChannel(
high=df['High'],
low=df['Low'],
close=df['Close'],
window=20
)
# Calculate channel values
df['Keltner_Upper'] = keltner.keltner_channel_hband()
df['Keltner_Lower'] = keltner.keltner_channel_lband()
df['Keltner_Middle'] = keltner.keltner_channel_mband()
df['Donchian_Upper'] = donchian.donchian_channel_hband()
df['Donchian_Lower'] = donchian.donchian_channel_lband()
df['Donchian_Middle'] = donchian.donchian_channel_mband()
# Breakout signals
df['Keltner_Breakout_Up'] = keltner.keltner_channel_hband_indicator()
df['Keltner_Breakout_Down'] = keltner.keltner_channel_lband_indicator()
# Channel width for volatility assessment
df['Keltner_Width'] = keltner.keltner_channel_wband()
df['Donchian_Width'] = donchian.donchian_channel_wband()
# Combined breakout signal (both channels agree)
df['Combined_Breakout_Up'] = (
(df['Close'] > df['Keltner_Upper']) &
(df['Close'] > df['Donchian_Upper'])
)
df['Combined_Breakout_Down'] = (
(df['Close'] < df['Keltner_Lower']) &
(df['Close'] < df['Donchian_Lower'])
)
return df
df_channels = channel_breakout_analysis(df)from ta.volatility import AverageTrueRange, UlcerIndex
# Advanced volatility regime analysis
def volatility_regime_analysis(df):
# Calculate volatility measures
atr_indicator = AverageTrueRange(
high=df['High'],
low=df['Low'],
close=df['Close'],
window=14
)
ulcer_indicator = UlcerIndex(
close=df['Close'],
window=14
)
df['ATR'] = atr_indicator.average_true_range()
df['Ulcer'] = ulcer_indicator.ulcer_index()
# Normalized ATR (as percentage of price)
df['ATR_Percent'] = (df['ATR'] / df['Close']) * 100
# Volatility percentiles for regime classification
df['ATR_Percentile'] = df['ATR_Percent'].rolling(252).rank(pct=True)
df['Ulcer_Percentile'] = df['Ulcer'].rolling(252).rank(pct=True)
# Volatility regimes
df['Volatility_Regime'] = pd.cut(
df['ATR_Percentile'],
bins=[0, 0.33, 0.66, 1.0],
labels=['Low', 'Medium', 'High']
)
# Risk-adjusted signals based on volatility regime
df['Risk_Adjusted_Position_Size'] = np.where(
df['Volatility_Regime'] == 'High', 0.5, # Reduce size in high vol
np.where(df['Volatility_Regime'] == 'Low', 1.5, 1.0) # Increase in low vol
)
# Downside risk assessment
df['High_Downside_Risk'] = df['Ulcer_Percentile'] > 0.8
return df
df_volatility_regime = volatility_regime_analysis(df)from ta.volatility import *
# Multi-timeframe volatility assessment
def multi_timeframe_volatility(df):
# Short-term volatility (5-day)
df['ATR_Short'] = average_true_range(df['High'], df['Low'], df['Close'], window=5)
df['BB_Width_Short'] = bollinger_wband(df['Close'], window=10, window_dev=2)
# Medium-term volatility (20-day)
df['ATR_Medium'] = average_true_range(df['High'], df['Low'], df['Close'], window=20)
df['BB_Width_Medium'] = bollinger_wband(df['Close'], window=20, window_dev=2)
# Long-term volatility (50-day)
df['ATR_Long'] = average_true_range(df['High'], df['Low'], df['Close'], window=50)
df['BB_Width_Long'] = bollinger_wband(df['Close'], window=50, window_dev=2)
# Volatility term structure analysis
df['Vol_Term_Structure'] = df['ATR_Short'] / df['ATR_Long']
# Volatility momentum (expanding vs contracting)
df['Vol_Momentum'] = (
(df['BB_Width_Short'] > df['BB_Width_Short'].shift(5)).astype(int) +
(df['BB_Width_Medium'] > df['BB_Width_Medium'].shift(10)).astype(int) +
(df['BB_Width_Long'] > df['BB_Width_Long'].shift(20)).astype(int)
)
# Volatility divergence signals
df['Vol_Divergence'] = (
(df['ATR_Short'] > df['ATR_Medium']) &
(df['ATR_Medium'] < df['ATR_Long'])
)
return df
df_multi_tf_vol = multi_timeframe_volatility(df)Install with Tessl CLI
npx tessl i tessl/pypi-ta