Technical Indicators
Comprehensive technical analysis library with 58+ TA-Lib compatible indicators built specifically for Polars DataFrames, including advanced pattern recognition indicators.
Overview
The indicators module provides both class-based and function-based interfaces for technical analysis, similar to TA-Lib but optimized for Polars DataFrames.
ProjectX Indicators - Technical Analysis Library
Author: @TexasCoding Date: 2025-08-02
- Overview:
ProjectX Indicators provides a comprehensive, extensible technical analysis library similar to TA-Lib, built on Polars DataFrames for high-performance financial analysis. It offers both class-based and function-based interfaces for over 60 technical indicators, with seamless integration for vectorized backtesting and strategy development in ProjectX and beyond.
- Key Features:
Wide range of indicators: trend/overlap, momentum, volatility, volume, and patterns
Class-based and TA-Lib-style function interface for flexible usage
All indicators operate on Polars DataFrames for speed and modern analytics
Utilities for indicator discovery, grouping, and docstring access
Clean API and naming convention for easy scripting and research
Built-in caching and validation for optimal performance
Support for custom indicators through base classes
- Indicator Categories:
Overlap Studies: SMA, EMA, BBANDS, DEMA, TEMA, WMA, SAR, etc.
Momentum Indicators: RSI, MACD, STOCH, CCI, ADX, AROON, etc.
Volatility Indicators: ATR, NATR, TRANGE, STDDEV
Volume Indicators: OBV, VWAP, AD, ADOSC
Pattern Indicators: FVG (Fair Value Gap), ORDERBLOCK, WAE (Waddah Attar Explosion)
- Example Usage:
```python # Class-based interface from project_x_py.indicators import RSI, SMA
rsi = RSI() data_with_rsi = rsi.calculate(ohlcv_data, period=14)
# Function-based interface (TA-Lib style) from project_x_py.indicators import calculate_rsi, calculate_sma
data_with_rsi = calculate_rsi(ohlcv_data, period=14) data_with_sma = calculate_sma(ohlcv_data, period=20)
# Pattern detection from project_x_py.indicators import FVG, ORDERBLOCK
fvg_data = FVG().calculate(ohlcv_data, min_gap_size=0.001) order_blocks = ORDERBLOCK().calculate(ohlcv_data, min_volume_percentile=75) ```
- Performance Notes:
All indicators use vectorized operations for optimal speed
Built-in caching prevents redundant calculations
Memory-efficient Polars DataFrame operations
Supports large datasets with minimal memory overhead
See also
project_x_py.indicators.base (abstract base classes/utilities)
project_x_py.indicators.momentum
project_x_py.indicators.overlap
project_x_py.indicators.volume
project_x_py.indicators.volatility
project_x_py.indicators.order_block
project_x_py.indicators.fvg
project_x_py.indicators.waddah_attar
- AD(data, high_column='high', low_column='low', close_column='close', volume_column='volume')[source]
Accumulation/Distribution Line (TA-Lib style).
- Return type:
DataFrame
- ADOSC(data, high_column='high', low_column='low', close_column='close', volume_column='volume', fast_period=3, slow_period=10)[source]
Accumulation/Distribution Oscillator (TA-Lib style).
- Return type:
DataFrame
- ADX(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Average Directional Movement Index (TA-Lib style).
- Return type:
DataFrame
- ATR(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Average True Range (TA-Lib style).
- Return type:
DataFrame
- BBANDS(data, column='close', period=20, std_dev=2.0)[source]
Bollinger Bands (TA-Lib style).
- Return type:
DataFrame
- BULLISHENGULFING(data, **kwargs)[source]
Bullish Engulfing pattern (TA-Lib style).
- Return type:
DataFrame
- CCI(data, high_column='high', low_column='low', close_column='close', period=20, constant=0.015)[source]
Commodity Channel Index (TA-Lib style).
- Return type:
DataFrame
- DEMA(data, column='close', period=20)[source]
Double Exponential Moving Average (TA-Lib style).
- Return type:
DataFrame
- DOJI(data, **kwargs)[source]
Doji candlestick pattern (TA-Lib style).
- Return type:
DataFrame
- EMA(data, column='close', period=20)[source]
Exponential Moving Average (TA-Lib style).
- Return type:
DataFrame
- FVG(data, high_column='high', low_column='low', close_column='close', min_gap_size=0.0, check_mitigation=False, mitigation_threshold=0.5)[source]
Fair Value Gap (TA-Lib style).
- Return type:
DataFrame
- HAMMER(data, **kwargs)[source]
Hammer candlestick pattern (TA-Lib style).
- Return type:
DataFrame
- HT_TRENDLINE(data, column='close')[source]
Hilbert Transform - Instantaneous Trendline (TA-Lib style).
- Return type:
DataFrame
- KAMA(data, column='close', period=30, fast_sc=2.0, slow_sc=30.0)[source]
Kaufman Adaptive Moving Average (TA-Lib style).
- Return type:
DataFrame
- MA(data, column='close', period=30, ma_type='sma')[source]
Moving Average (TA-Lib style).
- Return type:
DataFrame
- MACD(data, column='close', fast_period=12, slow_period=26, signal_period=9)[source]
Moving Average Convergence Divergence (TA-Lib style).
- Return type:
DataFrame
- MAMA(data, column='close', fast_limit=0.5, slow_limit=0.05)[source]
MESA Adaptive Moving Average (TA-Lib style).
- Return type:
DataFrame
- MAVP(data, column='close', periods_column='periods', min_period=2, max_period=30, ma_type='sma')[source]
Moving Average with Variable Period (TA-Lib style).
- Return type:
DataFrame
- MIDPOINT(data, column='close', period=14)[source]
Midpoint over period (TA-Lib style).
- Return type:
DataFrame
- MIDPRICE(data, high_column='high', low_column='low', period=14)[source]
Midpoint Price over period (TA-Lib style).
- Return type:
DataFrame
- MOM(data, column='close', period=10)[source]
Momentum (TA-Lib style).
- Return type:
DataFrame
- NATR(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Normalized Average True Range (TA-Lib style).
- Return type:
DataFrame
- OBV(data, close_column='close', volume_column='volume')[source]
On-Balance Volume (TA-Lib style).
- Return type:
DataFrame
- ORDERBLOCK(data, open_column='open', high_column='high', low_column='low', close_column='close', volume_column='volume', min_volume_percentile=50, check_mitigation=False, mitigation_threshold=0.5, lookback_periods=3, use_wicks=True)[source]
Order Block (TA-Lib style).
- Return type:
DataFrame
- ROC(data, column='close', period=10)[source]
Rate of Change (TA-Lib style).
- Return type:
DataFrame
- RSI(data, column='close', period=14)[source]
Relative Strength Index (TA-Lib style).
- Return type:
DataFrame
- SAR(data, high_column='high', low_column='low', acceleration=0.02, maximum=0.2)[source]
Parabolic SAR (TA-Lib style).
- Return type:
DataFrame
- SAREXT(data, high_column='high', low_column='low', start_value=0.0, offset_on_reverse=0.0, acceleration_init_long=0.02, acceleration_long=0.02, acceleration_max_long=0.2, acceleration_init_short=0.02, acceleration_short=0.02, acceleration_max_short=0.2)[source]
Parabolic SAR - Extended (TA-Lib style).
- Return type:
DataFrame
- SHOOTINGSTAR(data, **kwargs)[source]
Shooting Star candlestick pattern (TA-Lib style).
- Return type:
DataFrame
- SMA(data, column='close', period=20)[source]
Simple Moving Average (TA-Lib style).
- Return type:
DataFrame
- STDDEV(data, column='close', period=5, ddof=1)[source]
Standard Deviation (TA-Lib style).
- Return type:
DataFrame
- STOCH(data, high_column='high', low_column='low', close_column='close', k_period=14, d_period=3)[source]
Stochastic Oscillator (TA-Lib style).
- Return type:
DataFrame
- STOCHRSI(data, column='close', rsi_period=14, stoch_period=14, k_period=3, d_period=3)[source]
Stochastic RSI (TA-Lib style).
- Return type:
DataFrame
- T3(data, column='close', period=5, v_factor=0.7)[source]
Triple Exponential Moving Average (T3) (TA-Lib style).
- Return type:
DataFrame
- TEMA(data, column='close', period=20)[source]
Triple Exponential Moving Average (TA-Lib style).
- Return type:
DataFrame
- TRANGE(data, high_column='high', low_column='low', close_column='close')[source]
True Range (TA-Lib style).
- Return type:
DataFrame
- TRIMA(data, column='close', period=20)[source]
Triangular Moving Average (TA-Lib style).
- Return type:
DataFrame
- ULTOSC(data, high_column='high', low_column='low', close_column='close', period1=7, period2=14, period3=28)[source]
Ultimate Oscillator (TA-Lib style).
- Return type:
DataFrame
- VWAP(data, high_column='high', low_column='low', close_column='close', volume_column='volume', period=None)[source]
Volume Weighted Average Price (TA-Lib style).
- Return type:
DataFrame
- WAE(data, close_column='close', high_column='high', low_column='low', fast_period=20, slow_period=40, bb_period=20, bb_mult=2.0, sensitivity=150, dead_zone_period=100, dead_zone_mult=3.6)[source]
Waddah Attar Explosion (TA-Lib style).
- Return type:
DataFrame
- WILLR(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Williams %R (TA-Lib style).
- Return type:
DataFrame
- WMA(data, column='close', period=20)[source]
Weighted Moving Average (TA-Lib style).
- Return type:
DataFrame
- class BaseIndicator(name, description='')[source]
Bases:
ABC
Base class for all technical indicators.
Provides common validation, error handling, caching, and utility methods that all indicators can inherit from. This abstract base class ensures consistent behavior across all indicators while providing performance optimizations through intelligent caching.
- Key Features:
Automatic parameter validation and data checking
Built-in caching system to avoid redundant calculations
Standardized error handling with IndicatorError exceptions
Support for both class-based and function-based usage
Memory-efficient operations with Polars DataFrames
All custom indicators should inherit from this class or one of its specialized subclasses (OverlapIndicator, MomentumIndicator, etc.) for consistent behavior and optimal performance.
- __call__(data, **kwargs)[source]
Allow indicator to be called directly with caching.
- Parameters:
data (
DataFrame
) – Input DataFrame**kwargs (
Any
) – Additional parameters
- Return type:
DataFrame
- Returns:
DataFrame with indicator values
- __init__(name, description='')[source]
Initialize base indicator.
- abstractmethod calculate(data, **kwargs)[source]
Calculate the indicator values.
This method must be implemented by all indicator subclasses. It should perform the core calculation logic for the specific indicator, including parameter validation, data processing, and result generation.
The method should: 1. Validate input data and parameters using inherited validation methods 2. Perform the indicator-specific calculations 3. Return a DataFrame with the original data plus new indicator columns 4. Handle edge cases (insufficient data, invalid parameters, etc.)
- Parameters:
data (
DataFrame
) – Input DataFrame with OHLCV data (must contain required columns)**kwargs (
Any
) – Additional parameters specific to each indicator (period, thresholds, column names, etc.)
- Returns:
- DataFrame with original data plus new indicator columns.
The indicator values should be added as new columns with descriptive names (e.g., “rsi”, “macd”, “bb_upper”).
- Return type:
pl.DataFrame
- Raises:
IndicatorError – If data validation fails or calculation cannot proceed
- validate_data(data, required_columns)[source]
Validate input DataFrame and required columns.
- Parameters:
- Raises:
IndicatorError – If validation fails
- Return type:
- validate_data_length(data, min_length)[source]
Validate that data has sufficient length for calculation.
- Parameters:
data (
DataFrame
) – Input DataFramemin_length (
int
) – Minimum required data length
- Raises:
IndicatorError – If data is too short
- Return type:
- validate_period(period, min_period=1)[source]
Validate period parameter.
- Parameters:
- Raises:
IndicatorError – If period is invalid
- Return type:
- exception IndicatorError[source]
Bases:
Exception
Custom exception for indicator calculation errors.
- class MomentumIndicator(name, description='')[source]
Bases:
BaseIndicator
Base class for momentum indicators.
- class OverlapIndicator(name, description='')[source]
Bases:
BaseIndicator
Base class for overlap study indicators (trend-following).
- class VolatilityIndicator(name, description='')[source]
Bases:
BaseIndicator
Base class for volatility indicators.
- class VolumeIndicator(name, description='')[source]
Bases:
BaseIndicator
Base class for volume indicators.
- calculate_adx(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Calculate ADX (convenience function).
- Return type:
DataFrame
- calculate_aroon(data, high_column='high', low_column='low', period=14)[source]
Calculate Aroon (convenience function).
- Return type:
DataFrame
- calculate_atr(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Calculate ATR (convenience function).
- Return type:
DataFrame
- calculate_bollinger_bands(data, column='close', period=20, std_dev=2.0)[source]
Calculate Bollinger Bands (convenience function).
- Return type:
DataFrame
- calculate_bullishengulfing(data, **kwargs)[source]
- Return type:
DataFrame
- calculate_commodity_channel_index(data, high_column='high', low_column='low', close_column='close', period=20, constant=0.015)[source]
Calculate CCI (convenience function).
- Return type:
DataFrame
- calculate_dema(data, column='close', period=20)[source]
Calculate Double Exponential Moving Average (convenience function).
- Return type:
DataFrame
- calculate_doji(data, **kwargs)[source]
- Return type:
DataFrame
- calculate_ema(data, column='close', period=20)[source]
Calculate Exponential Moving Average (convenience function).
- Return type:
DataFrame
- calculate_fvg(data, high_column='high', low_column='low', close_column='close', min_gap_size=0.0, check_mitigation=False, mitigation_threshold=0.5)[source]
Calculate Fair Value Gaps (convenience function).
See FVG.calculate() for detailed documentation.
- Parameters:
data (
DataFrame
) – DataFrame with OHLC datahigh_column (
str
) – High price columnlow_column (
str
) – Low price columnclose_column (
str
) – Close price columnmin_gap_size (
float
) – Minimum gap size to consider validcheck_mitigation (
bool
) – Whether to check if gaps have been mitigatedmitigation_threshold (
float
) – Percentage of gap that needs to be filled to consider it mitigated
- Return type:
DataFrame
- Returns:
DataFrame with FVG columns added
- calculate_hammer(data, **kwargs)[source]
- Return type:
DataFrame
- calculate_ht_trendline(data, column='close')[source]
Calculate Hilbert Transform Trendline (convenience function).
- Return type:
DataFrame
- calculate_kama(data, column='close', period=30, fast_sc=2.0, slow_sc=30.0)[source]
Calculate Kaufman Adaptive Moving Average (convenience function).
- Return type:
DataFrame
- calculate_ma(data, column='close', period=30, ma_type='sma')[source]
Calculate generic Moving Average (convenience function).
- Return type:
DataFrame
- calculate_macd(data, column='close', fast_period=12, slow_period=26, signal_period=9)[source]
Calculate MACD (convenience function).
- Return type:
DataFrame
- calculate_mama(data, column='close', fast_limit=0.5, slow_limit=0.05)[source]
Calculate MESA Adaptive Moving Average (convenience function).
- Return type:
DataFrame
- calculate_midpoint(data, column='close', period=14)[source]
Calculate Midpoint (convenience function).
- Return type:
DataFrame
- calculate_midprice(data, high_column='high', low_column='low', period=14)[source]
Calculate Midpoint Price (convenience function).
- Return type:
DataFrame
- calculate_money_flow_index(data, high_column='high', low_column='low', close_column='close', volume_column='volume', period=14)[source]
Calculate MFI (convenience function).
- Return type:
DataFrame
- calculate_obv(data, close_column='close', volume_column='volume')[source]
Calculate OBV (convenience function).
- Return type:
DataFrame
- calculate_order_block(data, open_column='open', high_column='high', low_column='low', close_column='close', volume_column='volume', min_volume_percentile=50, check_mitigation=False, mitigation_threshold=0.5, lookback_periods=3, use_wicks=True)[source]
Calculate Order Blocks (convenience function).
See OrderBlock.calculate() for detailed documentation.
- Parameters:
data (
DataFrame
) – DataFrame with OHLC dataopen_column (
str
) – Open price columnhigh_column (
str
) – High price columnlow_column (
str
) – Low price columnclose_column (
str
) – Close price columnvolume_column (
str
) – Volume columnmin_volume_percentile (
float
) – Minimum volume percentile for valid OBcheck_mitigation (
bool
) – Whether to check if blocks have been mitigatedmitigation_threshold (
float
) – Percentage of block that needs to be filledlookback_periods (
int
) – Number of periods to look back for breakuse_wicks (
bool
) – Whether to use wicks or bodies for OB zones
- Return type:
DataFrame
- Returns:
DataFrame with Order Block columns added
- calculate_ppo(data, column='close', fast_period=12, slow_period=26, signal_period=9)[source]
Calculate PPO (convenience function).
- Return type:
DataFrame
- calculate_rsi(data, column='close', period=14)[source]
Calculate RSI (convenience function).
- Return type:
DataFrame
- calculate_sar(data, high_column='high', low_column='low', acceleration=0.02, maximum=0.2)[source]
Calculate Parabolic SAR (convenience function).
- Return type:
DataFrame
- calculate_shootingstar(data, **kwargs)[source]
- Return type:
DataFrame
- calculate_sma(data, column='close', period=20)[source]
Calculate Simple Moving Average (convenience function).
- Return type:
DataFrame
- calculate_stddev(data, column='close', period=5, ddof=1)[source]
Calculate STDDEV (convenience function).
- Return type:
DataFrame
- calculate_stochastic(data, high_column='high', low_column='low', close_column='close', k_period=14, d_period=3)[source]
Calculate Stochastic (convenience function).
- Return type:
DataFrame
- calculate_t3(data, column='close', period=5, v_factor=0.7)[source]
Calculate T3 Moving Average (convenience function).
- Return type:
DataFrame
- calculate_tema(data, column='close', period=20)[source]
Calculate Triple Exponential Moving Average (convenience function).
- Return type:
DataFrame
- calculate_trima(data, column='close', period=20)[source]
Calculate Triangular Moving Average (convenience function).
- Return type:
DataFrame
- calculate_ultimate_oscillator(data, high_column='high', low_column='low', close_column='close', period1=7, period2=14, period3=28)[source]
Calculate Ultimate Oscillator (convenience function).
- Return type:
DataFrame
- calculate_vwap(data, high_column='high', low_column='low', close_column='close', volume_column='volume', period=None)[source]
Calculate VWAP (convenience function).
- Return type:
DataFrame
- calculate_wae(data, close_column='close', high_column='high', low_column='low', fast_period=20, slow_period=40, bb_period=20, bb_mult=2.0, sensitivity=150, dead_zone_period=100, dead_zone_mult=3.6)[source]
Calculate Waddah Attar Explosion (convenience function).
See WAE.calculate() for detailed documentation.
- Parameters:
data (
DataFrame
) – DataFrame with OHLC dataclose_column (
str
) – Close price columnhigh_column (
str
) – High price columnlow_column (
str
) – Low price columnfast_period (
int
) – Fast EMA period for MACDslow_period (
int
) – Slow EMA period for MACDbb_period (
int
) – Bollinger Bands periodbb_mult (
float
) – Bollinger Bands multipliersensitivity (
float
) – Sensitivity multiplier for explosiondead_zone_period (
int
) – ATR period for dead zonedead_zone_mult (
float
) – Multiplier for dead zone ATR
- Return type:
DataFrame
- Returns:
DataFrame with WAE columns added
- calculate_williams_r(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Calculate Williams %R (convenience function).
- Return type:
DataFrame
- calculate_wma(data, column='close', period=20)[source]
Calculate Weighted Moving Average (convenience function).
- Return type:
DataFrame
- ema_alpha(period)[source]
Calculate EMA alpha (smoothing factor) from period.
This utility function calculates the smoothing factor (alpha) used in Exponential Moving Average calculations. The alpha determines how much weight is given to recent prices versus older prices.
Formula: alpha = 2 / (period + 1)
- Parameters:
period (
int
) – EMA period (number of periods for the moving average)- Returns:
Alpha value (smoothing factor) between 0 and 1
- Return type:
Example
>>> alpha = ema_alpha(14) # Returns 0.1333... >>> # Higher alpha = more weight to recent prices >>> alpha_short = ema_alpha(5) # 0.3333... >>> alpha_long = ema_alpha(50) # 0.0392...
- get_indicator_info(indicator_name)[source]
Get information about a specific indicator.
- Return type:
- safe_division(numerator, denominator, default=0.0)[source]
Safe division that handles division by zero.
This utility function creates a Polars expression that performs division while safely handling cases where the denominator is zero. It’s commonly used in technical indicator calculations where division operations might encounter zero values.
- Parameters:
numerator (
Expr
) – Numerator expression (pl.Expr)denominator (
Expr
) – Denominator expression (pl.Expr)default (
float
) – Default value to return when denominator is zero (default: 0.0)
- Returns:
- Polars expression that performs safe division, returning the
default value when denominator is zero
- Return type:
pl.Expr
Example
>>> # Safe division in RSI calculation >>> gain = pl.col("close").diff().filter(pl.col("close").diff() > 0) >>> loss = -pl.col("close").diff().filter(pl.col("close").diff() < 0) >>> rs = safe_division(gain.rolling_mean(14), loss.rolling_mean(14))
Quick Start
import asyncio
from project_x_py.indicators import RSI, SMA, MACD, BBANDS
from project_x_py import ProjectX
async def analyze_market():
# Get market data
async with ProjectX.from_env() as client:
await client.authenticate()
data = await client.get_bars('MNQ', days=30, interval=60) # V3: actual symbol
# Class-based interface
rsi = RSI()
data_with_rsi = rsi.calculate(data, period=14)
# TA-Lib style functions (direct usage)
data = RSI(data, period=14) # Add RSI
data = SMA(data, period=20) # Add 20-period SMA
data = BBANDS(data, period=20) # Add Bollinger Bands
return data
# Run the analysis
data = asyncio.run(analyze_market())
Base Classes
- class BaseIndicator(name, description='')[source]
Bases:
ABC
Base class for all technical indicators.
Provides common validation, error handling, caching, and utility methods that all indicators can inherit from. This abstract base class ensures consistent behavior across all indicators while providing performance optimizations through intelligent caching.
- Key Features:
Automatic parameter validation and data checking
Built-in caching system to avoid redundant calculations
Standardized error handling with IndicatorError exceptions
Support for both class-based and function-based usage
Memory-efficient operations with Polars DataFrames
All custom indicators should inherit from this class or one of its specialized subclasses (OverlapIndicator, MomentumIndicator, etc.) for consistent behavior and optimal performance.
- validate_data(data, required_columns)[source]
Validate input DataFrame and required columns.
- Parameters:
- Raises:
IndicatorError – If validation fails
- Return type:
- validate_period(period, min_period=1)[source]
Validate period parameter.
- Parameters:
- Raises:
IndicatorError – If period is invalid
- Return type:
- validate_data_length(data, min_length)[source]
Validate that data has sufficient length for calculation.
- Parameters:
data (
DataFrame
) – Input DataFramemin_length (
int
) – Minimum required data length
- Raises:
IndicatorError – If data is too short
- Return type:
- abstractmethod calculate(data, **kwargs)[source]
Calculate the indicator values.
This method must be implemented by all indicator subclasses. It should perform the core calculation logic for the specific indicator, including parameter validation, data processing, and result generation.
The method should: 1. Validate input data and parameters using inherited validation methods 2. Perform the indicator-specific calculations 3. Return a DataFrame with the original data plus new indicator columns 4. Handle edge cases (insufficient data, invalid parameters, etc.)
- Parameters:
data (
DataFrame
) – Input DataFrame with OHLCV data (must contain required columns)**kwargs (
Any
) – Additional parameters specific to each indicator (period, thresholds, column names, etc.)
- Returns:
- DataFrame with original data plus new indicator columns.
The indicator values should be added as new columns with descriptive names (e.g., “rsi”, “macd”, “bb_upper”).
- Return type:
pl.DataFrame
- Raises:
IndicatorError – If data validation fails or calculation cannot proceed
- class OverlapIndicator(name, description='')[source]
Bases:
BaseIndicator
Base class for overlap study indicators (trend-following).
- class MomentumIndicator(name, description='')[source]
Bases:
BaseIndicator
Base class for momentum indicators.
- class VolatilityIndicator(name, description='')[source]
Bases:
BaseIndicator
Base class for volatility indicators.
Overlap Studies (Trend Indicators)
- class SMA(data, column='close', period=20)[source]
Bases:
Simple Moving Average (TA-Lib style).
- Return type:
DataFrame
- class EMA(data, column='close', period=20)[source]
Bases:
Exponential Moving Average (TA-Lib style).
- Return type:
DataFrame
- class BBANDS(data, column='close', period=20, std_dev=2.0)[source]
Bases:
Bollinger Bands (TA-Lib style).
- Return type:
DataFrame
- class DEMA(data, column='close', period=20)[source]
Bases:
Double Exponential Moving Average (TA-Lib style).
- Return type:
DataFrame
- class TEMA(data, column='close', period=20)[source]
Bases:
Triple Exponential Moving Average (TA-Lib style).
- Return type:
DataFrame
Momentum Indicators
- class RSI(data, column='close', period=14)[source]
Bases:
Relative Strength Index (TA-Lib style).
- Return type:
DataFrame
- class MACD(data, column='close', fast_period=12, slow_period=26, signal_period=9)[source]
Bases:
Moving Average Convergence Divergence (TA-Lib style).
- Return type:
DataFrame
- class STOCH(data, high_column='high', low_column='low', close_column='close', k_period=14, d_period=3)[source]
Bases:
Stochastic Oscillator (TA-Lib style).
- Return type:
DataFrame
- class WILLR(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Bases:
Williams %R (TA-Lib style).
- Return type:
DataFrame
- class CCI(data, high_column='high', low_column='low', close_column='close', period=20, constant=0.015)[source]
Bases:
Commodity Channel Index (TA-Lib style).
- Return type:
DataFrame
- class ROC(data, column='close', period=10)[source]
Bases:
Rate of Change (TA-Lib style).
- Return type:
DataFrame
Volatility Indicators
- class ATR(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Bases:
Average True Range (TA-Lib style).
- Return type:
DataFrame
- class ADX(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Bases:
Average Directional Movement Index (TA-Lib style).
- Return type:
DataFrame
- class NATR(data, high_column='high', low_column='low', close_column='close', period=14)[source]
Bases:
Normalized Average True Range (TA-Lib style).
- Return type:
DataFrame
Volume Indicators
- class OBV(data, close_column='close', volume_column='volume')[source]
Bases:
On-Balance Volume (TA-Lib style).
- Return type:
DataFrame
- class VWAP(data, high_column='high', low_column='low', close_column='close', volume_column='volume', period=None)[source]
Bases:
Volume Weighted Average Price (TA-Lib style).
- Return type:
DataFrame
Pattern Recognition Indicators
Convenience Functions
Overlap Studies
- calculate_sma(data, column='close', period=20)[source]
Calculate Simple Moving Average (convenience function).
- Return type:
DataFrame
Momentum Indicators
- calculate_rsi(data, column='close', period=14)[source]
Calculate RSI (convenience function).
- Return type:
DataFrame
- calculate_macd(data, column='close', fast_period=12, slow_period=26, signal_period=9)[source]
Calculate MACD (convenience function).
- Return type:
DataFrame
- calculate_stochastic(data, high_column='high', low_column='low', close_column='close', k_period=14, d_period=3)[source]
Calculate Stochastic (convenience function).
- Return type:
DataFrame
Volatility Indicators
Volume Indicators
Pattern Recognition
- calculate_fvg(data, high_column='high', low_column='low', close_column='close', min_gap_size=0.0, check_mitigation=False, mitigation_threshold=0.5)[source]
Calculate Fair Value Gaps (convenience function).
See FVG.calculate() for detailed documentation.
- Parameters:
data (
DataFrame
) – DataFrame with OHLC datahigh_column (
str
) – High price columnlow_column (
str
) – Low price columnclose_column (
str
) – Close price columnmin_gap_size (
float
) – Minimum gap size to consider validcheck_mitigation (
bool
) – Whether to check if gaps have been mitigatedmitigation_threshold (
float
) – Percentage of gap that needs to be filled to consider it mitigated
- Return type:
DataFrame
- Returns:
DataFrame with FVG columns added
- calculate_order_block(data, open_column='open', high_column='high', low_column='low', close_column='close', volume_column='volume', min_volume_percentile=50, check_mitigation=False, mitigation_threshold=0.5, lookback_periods=3, use_wicks=True)[source]
Calculate Order Blocks (convenience function).
See OrderBlock.calculate() for detailed documentation.
- Parameters:
data (
DataFrame
) – DataFrame with OHLC dataopen_column (
str
) – Open price columnhigh_column (
str
) – High price columnlow_column (
str
) – Low price columnclose_column (
str
) – Close price columnvolume_column (
str
) – Volume columnmin_volume_percentile (
float
) – Minimum volume percentile for valid OBcheck_mitigation (
bool
) – Whether to check if blocks have been mitigatedmitigation_threshold (
float
) – Percentage of block that needs to be filledlookback_periods (
int
) – Number of periods to look back for breakuse_wicks (
bool
) – Whether to use wicks or bodies for OB zones
- Return type:
DataFrame
- Returns:
DataFrame with Order Block columns added
- calculate_wae(data, close_column='close', high_column='high', low_column='low', fast_period=20, slow_period=40, bb_period=20, bb_mult=2.0, sensitivity=150, dead_zone_period=100, dead_zone_mult=3.6)[source]
Calculate Waddah Attar Explosion (convenience function).
See WAE.calculate() for detailed documentation.
- Parameters:
data (
DataFrame
) – DataFrame with OHLC dataclose_column (
str
) – Close price columnhigh_column (
str
) – High price columnlow_column (
str
) – Low price columnfast_period (
int
) – Fast EMA period for MACDslow_period (
int
) – Slow EMA period for MACDbb_period (
int
) – Bollinger Bands periodbb_mult (
float
) – Bollinger Bands multipliersensitivity (
float
) – Sensitivity multiplier for explosiondead_zone_period (
int
) – ATR period for dead zonedead_zone_mult (
float
) – Multiplier for dead zone ATR
- Return type:
DataFrame
- Returns:
DataFrame with WAE columns added
Discovery Functions
Utility Functions
- ema_alpha(period)[source]
Calculate EMA alpha (smoothing factor) from period.
This utility function calculates the smoothing factor (alpha) used in Exponential Moving Average calculations. The alpha determines how much weight is given to recent prices versus older prices.
Formula: alpha = 2 / (period + 1)
- Parameters:
period (
int
) – EMA period (number of periods for the moving average)- Returns:
Alpha value (smoothing factor) between 0 and 1
- Return type:
Example
>>> alpha = ema_alpha(14) # Returns 0.1333... >>> # Higher alpha = more weight to recent prices >>> alpha_short = ema_alpha(5) # 0.3333... >>> alpha_long = ema_alpha(50) # 0.0392...
- safe_division(numerator, denominator, default=0.0)[source]
Safe division that handles division by zero.
This utility function creates a Polars expression that performs division while safely handling cases where the denominator is zero. It’s commonly used in technical indicator calculations where division operations might encounter zero values.
- Parameters:
numerator (
Expr
) – Numerator expression (pl.Expr)denominator (
Expr
) – Denominator expression (pl.Expr)default (
float
) – Default value to return when denominator is zero (default: 0.0)
- Returns:
- Polars expression that performs safe division, returning the
default value when denominator is zero
- Return type:
pl.Expr
Example
>>> # Safe division in RSI calculation >>> gain = pl.col("close").diff().filter(pl.col("close").diff() > 0) >>> loss = -pl.col("close").diff().filter(pl.col("close").diff() < 0) >>> rs = safe_division(gain.rolling_mean(14), loss.rolling_mean(14))
Usage Examples
Basic Usage
import asyncio
from project_x_py.indicators import RSI, SMA, MACD
from project_x_py import ProjectX
async def basic_analysis():
# Load your data (Polars DataFrame with OHLCV columns)
async with ProjectX.from_env() as client:
await client.authenticate()
data = await client.get_bars('MNQ', days=30, interval=60) # V3: actual symbol
# Add indicators using TA-Lib style functions
data = RSI(data, period=14)
data = SMA(data, period=20)
data = SMA(data, period=50)
data = MACD(data, fast_period=12, slow_period=26, signal_period=9)
# Check latest values
latest = data.tail(1)
print(f"RSI: {latest['rsi_14'].item():.2f}")
print(f"SMA(20): ${latest['sma_20'].item():.2f}")
asyncio.run(basic_analysis())
Class-Based Interface
from project_x_py.indicators import RSI, SMA, BBANDS
# Create indicator instances
rsi = RSI()
sma = SMA()
bb = BBANDS()
# Calculate indicators
data_with_rsi = rsi.calculate(data, period=14)
data_with_sma = sma.calculate(data_with_rsi, period=20)
data_with_bb = bb.calculate(data_with_sma, period=20, std_dev=2.0)
Multi-Indicator Strategy
import asyncio
import polars as pl
from project_x_py.indicators import *
from project_x_py import ProjectX
async def multi_indicator_analysis():
# Get data
async with ProjectX.from_env() as client:
await client.authenticate()
data = await client.get_bars('MNQ', days=60, interval=60) # V3: actual symbol
# Comprehensive technical analysis
analysis = (
data
# Trend indicators
.pipe(SMA, period=20)
.pipe(SMA, period=50)
.pipe(EMA, period=21)
.pipe(BBANDS, period=20, std_dev=2.0)
# Momentum indicators
.pipe(RSI, period=14)
.pipe(MACD, fast_period=12, slow_period=26, signal_period=9)
.pipe(STOCH, k_period=14, d_period=3)
# Volatility indicators
.pipe(ATR, period=14)
.pipe(ADX, period=14)
# Volume indicators
.pipe(OBV)
.pipe(VWAP, period=20)
# Pattern recognition
.pipe(FVG, min_gap_size=0.001, check_mitigation=True)
.pipe(ORDERBLOCK, min_volume_percentile=70)
.pipe(WAE, sensitivity=150)
)
return analysis
# Run the strategy
result = asyncio.run(multi_indicator_analysis())
Pattern Recognition Examples
from project_x_py.indicators import FVG, OrderBlock, WAE
# Fair Value Gap Detection
fvg = FVG()
data_with_fvg = fvg.calculate(
data,
min_gap_size=0.001, # 0.1% minimum gap
check_mitigation=True, # Track if gaps get filled
mitigation_threshold=0.5 # 50% fill threshold
)
# Order Block Identification
ob = OrderBlock()
data_with_ob = ob.calculate(
data,
min_volume_percentile=70, # Top 30% volume
lookback_periods=3, # Look for 3-candle patterns
use_wicks=True # Consider wicks in patterns
)
# Waddah Attar Explosion
wae = WAE()
data_with_wae = wae.calculate(
data,
sensitivity=150, # Trend sensitivity
dead_zone_period=100, # ATR period for filtering
dead_zone_mult=3.6 # Dead zone multiplier
)
# Confluence Trading: Combine all three
confluence_data = (
data
.pipe(FVG, check_mitigation=True)
.pipe(ORDERBLOCK, min_volume_percentile=80)
.pipe(WAE, sensitivity=150)
)
# Find strong signals where patterns align
strong_bullish = confluence_data.filter(
(pl.col("fvg_bullish") == True) &
(pl.col("ob_bullish") == True) &
(pl.col("wae_explosion_up") > 0)
)
Indicator Discovery
from project_x_py.indicators import get_all_indicators, get_indicator_groups
# List all available indicators
all_indicators = get_all_indicators()
print(f"Total indicators: {len(all_indicators)}")
# Get indicators by category
groups = get_indicator_groups()
for category, indicators in groups.items():
print(f"{category}: {indicators}")
# Get information about specific indicator
rsi_info = get_indicator_info('RSI')
print(f"RSI: {rsi_info}")
Error Handling
from project_x_py.indicators import IndicatorError
try:
# This will raise an error if the column doesn't exist
data_with_rsi = RSI(data, column='nonexistent_column', period=14)
except IndicatorError as e:
print(f"Indicator error: {e}")
try:
# This will raise an error if period is too large
data_with_sma = SMA(data, period=1000) # More than available data
except IndicatorError as e:
print(f"Invalid period: {e}")
Performance Tips
Use Polars methods: Indicators are optimized for Polars DataFrames
Chain operations: Use
.pipe()
for efficient chainingReuse instances: Create indicator instances once and reuse them
Batch calculations: Calculate multiple indicators in one pass when possible
Async data fetching: Fetch data once and apply all indicators
async def efficient_analysis():
# Fetch data once
async with ProjectX.from_env() as client:
await client.authenticate()
data = await client.get_bars('MNQ', days=30) # V3: actual symbol
# Efficient: Chain multiple indicators
data = (
data
.pipe(RSI, period=14)
.pipe(SMA, period=20)
.pipe(MACD)
)
# Less efficient: Separate calculations
# data = RSI(data, period=14)
# data = SMA(data, period=20)
# data = MACD(data)
return data
TA-Lib Compatibility
The indicators are designed to be compatible with TA-Lib naming and parameter conventions:
TA-Lib Function |
project-x-py Equivalent |
Notes |
---|---|---|
|
|
Uses ‘close’ column by default |
|
|
Identical calculation method |
|
|
Returns upper, middle, lower bands |
|
|
Returns MACD line, signal, histogram |