boruta-quant
Temporal-aware Boruta feature selection for quantitative finance.
boruta-quant computes feature importance on validation data only, using purged cross-validation to prevent lookahead bias. Built for financial time series where temporal integrity matters.
Why boruta-quant?
Standard feature selection (SHAP, sklearn permutation importance) computes importance on training data. In financial time series, this leaks future information into feature rankings. boruta-quant fixes this:
- OOS-Only Importance: Importance computed exclusively on validation folds
- Purged Cross-Validation: Train/test gap with purge and embargo windows
- Shadow Features: Boruta's all-relevant selection via shadow comparison
Installation
# Basic (permutation importance only)
pip install boruta-quant
# With LightGBM
pip install boruta-quant[lightgbm]
# With SHAP support
pip install boruta-quant[shap]
# Everything
pip install boruta-quant[all]
Development
git clone https://github.com/BlackArbsCEO/boruta-quant.git
cd boruta-quant
uv sync --all-extras --dev
Quick Start
from boruta_quant import BorutaSelector, BorutaSelectorConfig
from boruta_quant.oracle import PermutationImportanceOracle
from boruta_quant.temporal import PurgedTemporalCV, PurgedCVConfig
from boruta_quant.metrics import rank_ic_scorer
from lightgbm import LGBMRegressor
# 1. Configure purged temporal CV
cv = PurgedTemporalCV(PurgedCVConfig(
n_splits=5,
purge_window_days=5, # gap before validation fold
embargo_window_days=5, # gap after validation fold
min_train_size=100,
test_size_ratio=0.2,
))
# 2. Configure importance oracle (OOS-only)
oracle = PermutationImportanceOracle(
scoring=rank_ic_scorer, # Spearman rank correlation
n_repeats=10,
random_state=42,
)
# 3. Configure Boruta selector
selector = BorutaSelector(
config=BorutaSelectorConfig(
n_trials=20, # Boruta iterations
percentile=100, # shadow threshold percentile
alpha=0.05, # significance level
two_step=True, # resolve tentative features
random_state=42,
),
oracle=oracle,
cv=cv,
)
# 4. Fit — model goes here, not in the constructor
result = selector.fit(
X, y,
timestamps=timestamps, # must be timezone-aware
model=LGBMRegressor(n_estimators=100, random_state=42),
)
# 5. Results
print(result.accepted_features) # confirmed important
print(result.rejected_features) # confirmed unimportant
print(result.tentative_features) # borderline (resolved if two_step=True)
Importance Oracles
All oracles fit the model on training data but measure importance on validation data only.
| Oracle | How it works | When to use |
|---|---|---|
PermutationImportanceOracle |
Shuffles one feature in validation set, measures prediction drop | Default — reliable, no refit needed |
DropColumnImportanceOracle |
Removes feature, refits model, measures prediction drop | When refit cost is acceptable |
BlockPermutationImportanceOracle |
Block-shuffles feature (preserves autocorrelation structure) | Autocorrelated time series |
Temporal Cross-Validation
Training Purge Validation Embargo
|--------------| |-------| |----------| |-------|
^ ^
train_start embargo_end
- Purge: removes observations that could leak into validation
- Embargo: prevents information from validation bleeding forward
Shadow Shuffle Modes
Shadow features are shuffled copies of real features. The shuffle mode controls how temporal structure is handled:
| Mode | Description | Use case |
|---|---|---|
ShuffleMode.RANDOM |
Standard i.i.d. permutation | Default — i.i.d. data |
ShuffleMode.BLOCK |
Block-preserving shuffle | Autocorrelated features |
ShuffleMode.ERA |
Shuffle within eras only | Regime-aware selection |
Metrics
| Function | Description |
|---|---|
rank_ic |
Spearman correlation between predictions and actuals |
rank_ic_scorer |
sklearn-compatible scorer wrapping rank_ic |
directional_accuracy |
Fraction of correct sign predictions (up vs down) |
directional_accuracy_scorer |
sklearn-compatible scorer wrapping directional_accuracy |
auc_score |
Area under ROC curve |
auc_scorer |
sklearn-compatible scorer wrapping auc_score |
Design Principles
- OOS-Only: Importance never computed on training data
- Fail-Fast: Invalid temporal data (naive timestamps, unsorted) raises immediately
- Type-Safe: Runtime enforcement with beartype, strict Pyright
- Explicit: All config parameters required — no hidden defaults
References
- Boruta Algorithm — Kursa & Rudnicki (2010)
- Advances in Financial Machine Learning — Lopez de Prado (2018), Ch. 7 (purged CV)
License
MIT — see LICENSE.
Metadata
Release files for boruta-quant 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| boruta_quant-0.1.1.tar.gz | 43.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| boruta_quant-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 75.8 kB
Release files / boruta_quant-0.1.1.tar.gz
| Download URL | boruta_quant-0.1.1.tar.gz |
|---|---|
| Size | 43.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
db5e310f18f8187b32d93ed1d139805ca425963e5cdddd69d2fa3ef07aa87455
|
|
BLAKE2b-256 checksum How to use checksums |
cd912e526d998557e277ac4835ac0e15d95e980d14d6867ebeee6600ddf5a042
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / boruta_quant-0.1.1-py3-none-any.whl
| Download URL | boruta_quant-0.1.1-py3-none-any.whl |
|---|---|
| Size | 31.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8e73c83c177a5c0e5d418dc5f34c3b4219486c152eda4f52945b5242310eb6e7
|
|
BLAKE2b-256 checksum How to use checksums |
cd887908b72ec8d17c2680cf33a1cded91b16ac93d23e0cb69b230a916355657
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|