A significant improvement over https://github.com/sethdford/deep_risk_model-v0 which is a Rust implementation of a deep learning-based risk model for financial markets, inspired by the research paper "Deep Risk Model: A Deep Learning Solution for Mining Latent Risk Factors to Improve Covariance Matrix Estimation" (Lin et al., 2021). This project combines Graph Attention Networks (GAT) and Gated Recurrent Units (GRU) to generate risk factors and estimate covariance matrices from market data.
- Advanced Risk Modeling: Transformer architecture, Temporal Fusion Transformer (TFT), Factor Analysis
- Market Intelligence: Regime Detection with HMM, Adaptive Risk Estimation
- Performance Optimizations: GPU acceleration, Quantization, Memory optimization
- Production Ready: Thread-safe, Error handling, No-BLAS fallback, Python bindings
- Comprehensive Testing: Backtesting framework, Benchmarks, CI/CD integration
Comprehensive documentation is available to help you get started:
- Architecture - System architecture and capabilities
- Theory - Theoretical foundations
- Use Cases - Application scenarios
- Benchmarks - Detailed performance metrics
- Sprint Backlog - Development progress
- Academic Documentation - Formal mathematical description and theoretical foundations
- Technical Documentation - Comprehensive API reference and developer guides
API Documentation: Run cargo doc --open
for detailed API reference
Add this to your Cargo.toml
:
[dependencies]
deep_risk_model = "0.1.0"
use deep_risk_model::prelude::{DeepRiskModel, MarketData, RiskModel};
use ndarray::Array2;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create sample data
let n_assets = 64;
let n_samples = 100;
let features = Array2::zeros((n_samples, n_assets));
let returns = Array2::zeros((n_samples, n_assets));
let data = MarketData::new(returns, features);
// Create and train model
let mut model = DeepRiskModel::new(n_assets, 5)?;
model.train(&data).await?;
// Generate risk factors
let risk_factors = model.generate_risk_factors(&data).await?;
// Estimate covariance matrix
let covariance = model.estimate_covariance(&data).await?;
Ok(())
}
use deep_risk_model::prelude::{
TransformerRiskModel, MarketData, RiskModel,
MemoryConfig, QuantizationConfig, QuantizationPrecision
};
// Create model with memory optimization
let mut model = TransformerRiskModel::new(64, 8, 256, 3)?;
// Configure memory optimization
let memory_config = MemoryConfig {
use_sparse_tensors: true,
sparsity_threshold: 0.7,
use_chunked_processing: true,
chunk_size: 1000,
..Default::default()
};
model.set_memory_config(memory_config);
// Quantize model for memory reduction
let quant_config = QuantizationConfig {
precision: QuantizationPrecision::Int8,
per_channel: true,
};
model.quantize(quant_config)?;
For more detailed examples, see the Use Cases documentation.
This library uses platform-specific BLAS implementations by default:
- macOS: Uses Apple's Accelerate framework for optimal performance
- Windows: Uses OpenBLAS via vcpkg
- Linux/Others: Uses OpenBLAS
You can build with the default platform-specific implementation:
# Build with the platform-specific default
cargo build
Or you can override the default by specifying a feature:
# Use OpenBLAS explicitly
cargo build --no-default-features --features openblas
# Use Netlib
cargo build --no-default-features --features netlib
# Use Intel MKL
cargo build --no-default-features --features intel-mkl
# Use Accelerate (macOS only)
cargo build --no-default-features --features accelerate
# Use system BLAS (required for Windows with vcpkg)
cargo build --no-default-features --features system
# Build without BLAS (pure Rust implementation)
cargo build --no-default-features --features no-blas
sudo apt-get install -y libopenblas-dev gfortran
No additional dependencies required by default (uses built-in Accelerate framework).
If you want to use OpenBLAS instead:
brew install openblas
For Windows, it's recommended to use vcpkg:
# Install vcpkg if you haven't already
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.bat
./vcpkg.exe integrate install
# Install OpenBLAS
./vcpkg.exe install openblas:x64-windows
Then build with the system
feature:
cargo build --no-default-features --features system
The library includes a pure Rust fallback implementation for environments where BLAS is not available:
- ✅ Automatic fallback to pure Rust implementation when BLAS is not available
- ✅ Matrix multiplication and inversion implemented in pure Rust
- ✅ Comprehensive test suite for both BLAS and no-BLAS configurations
To use the no-BLAS implementation:
# Build without BLAS (pure Rust implementation)
cargo build --no-default-features --features no-blas
Note for Windows Users: The no-BLAS feature is currently not supported on Windows without vcpkg. If you need to build on Windows, please use vcpkg with the system feature or use WSL (Windows Subsystem for Linux).
Note for Performance: The no-BLAS implementation is significantly slower for large matrices. It's recommended to use a BLAS implementation for production use.
[dependencies]
ndarray = "0.15.6"
ndarray-linalg = { version = "0.16", features = ["openblas-system"] }
ndarray-rand = "0.14.0"
ndarray-stats = "0.5.1"
tokio = { version = "1.0", features = ["full", "macros", "rt-multi-thread"] }
criterion = "0.5"
rand = "0.8"
anyhow = "1.0"
thiserror = "1.0"
# GPU acceleration (optional)
cuda-runtime-sys = { version = "0.7.0", optional = true }
cublas-sys = { version = "0.7.0", optional = true }
curand-sys = { version = "0.7.0", optional = true }
[features]
default = []
gpu = ["cuda-runtime-sys", "cublas-sys", "curand-sys"]
openblas-system = ["ndarray-linalg/openblas-system"]
- 🚀 Hardware-accelerated matrix operations via OpenBLAS
- 🔥 GPU acceleration for high-performance computing (optional)
- 💾 Memory optimization for handling large models and datasets
- 📊 Model compression through quantization
- 🔄 Async runtime with Tokio
- 🌐 REST API with Axum
- 📊 Comprehensive benchmarking with criterion.rs
deep_risk_model/
├── src/
│ ├── transformer/ # Transformer architecture
│ │ ├── attention.rs # Multi-head attention
│ │ ├── position.rs # Positional encoding
│ │ ├── layer.rs # Transformer layers
│ │ ├── model.rs # Transformer model
│ │ └── temporal_fusion.rs # TFT implementation
│ ├── factor_analysis.rs # Factor analysis utilities
│ ├── model.rs # Core risk model
│ ├── transformer_risk_model.rs # Transformer-based risk model
│ ├── tft_risk_model.rs # TFT-based risk model
│ ├── gpu.rs # GPU acceleration utilities
│ ├── gpu_transformer_risk_model.rs # GPU-accelerated transformer
│ ├── gpu_model.rs # GPU-accelerated deep risk model
│ ├── quantization.rs # Model compression through quantization
│ ├── memory_opt.rs # Memory optimization utilities
│ └── utils.rs # Utility functions
├── benches/
│ ├── model_benchmarks.rs
│ └── transformer_benchmarks.rs
├── examples/
│ ├── quantization_example.rs # Example of model quantization
│ └── memory_optimization_example.rs # Example of memory optimization
└── tests/
└── integration_tests.rs
- CPU: Modern processor with SIMD support
- RAM: 8GB minimum (16GB recommended)
- OS: Linux, macOS, or Windows with OpenBLAS
- Rust: 2021 edition or later
Run all tests with:
cargo test --features openblas
For tests that don't require BLAS:
cargo test --no-default-features --features no-blas -- --skip factor_analysis::tests::test_factor_selection --skip gpu_model::tests::test_gpu_factor_metrics --skip model::tests::test_factor_generation --skip model::tests::test_factor_metrics --skip model::tests::test_covariance_estimation --skip gpu_model::tests::test_gpu_factor_generation --skip gpu_model::tests::test_gpu_vs_cpu_performance
Or use the provided script:
./run_tests.sh
Run examples with:
cargo run --example quantization_example --features openblas
cargo run --example memory_optimization_example --features openblas
Contributions are welcome! Please check our Contributing Guidelines for details.
This project is licensed under the MIT License - see the LICENSE file for details.
This implementation is based on academic research that demonstrates how deep learning can be used to mine latent risk factors and improve covariance matrix estimation. The original paper shows:
- 1.9% higher explained variance (measured by R²)
- Improved risk reduction in global minimum variance portfolios
- Novel approach to learning risk factors using neural networks
- Effective combination of temporal and cross-sectional features
┌─────────────────────────────────────────────────────────────────────┐
│ Deep Risk Model │
├─────────────────┬─────────────────┬─────────────────┬───────────────┤
│ Transformer │ Temporal │ Factor │ Risk │
│ Architecture │ Fusion │ Analysis │ Modeling │
├─────────────────┼─────────────────┼─────────────────┼───────────────┤
│• Multi-head │• Variable │• Orthogonal- │• Covariance │
│ Attention │ Selection │ ization │ Estimation │
│• Positional │• Static │• Factor │• Risk Factor │
│ Encoding │• Temporal │• Metrics │ Analysis │
│• Feed-Forward │• Self-Attention │• Metrics │ Analysis │
│ Networks │• Temporal │• Metrics │ Analysis │
└─────────────────┴─────────────────┴─────────────────┴───────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ Memory Optimization │
├─────────────────┬─────────────────┬─────────────────┬───────────────┤
│ Sparse │ Chunked │ Gradient │ Memory │
│ Tensors │ Processing │ Checkpointing │ Management │
├─────────────────┼─────────────────┼─────────────────┼───────────────┤
│• Efficient │• Large Dataset │• Memory- │• Memory Pool │
│ Storage │ Processing │ Efficient │• Memory- │
│• Sparse Matrix │• Configurable │ Computation │ Mapped │
│ Operations │ Chunk Size │• Segment │ Arrays │
│• Memory Usage │• Progress │ Processing │• Efficient │
│ Tracking │ Tracking │• Memory Savings │ Allocation │
└─────────────────┴─────────────────┴─────────────────┴───────────────┘
- Deep learning-based risk factor generation
- Transformer architecture for feature processing
- Temporal Fusion Transformer for combining static and temporal features
- Covariance matrix estimation with improved accuracy
- Advanced factor analysis with orthogonalization
- Memory optimization for handling large models and datasets
- Model compression through quantization
- Comprehensive test suite and benchmarks
Add this to your Cargo.toml
:
[dependencies]
deep_risk_model = "0.1.0"
use deep_risk_model::prelude::{
DeepRiskModel, TransformerRiskModel, MarketData, RiskModel,
MemoryConfig, QuantizationConfig, QuantizationPrecision
};
use ndarray::Array2;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create sample data
let n_assets = 64;
let n_samples = 100;
let features = Array2::zeros((n_samples, n_assets));
let returns = Array2::zeros((n_samples, n_assets));
let data = MarketData::new(returns, features);
// Create model with memory optimization
let mut model = TransformerRiskModel::new(64, 8, 256, 3)?;
// Configure memory optimization
let memory_config = MemoryConfig {
use_sparse_tensors: true,
sparsity_threshold: 0.7,
use_chunked_processing: true,
chunk_size: 1000,
use_checkpointing: true,
checkpoint_segments: 4,
..Default::default()
};
model.set_memory_config(memory_config);
// Sparsify model weights
model.sparsify(0.1)?;
// Generate risk factors with memory-efficient processing
let risk_factors = model.generate_risk_factors(&data).await?;
// Quantize model for further memory reduction
let quant_config = QuantizationConfig {
precision: QuantizationPrecision::Int8,
per_channel: true,
};
model.quantize(quant_config)?;
// Check memory savings
let memory_usage = model.memory_usage();
println!("Memory usage: {} bytes", memory_usage);
Ok(())
}
For more detailed examples, see the Use Cases documentation.
The library provides GPU-accelerated versions of key components:
GPUDeepRiskModel
: GPU-accelerated deep risk modelGPUTransformerRiskModel
: GPU-accelerated transformer risk modelGPUConfig
: Configuration for GPU acceleration settings
To use GPU acceleration:
- Build with the
gpu
feature:cargo build --features gpu
- Use the GPU-accelerated model variants in your code
- Configure GPU settings using
GPUConfig
GPU acceleration provides significant performance improvements for:
- Matrix multiplication operations
- Attention mechanism computations
- Covariance matrix estimation
- Factor generation and analysis
Note: The current GPU implementation is a placeholder that demonstrates the architecture for GPU acceleration. It includes CPU fallbacks for all operations. Full CUDA integration requires uncommenting and updating the CUDA dependencies in Cargo.toml and installing the CUDA toolkit.
The models now support configurable dimensions:
// Create model with default dimensions (d_model = n_assets)
let model = DeepRiskModel::new(64, 5)?;
// Create model with custom dimensions
let model = DeepRiskModel::with_config(64, 5, 128, 8, 512, 3)?;
// Create model with custom transformer configuration
let config = TransformerConfig {
d_model: 128,
n_heads: 8,
d_ff: 512,
n_layers: 3,
// ... other config options
};
let model = DeepRiskModel::with_transformer_config(64, 5, config)?;
The same configuration options are available for GPUDeepRiskModel
.
This project provides cross-platform linear algebra support with two options:
By default, the project uses a pure Rust implementation of linear algebra operations via the linfa-linalg
crate. This approach:
- Requires no external dependencies
- Works on all platforms without configuration
- Is slightly slower for large matrices but perfectly adequate for most use cases
To use the pure Rust implementation (default):
cargo build
# or explicitly
cargo build --features pure-rust
For performance-critical applications with large matrices, you can enable BLAS acceleration:
# Use Apple's Accelerate framework (recommended on macOS)
cargo build --no-default-features --features accelerate
# Use OpenBLAS (common on Linux)
cargo build --no-default-features --features openblas
# Use Intel MKL
cargo build --no-default-features --features intel-mkl
The linear algebra module provides a unified interface regardless of which backend is used:
use deep_risk_model::linalg;
use ndarray::array;
// Create matrices
let a = array![[1.0, 2.0], [3.0, 4.0]];
let b = array![[5.0, 6.0], [7.0, 8.0]];
// Matrix multiplication
let c = linalg::matmul(&a, &b);
// SVD decomposition
let (u, s, v) = linalg::svd(&a).unwrap();
// Solve linear system
let x = array![1.0, 2.0];
let b = linalg::matvec(&a, &x);
let solution = linalg::solve(&a, &b).unwrap();
See the examples/linalg_example.rs
file for a complete demonstration.
This project can be deployed as an AWS Lambda function.
- Rust (stable)
- Docker (for SAM local development and deployment)
- AWS CLI (configured with appropriate credentials)
- SAM CLI
make build
make test
make generate-payload
make local-invoke
make sam-build
make sam-deploy
make sam-local-invoke
make sam-local-api
This project includes a GitHub Actions workflow that automatically deploys the Lambda function to AWS when changes are pushed to the main branch.
To set up CI/CD:
-
Add the following secrets to your GitHub repository:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_REGION
-
Push changes to the main branch to trigger a deployment.
{
"features": [
[feature1_1, feature1_2, ..., feature1_n, feature1_n+1, ..., feature1_2n],
[feature2_1, feature2_2, ..., feature2_n, feature2_n+1, ..., feature2_2n],
...
],
"returns": [
[return1_1, return1_2, ..., return1_n],
[return2_1, return2_2, ..., return2_n],
...
]
}
Where:
features
is a 2D array of feature values (each row has 2n values)returns
is a 2D array of return values (each row has n values)- n is the number of assets
{
"factors": [[factor_values]],
"covariance": [[covariance_matrix]]
}
Where:
factors
is a 2D array of risk factor valuescovariance
is a 2D array representing the covariance matrix
This project implements a Lambda function for the Deep Risk Model, which analyzes financial data to generate risk factors and covariance matrices.
The Deep Risk Model Lambda function is built with Rust and deployed to AWS Lambda using the Serverless Application Model (SAM). It exposes an API endpoint through API Gateway that accepts POST requests with financial data and returns risk analysis results.
The project uses GitHub Actions for CI/CD, with automatic deployments to different environments based on the branch:
develop
branch → Dev environmentrelease/*
branches → Staging environmentmain
branch → Production environment
You can also manually trigger a deployment to any environment using the GitHub Actions workflow dispatch.
To set up the CI/CD pipeline, you need:
- An AWS account with appropriate permissions
- GitHub repository secrets:
AWS_ACCESS_KEY_ID
: Your AWS access keyAWS_SECRET_ACCESS_KEY
: Your AWS secret keyAWS_REGION
: The AWS region to deploy to (e.g.,us-east-1
)
-
Build the project:
make build
-
Run tests:
make test
-
Test the model with sample data:
make local-invoke
-
Build with SAM:
make sam-build
-
Invoke the Lambda function locally:
make sam-local-invoke
-
Start a local API endpoint:
make sam-local-api
You can deploy to different environments manually using SAM:
# Deploy to dev
sam deploy --config-env dev
# Deploy to staging
sam deploy --config-env staging
# Deploy to production
sam deploy --config-env prod
Send a POST request to the API endpoint with the following JSON structure:
{
"features": [
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0],
[7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
],
"returns": [
[0.01, 0.02, 0.03],
[0.04, 0.05, 0.06]
]
}
The API returns a JSON response with the following structure:
{
"factors": [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]],
"covariance": [[1.0, 0.5], [0.5, 1.0]]
}
The Lambda function is configured differently for each environment:
- Dev: 1024 MB memory, 30-second timeout, DEBUG log level
- Staging: 1536 MB memory, 60-second timeout, INFO log level
- Production: 2048 MB memory, 90-second timeout, INFO log level
- CloudWatch Logs: All Lambda function logs are sent to CloudWatch Logs
- CloudWatch Metrics: Lambda metrics are available in CloudWatch
- GitHub Actions: Deployment logs are available in the GitHub Actions tab