polars-anta
ANTA (Alpha & Numerical Technical Analysis): Ultra-fast, zero-C-dependency technical analysis and factor library powered natively by Polars Expressions.
Documentation • Features • Benchmark • Installation • Quickstart • Tutorials • Indicators • Development
Why polars-anta?
Quantitative researchers and financial engineers have historically faced a trade-off between installation complexity and computation speed:
| Capability | TA-Lib | pandas-ta | polars-anta |
|---|---|---|---|
| Dependencies | Requires external C library & MSVC / GCC | Pure Python / NumPy | Zero C compilation (pure Polars) |
| Execution Engine | Single-threaded C loops | Single-threaded Pandas / GIL | Multi-threaded Rust query engine |
| Multi-Asset Scaling | Manual sequential loops | Slow .groupby().apply() |
Native .over("ticker") parallelization |
| Dual Expression Namespace | Unsupported | Unsupported | Both .anta & .ta supported |
| Lazy Evaluation | Unsupported | Unsupported | Full pl.LazyFrame streaming support |
| Memory Layout | Array conversion overhead | High Pandas memory footprint | Zero-copy Arrow memory format |
polars-anta eliminates this compromise by implementing financial indicators directly as Polars Expressions (pl.Expr). Computations are pushed into Polars' multi-threaded Rust engine, eliminating Python GIL bottlenecks without requiring any C compilers.
Performance Benchmark (1,000,000 Rows)
Benchmarks measured across 1,000,000 bars (single-asset random walk) and a 500 tickers x 2,000 bars universe. Computations executed on Polars' multi-threaded Rust query engine vs single-threaded Pandas:
| Operation / Indicator | Dataset Scale | Pandas Execution | polars-anta Execution |
Measured Speedup |
|---|---|---|---|---|
| Linear Regression Slope | 1,000,000 bars | 2.3529 s | 0.0209 s | 112.4x Faster |
| Multi-Asset RSI | 500 tickers x 2k bars | 0.4398 s | 0.0545 s | 8.1x Faster |
| Multi-Asset SMA | 500 tickers x 2k bars | 0.1345 s | 0.0168 s | 8.0x Faster |
| Z-Score Normalization | 1,000,000 bars | 0.0450 s | 0.0267 s | 1.7x Faster |
| Exponential Moving Average | 1,000,000 bars | 0.0100 s | 0.0069 s | 1.5x Faster |
| Simple Moving Average | 1,000,000 bars | 0.0170 s | 0.0153 s | 1.1x Faster |
Reproduce benchmarks locally using pip install -e .[benchmark] followed by python benchmarks/benchmark_speed.py.
Key Features
- Dual Expression Namespaces: Call indicators via
pl.col("close").anta.<indicator>()or the classic shorthandpl.col("close").ta.<indicator>(). - Expression-First Design: Compose indicators directly within
.select(),.with_columns(), and lazy query plans. - Parallel Multi-Asset Computation: Compute indicators across thousands of tickers in parallel using Polars' native window context:
pl.col("close").anta.rsi(14).over("symbol")
- Structured Outputs: Multi-component indicators (MACD, Bollinger Bands, Stochastic, Keltner Channels) return typed
pl.Structexpressions that maintain clean schemas. - Zero-C Compilation:
pip install polars-antaworks out of the box across Linux, macOS, and Windows.
Installation
pip install polars-anta
Requirements: Python >= 3.10, Polars >= 1.0.0
Quickstart
1. Modern Chained Expression Syntax (.anta or .ta)
import polars as pl
import polars_anta # Registers both `.anta` and `.ta` expression namespaces
df = pl.DataFrame(
{
"open": [100.0, 102.0, 101.5, 103.0, 105.0],
"high": [101.5, 103.5, 103.0, 104.5, 106.5],
"low": [98.8, 100.8, 100.3, 101.8, 103.8],
"close": [100.0, 102.0, 101.5, 103.0, 105.0],
"volume": [1000, 1050, 1100, 1150, 1200],
}
)
# Compute indicators directly on expressions (using .anta or .ta)
result = df.with_columns(
pl.col("close").anta.sma(period=3).alias("sma_3"),
pl.col("close").anta.rsi(period=3).alias("rsi_3"),
pl.col("close").anta.bollinger_bands(period=3).alias("bb"),
)
# Unnest structured outputs as needed
print(result.unnest("bb"))
2. Market-Wide Multi-Asset Parallel Execution
Running technical indicators across an entire investment universe is a common bottleneck. In polars-anta, Polars distributes evaluation across all CPU cores automatically:
# Compute indicators across thousands of symbols simultaneously in Rust
universe.with_columns(
[
pl.col("close").anta.sma(20).over("ticker").alias("sma_20"),
pl.col("close").anta.rsi(14).over("ticker").alias("rsi_14"),
pl.col("close").anta.macd().over("ticker").alias("macd"),
pl.col("close").anta.obv("volume").over("ticker").alias("obv"),
]
)
3. Interactive Jupyter Notebooks
Run our interactive tutorials directly in your browser with zero setup:
Supported Indicators (100 Indicators)
Trend & Overlays (25 Indicators)
sma(close, period=10): Simple Moving Averageema(close, period=10): Exponential Moving Averagewma(close, period=10): Linearly-Weighted Moving Averagehma(close, period=10): Hull Moving Averagedema(close, period=10): Double Exponential Moving Averagetema(close, period=10): Triple Exponential Moving Averagezlema(close, period=10): Zero-Lag Exponential Moving Averagevortex(high, low, close, period=14): Vortex Indicator (vi_plus,vi_minus)adx(high, low, close, period=14): Average Directional Index (adx,plus_di,minus_di)aroon(high, low, period=25): Aroon Oscillator & Indicator (up,down,oscillator)chop(high, low, close, period=14): Choppiness Index (Trend vs Consolidation)t3(close, period=5, vfactor=0.7): Tillson T3 Moving Averagealma(close, period=9, offset=0.85, sigma=6.0): Arnaud Legoux Moving Average (Gaussian-filtered)mass_index(high, low, fast_period=9, slow_period=25): Mass Index (Reversal predictor)supertrend(high, low, close, period=10, multiplier=3.0): SuperTrend Volatility Stop (supertrend,direction)psar(high, low, af_step=0.02, af_max=0.2): Parabolic Stop and Reverse (Trailing SAR)kama(close, period=10, fast_span=2, slow_span=30): Kaufman's Adaptive Moving Averagemcginley_dynamic(close, period=14, k=0.6): McGinley Dynamic Averagevidya(close, period=9, cmo_period=9): Variable Index Dynamic Average (Chande's VIDYA)center_of_gravity(close, period=10): Ehlers Center of Gravity Oscillatorichimoku(high, low, close, tenkan=9, kijun=26, senkou_b=52, displacement=26): Ichimoku Kinko Hyo Cloudpivot_points(high, low, close): Floor Trader Standard Pivot Points (pivot,r1-r3,s1-s3)fibonacci_pivots(high, low, close): Fibonacci Pivot Points (38.2%, 61.8%, 100%)camarilla_pivots(high, low, close): Camarilla Intraday Pivot Points (r1-r4,s1-s4)woodie_pivots(open, high, low, close): Woodie's Heavy-Close Pivot Points
Momentum (19 Indicators)
rsi(close, period=14): Relative Strength Index (Wilder's smoothing)macd(close, fast=12, slow=26, signal=9): Moving Average Convergence Divergence (macd,signal,histogram)stochastic(high, low, close, k=14, d=3): Stochastic Oscillator (%K, %D)williams_r(high, low, close, period=14): Williams %Rcci(high, low, close, period=20): Commodity Channel Indexroc(close, period=10): Rate of Change (Momentum %)stoch_rsi(close, rsi_period=14, stoch_period=14): Stochastic RSI (%K, %D)awesome_oscillator(high, low, fast=5, slow=34): Awesome Oscillator (AO)tsi(close, long_period=25, short_period=13): True Strength Index (TSI)cmo(close, period=14): Chande Momentum Oscillatorppo(close, fast=12, slow=26, signal=9): Percentage Price Oscillator (ppo,signal,histogram)coppock(close, wma_period=10, fast_roc=11, slow_roc=14): Coppock Curveultimate_oscillator(high, low, close, p1=7, p2=14, p3=28): Ultimate Oscillator (UO)fisher_transform(high, low, period=10): Ehlers Fisher Transform (fisher,signal)rvi(open, high, low, close, period=10): Relative Vigor Index (rvi,signal)kst(close): "Know Sure Thing" Oscillator (kst,signal)dpo(close, period=20): Detrended Price Oscillatorbop(open, high, low, close): Balance of Market Powercfo(close, period=14): Chande Forecast Oscillator
Volatility & Channels (18 Indicators)
true_range(high, low, close): True Rangeatr(high, low, close, period=14): Average True Rangebollinger_bands(close, period=20, num_std=2.0): Bollinger Bands (Upper, Middle, Lower, Bandwidth, %B)keltner_channels(high, low, close, ema=20, atr=10, multiplier=2.0): Keltner Channelsdonchian_channels(high, low, period=20): Donchian Channels (Upper, Middle, Lower)stddev(close, period=20): Rolling Standard Deviationulcer_index(close, period=14): Ulcer Index (Downside Drawdown Risk)chandelier_exit(high, low, close, period=22, multiplier=3.0): Chandelier Exit (long_stop,short_stop)natr(high, low, close, period=14): Normalized Average True Range (%)historical_volatility(close, period=20, trading_days=252): Annualized Log Historical Volatilityparkinson_volatility(high, low, period=20, trading_days=252): Parkinson Extreme-Value Volatilitygarman_klass_volatility(open, high, low, close, period=20, trading_days=252): Garman-Klass Efficient Volatilitychaikin_volatility(high, low, period=10, roc_period=10): Chaikin Volatilitydonchian_width(high, low, period=20): Donchian Channel Width (%)envelopes(close, period=20, percentage=0.025): Moving Average Envelopes (upper,middle,lower)keltner_width(high, low, close, ema=20, atr=10, multiplier=2.0): Normalized Keltner Channel Width (%)bollinger_delta(close, period=20, num_std=2.0): Bollinger Band Spread ($2 \cdot k \cdot \sigma$)starc_bands(high, low, close, period=20, atr_period=15, multiplier=2.0): STARC Bands (Stoller Average Range Channels)
Volume (14 Indicators)
obv(close, volume): On-Balance Volumevwap(high, low, close, volume, period=None): Volume Weighted Average Price (Cumulative or Rolling)vwma(close, volume, period=20): Volume Weighted Moving Averagecmf(high, low, close, volume, period=20): Chaikin Money Flowadl(high, low, close, volume): Accumulation/Distribution Linemfi(high, low, close, volume, period=14): Money Flow Indexeom(high, low, volume, period=14): Ease of Movement (EMV)klinger(high, low, close, volume, fast=34, slow=55, signal=13): Klinger Volume Oscillator (klinger,signal)nvi(close, volume): Negative Volume Indexpvi(close, volume): Positive Volume Indexpvt(close, volume): Price Volume Trendforce_index(close, volume, period=13): Elder's Force Indexvpci(close, volume, short_period=5, long_period=20): Volume Price Confirmation Indicatorvr(close, volume, period=26): Volume Ratio (Bullish vs Bearish volume)
Quantitative Statistics & Regression (12 Indicators)
zscore(close, period=20): Rolling Z-Score standardized anomaly scorepercentile_rank(close, period=20): Rolling Percentile Rank $[0.0, 1.0]$skewness(close, period=20): Rolling Sample Skewness (asymmetry metric)kurtosis(close, period=20): Rolling Excess Kurtosis (tail-risk metric)rolling_cov(x, y, period=20): Rolling Sample Covariance between two seriesrolling_corr(x, y, period=20): Rolling Pearson Correlation $[-1.0, 1.0]$rolling_beta(asset_ret, bench_ret, period=60): Rolling CAPM Market Beta ($\text{Cov} / \text{Var}$)rolling_alpha(asset_ret, bench_ret, rf=0.0, period=60): Rolling Jensen's Risk-Adjusted Alphalinear_regression_slope(close, period=14): Vectorized OLS Linear Regression Slopelinear_regression_intercept(close, period=14): Vectorized OLS Linear Regression Interceptlinear_regression_angle(close, period=14): Linear Regression Trend Angle in degreeslinear_regression_forecast(close, period=14): Linear Regression Current/Next-Bar Value Forecast
Alpha Factor Primitives (12 Indicators)
ts_rank(close, period=10): Time-Series Rank (WorldQuant Alpha 101 primitive)ts_argmax(close, period=10): Time-Series ArgMax (lookback bars ago of window peak)ts_argmin(close, period=10): Time-Series ArgMin (lookback bars ago of window trough)decay_linear(close, period=10): Linearly Weighted Decay moving transformts_zscore(close, period=20): Time-Series Standardized Normalizationreturns_divergence(close, volume, period=14): Price vs Volume Momentum Divergencehl_ratio(high, low): Log Intraday Range Expansion $\ln(\text{High} / \text{Low})$co_ratio(close, open): Log Intraday Sentiment Drift $\ln(\text{Close} / \text{Open})$volume_weighted_momentum(close, volume, period=10): Momentum amplified by relative volumerelative_spread(high, low, close): Normalized Bar Range $(\text{High} - \text{Low}) / \text{Close}$twap(high, low, close, period=20): Rolling Time-Weighted Average Priceentropy(close, period=20, bins=5): Rolling Shannon Information Entropy (Regime detector)
Architecture & Performance
polars-anta is designed around three architectural pillars:
- Arrow Memory Layout: Avoids memory copying between indicator transformations.
- SIMD-Accelerated Vectorization: Executes through Polars' optimized analytical kernels.
- Query Optimization: Integrates with Polars' expression engine for predicate pushdown and dead-code elimination.
Development & Testing
# Clone the repository
git clone https://github.com/huuan26/polars-anta.git
cd polars-anta
# Install in editable mode with development dependencies
pip install -e .[dev]
# Run the test suite
pytest -v
# Run linter and formatter checks
ruff check .
ruff format --check .
Author & Community
- Author: An Phan (Phan Bùi Hữu Ân) - phanbuihuuan261103@gmail.com
- GitHub: @huuan26
- Discussion & Feature Requests: GitHub Discussions
License
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Metadata
Release files for polars-anta 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| polars_anta-0.1.0.tar.gz | 226.2 kB | With provenance | Details for polars_anta-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| polars_anta-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for polars_anta-0.1.0-py3-none-any.whl |
Total release size: 264.3 kB
Release files / polars_anta-0.1.0.tar.gz
| Download URL | polars_anta-0.1.0.tar.gz |
|---|---|
| Size | 226.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4f08148815fe9732befa9c9007e78cd0dd5f26313e4d035b3f02eccc5864cc51
|
|
BLAKE2b-256 checksum How to use checksums |
619c514f19b67a3f642f53c5b2fb3754343d10f95454d0963f8d6618e06ee976
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / polars_anta-0.1.0-py3-none-any.whl
| Download URL | polars_anta-0.1.0-py3-none-any.whl |
|---|---|
| Size | 38.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
91fab1c0fc42c3a8667a882f6982987e4104855e98c41a7bf7f37876ac5ab774
|
|
BLAKE2b-256 checksum How to use checksums |
6a6b19290bd3c9b6eea6e262e723ade4526e8dcd6801604391692d2b0f0081d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logSecurity for polars-anta 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for polars_anta-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.