📈 TinyCTA¶
A Lightweight Python Package for Commodity Trading Advisor Strategies.
Quick Links: 📚 Repository • 📦 PyPI • 🐛 Issues • 💬 Discussions
📋 Overview¶
TinyCTA provides essential tools for quantitative finance and algorithmic trading, particularly for trend-following strategies. The package includes:
- Polars-based signal processing: oscillators, moving-average crossovers, and volatility-adjusted returns
- Robust volatility estimation via rolling median absolute deviation
- Linear algebra utilities that handle matrices with missing values
- Matrix shrinkage techniques commonly used in portfolio optimization
This package is designed to be the foundation for implementing CTA strategies in just a few lines of code, hence the name "TinyCTA".
🚀 Installation¶
Using pip¶
From source¶
Clone the repository and install using the provided Makefile:
This will install uv (a fast Python package installer) and create a virtual environment with all dependencies.
💻 Usage¶
Oscillator signal (Polars)¶
import polars as pl
from tinycta.osc import osc
prices = pl.DataFrame({"A": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})
result = prices.with_columns(osc(pl.col("A"), fast=2, slow=6).alias("osc_A"))
Moving-average crossover (Polars)¶
import polars as pl
from tinycta.ewma import ma_cross
prices = pl.DataFrame({"A": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})
result = prices.with_columns(
ma_cross(pl.col("A"), fast=2, slow=6).alias("sig_A")
)
Volatility-adjusted returns (Polars)¶
import polars as pl
from tinycta.util import vol_adj, adj_log_prices
prices = pl.DataFrame({"A": [100, 101, 99, 102, 98, 103]})
result = prices.with_columns(
vol_adj(pl.col("A"), vola=3, clip=4.2).alias("vol_adj_A"),
adj_log_prices(pl.col("A"), vola=3, clip=4.2).alias("adj_log_A"),
)
Linear algebra operations¶
import numpy as np
from tinycta.linalg import solve
matrix = np.array([[1.0, 0.5], [0.5, 1.0]])
rhs = np.array([1.0, 2.0])
solution = solve(matrix, rhs)
print(np.round(solution, 10) + 0)
📚 API Reference¶
Signal Processing (tinycta.osc, tinycta.ewma, tinycta.util)¶
osc(x, fast, slow, min_samples=1)— analytically scaled EWMA-difference oscillator (Polars)ma_cross(prices, fast, slow, min_samples=1)— sign of fast-vs-slow EWM crossover: -1, 0, or +1 (Polars)vol_adj(x, vola, clip, min_samples=1)— clipped, volatility-adjusted log returns (Polars)adj_log_prices(x, vola, clip, min_samples=1)— cumulative sum of volatility-adjusted log returns (Polars)
Signal Utilities (tinycta.signal)¶
moving_absolute_deviation(price, com=32)— robust rolling volatility estimate via median absolute deviation (pandas)shrink2id(matrix, lamb=1.0)— shrink a matrix towards the identity matrix
Linear Algebra (tinycta.linalg)¶
valid(matrix)— extract the finite subset of a matrix by filtering NaN rows/columnsa_norm(vector, matrix=None)— matrix-norm of a vectorinv_a_norm(vector, matrix=None)— inverse matrix-norm of a vectorsolve(matrix, rhs)— solve a linear system, handling matrices with NaN values
🛠️ Development¶
Setting up the development environment¶
Running tests¶
Code formatting and linting¶
Cleaning up¶
📄 License¶
TinyCTA is licensed under the MIT License. See the LICENSE file for details.
🤝 Contributing¶
Contributions are welcome! Please feel free to submit a Pull Request.