A Compact Recurrent-Invariant Eigenvalue Network for Portfolio Optimization
Project description
Compact-RIEnet: A Compact Rotational Invariant Estimator Network for GMV Optimisation
Compact-RIEnet is a neural architecture purpose-built for global minimum-variance (GMV) portfolio optimisation. The model combines Rotational Invariant Estimator (RIE) techniques for covariance cleaning with recurrent neural networks, allowing it to capture both cross-sectional structure and temporal dynamics in financial data.
Key Features
- GMV-First Design – End-to-end training minimises realised portfolio variance
- RIE-Based Cleaning – Rotational Invariant Estimators denoise the covariance spectrum for stable optimisation
- Dimension Agnostic – Train on mixed asset universes and deploy on unseen sizes without architectural changes
- Configurable Recurrent Core – Switch between GRU/LSTM cleaners and customise hidden stacks while retaining paper defaults
- Professional Implementation – Comprehensive documentation, type hints, and test coverage
Installation
Install from PyPI:
pip install compact-rienet
Or install from source:
git clone https://github.com/author/compact-rienet.git
cd compact-rienet
pip install -e .
Quick Start
Basic Usage
import tensorflow as tf
from compact_rienet import CompactRIEnetLayer, variance_loss_function
# Defaults reproduce the compact GMV architecture (bidirectional GRU with 16 units)
rienet_layer = CompactRIEnetLayer(output_type=['weights', 'precision'])
# Sample data: (batch_size, n_stocks, n_days)
returns = tf.random.normal((32, 10, 60), stddev=0.02)
# Retrieve GMV weights and cleaned precision in one pass
outputs = rienet_layer(returns)
weights = outputs['weights'] # (32, 10, 1)
precision = outputs['precision'] # (32, 10, 10)
# GMV training objective
covariance = tf.random.normal((32, 10, 10))
covariance = tf.matmul(covariance, covariance, transpose_b=True)
loss = variance_loss_function(covariance, weights)
print(loss.shape) # (32, 1, 1)
Training with the GMV Variance Loss
import tensorflow as tf
from compact_rienet import CompactRIEnetLayer, variance_loss_function
def create_portfolio_model():
inputs = tf.keras.Input(shape=(None, None))
weights = CompactRIEnetLayer(output_type='weights')(inputs)
return tf.keras.Model(inputs=inputs, outputs=weights)
model = create_portfolio_model()
# Synthetic training data
X_train = tf.random.normal((1000, 10, 60), stddev=0.02)
Sigma_train = tf.random.normal((1000, 10, 10))
Sigma_train = tf.matmul(Sigma_train, Sigma_train, transpose_b=True)
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-4, clipnorm=1.0)
model.compile(optimizer=optimizer, loss=variance_loss_function)
model.fit(X_train, Sigma_train, epochs=10, batch_size=32, verbose=True)
Tip: When you intend to deploy Compact-RIEnet on portfolios of varying size, train on batches that span different asset universes. The RIE-based architecture is dimension agnostic and benefits from heterogeneous training shapes.
Using Different Output Types
# GMV weights only
weights = CompactRIEnetLayer(output_type='weights')(returns)
# Precision matrix only
precision_matrix = CompactRIEnetLayer(output_type='precision')(returns)
# Both precision and covariance in one pass
outputs = CompactRIEnetLayer(output_type=['precision', 'covariance'])(returns)
precision_matrix = outputs['precision']
covariance_matrix = outputs['covariance']
Loss Function
Variance Loss Function
from compact_rienet import variance_loss_function
loss = variance_loss_function(
covariance_true=true_covariance, # (batch_size, n_assets, n_assets)
weights_predicted=predicted_weights # (batch_size, n_assets, 1)
)
Mathematical Formula:
Loss = n_assets × wᵀ Σ w
Where w are the portfolio weights and Σ is the realised covariance matrix.
Architecture Details
The Compact-RIEnet pipeline consists of:
- Input Scaling – Annualise returns by 252
- Lag Transformation – Five-parameter memory kernel for temporal weighting
- Covariance Estimation – Sample covariance across assets
- Eigenvalue Decomposition – Spectral analysis of the covariance matrix
- Recurrent Cleaning – Bidirectional GRU/LSTM processing of eigen spectra
- Marginal Volatility Head – Dense network forecasting inverse standard deviations
- Matrix Reconstruction – RIE-based synthesis of Σ⁻¹ and GMV weight normalisation
Paper defaults use a single bidirectional GRU layer with 16 units per direction and a marginal-volatility head with 8 hidden units, matching the compact network described in Bongiorno et al. (2025).
Requirements
- Python ≥ 3.8
- TensorFlow ≥ 2.10.0
- Keras ≥ 2.10.0
- NumPy ≥ 1.21.0
Development
git clone https://github.com/author/compact-rienet.git
cd compact-rienet
pip install -e ".[dev]"
pytest tests/
Citation
Please cite the following references when using Compact-RIEnet:
@inproceedings{bongiorno2025compact,
title={Neural Network-Driven Volatility Drag Mitigation under Aggressive Leverage},
author={Bongiorno, Christian and Manolakis, Efstratios and Mantegna, Rosario N.},
booktitle={Proceedings of the 6th ACM International Conference on AI in Finance (ICAIF '25)},
year={2025}
}
@article{bongiorno2025covariance,
title={End-to-End Large Portfolio Optimization for Variance Minimization with Neural Networks through Covariance Cleaning},
author={Bongiorno, Christian and Manolakis, Efstratios and Mantegna, Rosario N.},
journal={arXiv preprint arXiv:2507.01918},
year={2025}
}
For software citation:
@software{compact_rienet2025,
title={Compact-RIEnet: A Compact Rotational Invariant Estimator Network for Global Minimum-Variance Optimisation},
author={Bongiorno, Christian},
year={2025},
version={1.0.0},
url={https://github.com/author/compact-rienet}
}
You can print citation information programmatically:
import compact_rienet
compact_rienet.print_citation()
Support
For questions, issues, or contributions, please:
- Open an issue on GitHub
- Check the documentation
- Contact Prof. Christian Bongiorno (christian.bongiorno@centralesupelec.fr) for calibrated model weights or collaboration requests
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file compact_rienet-1.0.2.tar.gz.
File metadata
- Download URL: compact_rienet-1.0.2.tar.gz
- Upload date:
- Size: 23.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
452a2e13fe0602c06e08cda7103f6feba7076511b290abee7b87f1f4cb005f09
|
|
| MD5 |
d87f6c7cb3cda72c299359c87e52a8d1
|
|
| BLAKE2b-256 |
680a46b3bdc096f714f889e27f99d4c87236f95e2a7f747684adafd5cf1488e8
|
Provenance
The following attestation bundles were made for compact_rienet-1.0.2.tar.gz:
Publisher:
publish.yml on bongiornoc/Compact-RIEnet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
compact_rienet-1.0.2.tar.gz -
Subject digest:
452a2e13fe0602c06e08cda7103f6feba7076511b290abee7b87f1f4cb005f09 - Sigstore transparency entry: 571434589
- Sigstore integration time:
-
Permalink:
bongiornoc/Compact-RIEnet@16484e899eaaf860583aecbed7b17cffe5653f7d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/bongiornoc
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@16484e899eaaf860583aecbed7b17cffe5653f7d -
Trigger Event:
push
-
Statement type:
File details
Details for the file compact_rienet-1.0.2-py3-none-any.whl.
File metadata
- Download URL: compact_rienet-1.0.2-py3-none-any.whl
- Upload date:
- Size: 19.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6188027c91965c4f8cb5b6836590594910d6f77ac73f17cca62675a6d50ddbe1
|
|
| MD5 |
bf7332d49de14ea035d0511466b9539b
|
|
| BLAKE2b-256 |
55583b9d0553750cd5cf87ae2fade5f5dd69b087ecb394702f0c444751d32fcd
|
Provenance
The following attestation bundles were made for compact_rienet-1.0.2-py3-none-any.whl:
Publisher:
publish.yml on bongiornoc/Compact-RIEnet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
compact_rienet-1.0.2-py3-none-any.whl -
Subject digest:
6188027c91965c4f8cb5b6836590594910d6f77ac73f17cca62675a6d50ddbe1 - Sigstore transparency entry: 571434663
- Sigstore integration time:
-
Permalink:
bongiornoc/Compact-RIEnet@16484e899eaaf860583aecbed7b17cffe5653f7d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/bongiornoc
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@16484e899eaaf860583aecbed7b17cffe5653f7d -
Trigger Event:
push
-
Statement type: