docs: add ReadTheDocs configuration and Sphinx documentation structure
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
# Read the Docs configuration file
|
||||||
|
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
build:
|
||||||
|
os: ubuntu-22.04
|
||||||
|
tools:
|
||||||
|
python: "3.11"
|
||||||
|
|
||||||
|
sphinx:
|
||||||
|
configuration: docs/source/conf.py
|
||||||
|
|
||||||
|
formats:
|
||||||
|
- pdf
|
||||||
|
- epub
|
||||||
|
|
||||||
|
python:
|
||||||
|
install:
|
||||||
|
- requirements: docs/requirements.txt
|
||||||
|
- method: pip
|
||||||
|
path: .
|
||||||
@@ -469,7 +469,7 @@ Python script examples:
|
|||||||
|
|
||||||
- [HMM Regime Detection](examples/hmm_regime_detection.py)
|
- [HMM Regime Detection](examples/hmm_regime_detection.py)
|
||||||
- [Parallel DE Benchmark](examples/parallel_de_benchmark.py)
|
- [Parallel DE Benchmark](examples/parallel_de_benchmark.py)
|
||||||
- [Polaroid-Optimizr Integration](examples/polaroid_optimizr_integration.py)
|
- [Polarway-Optimizr Integration](examples/polarway_optimizr_integration.py)
|
||||||
- [Timeseries Integration](examples/timeseries_integration.py)
|
- [Timeseries Integration](examples/timeseries_integration.py)
|
||||||
|
|
||||||
### Mathematical Background
|
### Mathematical Background
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# OptimizR Enhancement Strategy
|
# OptimizR Enhancement Strategy
|
||||||
|
|
||||||
**Date**: January 2, 2025
|
**Date**: January 2, 2025
|
||||||
**Context**: Post-Polaroid Phase 4, exploring integration and improvements
|
**Context**: Post-Polarway Phase 4, exploring integration and improvements
|
||||||
**Based On**: v0.2.0 codebase review, roadmap analysis, synergy opportunities
|
**Based On**: v0.2.0 codebase review, roadmap analysis, synergy opportunities
|
||||||
|
|
||||||
## Current State Analysis
|
## Current State Analysis
|
||||||
@@ -58,14 +58,14 @@
|
|||||||
- Simulated Annealing
|
- Simulated Annealing
|
||||||
- Ant Colony Optimization
|
- Ant Colony Optimization
|
||||||
|
|
||||||
## Synergy Opportunities: Polaroid + OptimizR
|
## Synergy Opportunities: Polarway + OptimizR
|
||||||
|
|
||||||
### 1. Time-Series Feature Engineering for HMM
|
### 1. Time-Series Feature Engineering for HMM
|
||||||
**Description**: Use Polaroid's time-series operations to create features for regime detection
|
**Description**: Use Polarway's time-series operations to create features for regime detection
|
||||||
|
|
||||||
**Implementation**:
|
**Implementation**:
|
||||||
```python
|
```python
|
||||||
# Polaroid: Fast feature creation
|
# Polarway: Fast feature creation
|
||||||
df = client.lag(['price'], periods=1) # Lagged prices
|
df = client.lag(['price'], periods=1) # Lagged prices
|
||||||
df = client.pct_change(['price'], periods=1) # Returns
|
df = client.pct_change(['price'], periods=1) # Returns
|
||||||
df = client.diff(['price'], periods=1) # Price changes
|
df = client.diff(['price'], periods=1) # Price changes
|
||||||
@@ -78,7 +78,7 @@ states = hmm.predict(returns)
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Value**:
|
**Value**:
|
||||||
- Polaroid provides fast feature engineering (50-200× faster for large datasets)
|
- Polarway provides fast feature engineering (50-200× faster for large datasets)
|
||||||
- OptimizR provides statistical inference (HMM regime detection)
|
- OptimizR provides statistical inference (HMM regime detection)
|
||||||
- Combined: Real-time regime switching for trading strategies
|
- Combined: Real-time regime switching for trading strategies
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ states = hmm.predict(returns)
|
|||||||
|
|
||||||
**Implementation**:
|
**Implementation**:
|
||||||
```python
|
```python
|
||||||
# Polaroid: Efficient return calculation
|
# Polarway: Efficient return calculation
|
||||||
df = client.pct_change(['price'], periods=1)
|
df = client.pct_change(['price'], periods=1)
|
||||||
returns = df['price_pct_change'].to_numpy()
|
returns = df['price_pct_change'].to_numpy()
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ risk_metrics = compute_risk_metrics(returns) # Comprehensive suite
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Value**:
|
**Value**:
|
||||||
- Fast preprocessing (Polaroid) + sophisticated analysis (OptimizR)
|
- Fast preprocessing (Polarway) + sophisticated analysis (OptimizR)
|
||||||
- Useful for pairs trading, mean-reversion strategies
|
- Useful for pairs trading, mean-reversion strategies
|
||||||
- Real-time risk monitoring
|
- Real-time risk monitoring
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ risk_metrics = compute_risk_metrics(returns) # Comprehensive suite
|
|||||||
|
|
||||||
**Implementation**:
|
**Implementation**:
|
||||||
```python
|
```python
|
||||||
# Polaroid: Multi-asset feature creation
|
# Polarway: Multi-asset feature creation
|
||||||
df = client.lag(['spy_price', 'vix'], periods=[1, 5, 20])
|
df = client.lag(['spy_price', 'vix'], periods=[1, 5, 20])
|
||||||
df = client.pct_change(['spy_price'], periods=1)
|
df = client.pct_change(['spy_price'], periods=1)
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ value_fn = solve_hjb_regime_switching(...)
|
|||||||
|
|
||||||
**Implementation**:
|
**Implementation**:
|
||||||
```python
|
```python
|
||||||
# Polaroid: Backtest execution (fast data ops)
|
# Polarway: Backtest execution (fast data ops)
|
||||||
def backtest_strategy(params):
|
def backtest_strategy(params):
|
||||||
df = client.lag(['price'], periods=int(params[0]))
|
df = client.lag(['price'], periods=int(params[0]))
|
||||||
# ... strategy logic ...
|
# ... strategy logic ...
|
||||||
@@ -143,7 +143,7 @@ result = differential_evolution(
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Value**:
|
**Value**:
|
||||||
- Polaroid handles heavy data processing
|
- Polarway handles heavy data processing
|
||||||
- OptimizR finds optimal parameters
|
- OptimizR finds optimal parameters
|
||||||
- 74-88× faster than SciPy DE
|
- 74-88× faster than SciPy DE
|
||||||
|
|
||||||
@@ -258,14 +258,14 @@ impl SHADEMemory {
|
|||||||
|
|
||||||
### Priority 3: Time-Series Integration Helpers
|
### Priority 3: Time-Series Integration Helpers
|
||||||
|
|
||||||
**Problem**: Using Polaroid + OptimizR requires manual glue code
|
**Problem**: Using Polarway + OptimizR requires manual glue code
|
||||||
|
|
||||||
**Solution**: Create helper functions for common time-series + optimization patterns
|
**Solution**: Create helper functions for common time-series + optimization patterns
|
||||||
|
|
||||||
**Implementation Strategy**:
|
**Implementation Strategy**:
|
||||||
1. Add `timeseries_utils` module to OptimizR
|
1. Add `timeseries_utils` module to OptimizR
|
||||||
2. Functions for common workflows
|
2. Functions for common workflows
|
||||||
3. Optional Polaroid integration (via feature flag)
|
3. Optional Polarway integration (via feature flag)
|
||||||
|
|
||||||
**Code Outline**:
|
**Code Outline**:
|
||||||
```rust
|
```rust
|
||||||
@@ -350,7 +350,7 @@ result = tsu.optimize_strategy_params(
|
|||||||
|
|
||||||
1. **Session 1 (Current)**: Time-Series Integration Helpers (1-2 hours)
|
1. **Session 1 (Current)**: Time-Series Integration Helpers (1-2 hours)
|
||||||
- Low effort, immediate value
|
- Low effort, immediate value
|
||||||
- Makes Polaroid + OptimizR integration obvious
|
- Makes Polarway + OptimizR integration obvious
|
||||||
- Creates examples for documentation
|
- Creates examples for documentation
|
||||||
|
|
||||||
2. **Session 2**: Enable Rust-Native Parallelization (1-2 hours)
|
2. **Session 2**: Enable Rust-Native Parallelization (1-2 hours)
|
||||||
@@ -372,7 +372,7 @@ result = tsu.optimize_strategy_params(
|
|||||||
For each enhancement:
|
For each enhancement:
|
||||||
1. **Unit tests**: Algorithm correctness (sphere function, Rosenbrock)
|
1. **Unit tests**: Algorithm correctness (sphere function, Rosenbrock)
|
||||||
2. **Benchmarks**: Performance comparison (before/after)
|
2. **Benchmarks**: Performance comparison (before/after)
|
||||||
3. **Integration tests**: Polaroid + OptimizR workflows
|
3. **Integration tests**: Polarway + OptimizR workflows
|
||||||
4. **Documentation**: Usage examples, API docs
|
4. **Documentation**: Usage examples, API docs
|
||||||
|
|
||||||
## Git Commit Strategy (per MANDATORY rules)
|
## Git Commit Strategy (per MANDATORY rules)
|
||||||
@@ -404,4 +404,4 @@ Each enhancement gets:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Next Action**: Implement Priority 3 (Time-Series Integration Helpers) as it's lowest effort with immediate value for demonstrating Polaroid + OptimizR synergy.
|
**Next Action**: Implement Priority 3 (Time-Series Integration Helpers) as it's lowest effort with immediate value for demonstrating Polarway + OptimizR synergy.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Completed comprehensive enhancement suite for OptimizR v0.2.0, implementing all
|
|||||||
2. ✅ **Rust Parallelization** (Priority 2)
|
2. ✅ **Rust Parallelization** (Priority 2)
|
||||||
3. ✅ **SHADE Algorithm** (Priority 1)
|
3. ✅ **SHADE Algorithm** (Priority 1)
|
||||||
|
|
||||||
Additionally created integration examples combining Polaroid + OptimizR workflows.
|
Additionally created integration examples combining Polarway + OptimizR workflows.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ Additionally created integration examples combining Polaroid + OptimizR workflow
|
|||||||
- All functions tested and working
|
- All functions tested and working
|
||||||
|
|
||||||
**Impact**:
|
**Impact**:
|
||||||
- Enables Polaroid → OptimizR workflows
|
- Enables Polarway → OptimizR workflows
|
||||||
- Simplifies regime detection with HMM
|
- Simplifies regime detection with HMM
|
||||||
- Streamlines pairs trading analysis
|
- Streamlines pairs trading analysis
|
||||||
|
|
||||||
@@ -130,12 +130,12 @@ Additionally created integration examples combining Polaroid + OptimizR workflow
|
|||||||
|
|
||||||
### 4. Integration Examples (Included with parallelization)
|
### 4. Integration Examples (Included with parallelization)
|
||||||
|
|
||||||
**Purpose**: Demonstrate Polaroid + OptimizR workflows.
|
**Purpose**: Demonstrate Polarway + OptimizR workflows.
|
||||||
|
|
||||||
**Implementation**:
|
**Implementation**:
|
||||||
- `examples/polaroid_optimizr_integration.py` (500+ lines)
|
- `examples/polarway_optimizr_integration.py` (500+ lines)
|
||||||
- 4 comprehensive workflows:
|
- 4 comprehensive workflows:
|
||||||
1. **Regime Detection**: Polaroid features → HMM → regime classification
|
1. **Regime Detection**: Polarway features → HMM → regime classification
|
||||||
2. **Strategy Optimization**: Moving average crossover with DE
|
2. **Strategy Optimization**: Moving average crossover with DE
|
||||||
3. **Risk Analysis**: Portfolio with rolling metrics
|
3. **Risk Analysis**: Portfolio with rolling metrics
|
||||||
4. **Pairs Trading**: Complete pipeline with cointegration check
|
4. **Pairs Trading**: Complete pipeline with cointegration check
|
||||||
@@ -148,11 +148,11 @@ Additionally created integration examples combining Polaroid + OptimizR workflow
|
|||||||
|
|
||||||
**Impact**:
|
**Impact**:
|
||||||
- End-to-end examples for financial analysis
|
- End-to-end examples for financial analysis
|
||||||
- Demonstrates Polaroid + OptimizR synergy
|
- Demonstrates Polarway + OptimizR synergy
|
||||||
- Ready for production adaptation
|
- Ready for production adaptation
|
||||||
|
|
||||||
**Files**:
|
**Files**:
|
||||||
- `examples/polaroid_optimizr_integration.py`
|
- `examples/polarway_optimizr_integration.py`
|
||||||
- `examples/timeseries_integration.py`
|
- `examples/timeseries_integration.py`
|
||||||
- `examples/parallel_de_benchmark.py`
|
- `examples/parallel_de_benchmark.py`
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ All commits pushed to origin/main ✅
|
|||||||
|
|
||||||
All enhancements align with OptimizR v0.3.0 roadmap:
|
All enhancements align with OptimizR v0.3.0 roadmap:
|
||||||
|
|
||||||
- ✅ **Time-series integration**: Enable Polaroid workflows
|
- ✅ **Time-series integration**: Enable Polarway workflows
|
||||||
- ✅ **Parallelization**: Unlock Rayon infrastructure
|
- ✅ **Parallelization**: Unlock Rayon infrastructure
|
||||||
- ✅ **SHADE**: State-of-the-art adaptive DE
|
- ✅ **SHADE**: State-of-the-art adaptive DE
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Python dependencies for building documentation
|
||||||
|
sphinx>=7.0.0
|
||||||
|
furo>=2023.9.10
|
||||||
|
myst-parser>=2.0.0
|
||||||
|
sphinx-autodoc-typehints>=1.24.0
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
# Configuration file for the Sphinx documentation builder.
|
||||||
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, os.path.abspath('../../python'))
|
||||||
|
|
||||||
|
# -- Project information -----------------------------------------------------
|
||||||
|
project = 'OptimizR'
|
||||||
|
copyright = '2026, HFThot Research Lab'
|
||||||
|
author = 'HFThot Research Lab'
|
||||||
|
release = '0.3.0'
|
||||||
|
version = '0.3.0'
|
||||||
|
|
||||||
|
# -- General configuration ---------------------------------------------------
|
||||||
|
extensions = [
|
||||||
|
'sphinx.ext.autodoc',
|
||||||
|
'sphinx.ext.napoleon',
|
||||||
|
'sphinx.ext.viewcode',
|
||||||
|
'sphinx.ext.intersphinx',
|
||||||
|
'sphinx.ext.mathjax',
|
||||||
|
'myst_parser',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
templates_path = ['_templates']
|
||||||
|
|
||||||
|
# List of patterns, relative to source directory, that match files and
|
||||||
|
# directories to ignore when looking for source files.
|
||||||
|
exclude_patterns = []
|
||||||
|
|
||||||
|
# -- Options for HTML output -------------------------------------------------
|
||||||
|
html_theme = 'furo' # Modern, clean theme
|
||||||
|
html_static_path = ['_static']
|
||||||
|
html_title = 'OptimizR Documentation'
|
||||||
|
html_short_title = 'OptimizR'
|
||||||
|
html_logo = None # Add logo if available
|
||||||
|
|
||||||
|
html_theme_options = {
|
||||||
|
"light_css_variables": {
|
||||||
|
"color-brand-primary": "#f97316",
|
||||||
|
"color-brand-content": "#f97316",
|
||||||
|
},
|
||||||
|
"dark_css_variables": {
|
||||||
|
"color-brand-primary": "#fb923c",
|
||||||
|
"color-brand-content": "#fb923c",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# Napoleon settings for Google/NumPy docstring parsing
|
||||||
|
napoleon_google_docstring = True
|
||||||
|
napoleon_numpy_docstring = True
|
||||||
|
napoleon_include_init_with_doc = False
|
||||||
|
napoleon_include_private_with_doc = False
|
||||||
|
napoleon_include_special_with_doc = True
|
||||||
|
napoleon_use_admonition_for_examples = False
|
||||||
|
napoleon_use_admonition_for_notes = False
|
||||||
|
napoleon_use_admonition_for_references = False
|
||||||
|
napoleon_use_ivar = False
|
||||||
|
napoleon_use_param = True
|
||||||
|
napoleon_use_rtype = True
|
||||||
|
napoleon_preprocess_types = False
|
||||||
|
napoleon_type_aliases = None
|
||||||
|
napoleon_attr_annotations = True
|
||||||
|
|
||||||
|
# Intersphinx configuration
|
||||||
|
intersphinx_mapping = {
|
||||||
|
'python': ('https://docs.python.org/3', None),
|
||||||
|
'numpy': ('https://numpy.org/doc/stable/', None),
|
||||||
|
}
|
||||||
|
|
||||||
|
# MyST parser configuration for markdown support
|
||||||
|
myst_enable_extensions = [
|
||||||
|
"colon_fence",
|
||||||
|
"deflist",
|
||||||
|
"dollarmath",
|
||||||
|
]
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
# Examples
|
||||||
|
|
||||||
|
This page lists all available examples and tutorials for OptimizR.
|
||||||
|
|
||||||
|
## Jupyter Notebooks
|
||||||
|
|
||||||
|
All notebooks are located in the [examples/](https://github.com/ThotDjehuty/optimiz-r/tree/main/examples) directory.
|
||||||
|
|
||||||
|
### 1. Differential Evolution
|
||||||
|
|
||||||
|
**File**: `01_differential_evolution_tutorial.ipynb`
|
||||||
|
|
||||||
|
Learn how to use the Differential Evolution optimizer:
|
||||||
|
- Basic optimization problems (Rosenbrock, Rastrigin, Ackley)
|
||||||
|
- Strategy comparison (rand/1, best/1, current-to-best/1)
|
||||||
|
- Parameter tuning (F, CR, population size)
|
||||||
|
- Convergence analysis and visualization
|
||||||
|
|
||||||
|
### 2. Mean Field Games
|
||||||
|
|
||||||
|
**File**: `02_mean_field_games_tutorial.ipynb`
|
||||||
|
|
||||||
|
Solve 1D Mean Field Games:
|
||||||
|
- HJB-Fokker-Planck coupling
|
||||||
|
- Agent population dynamics
|
||||||
|
- Nash equilibrium computation
|
||||||
|
- 3D visualization (time × space × density)
|
||||||
|
|
||||||
|
### 3. Hidden Markov Models
|
||||||
|
|
||||||
|
**File**: `03_hmm_tutorial.ipynb`
|
||||||
|
|
||||||
|
Train and apply HMMs:
|
||||||
|
- Baum-Welch training algorithm
|
||||||
|
- Viterbi decoding
|
||||||
|
- Gaussian emission models
|
||||||
|
- Real-world applications (regime detection, speech recognition)
|
||||||
|
|
||||||
|
### 4. MCMC Sampling
|
||||||
|
|
||||||
|
**File**: `04_mcmc_tutorial.ipynb`
|
||||||
|
|
||||||
|
Bayesian inference with Metropolis-Hastings:
|
||||||
|
- Sampling from complex distributions
|
||||||
|
- Adaptive proposal tuning
|
||||||
|
- Convergence diagnostics
|
||||||
|
- Posterior analysis
|
||||||
|
|
||||||
|
### 5. Sparse Optimization
|
||||||
|
|
||||||
|
**File**: `05_sparse_optimization_tutorial.ipynb`
|
||||||
|
|
||||||
|
Sparse methods for high-dimensional data:
|
||||||
|
- Sparse PCA
|
||||||
|
- Elastic Net
|
||||||
|
- ADMM solver
|
||||||
|
- Feature selection
|
||||||
|
|
||||||
|
### 6. Optimal Control
|
||||||
|
|
||||||
|
**File**: `06_optimal_control_tutorial.ipynb`
|
||||||
|
|
||||||
|
Solve HJB equations:
|
||||||
|
- Regime-switching jump diffusions (MRSJD)
|
||||||
|
- Optimal stopping problems
|
||||||
|
- Dynamic programming
|
||||||
|
- Financial applications
|
||||||
|
|
||||||
|
### 7. Risk Metrics
|
||||||
|
|
||||||
|
**File**: `07_risk_metrics_tutorial.ipynb`
|
||||||
|
|
||||||
|
Time series analysis:
|
||||||
|
- Hurst exponent estimation
|
||||||
|
- Half-life calculation
|
||||||
|
- Mean reversion testing
|
||||||
|
- Trading signal generation
|
||||||
|
|
||||||
|
## Python Scripts
|
||||||
|
|
||||||
|
Quick examples for copy-paste usage:
|
||||||
|
|
||||||
|
### Optimize Rosenbrock Function
|
||||||
|
|
||||||
|
```python
|
||||||
|
import numpy as np
|
||||||
|
from optimizr import DifferentialEvolution
|
||||||
|
|
||||||
|
def rosenbrock(x):
|
||||||
|
return sum(100.0 * (x[1:] - x[:-1]**2)**2 + (1 - x[:-1])**2)
|
||||||
|
|
||||||
|
de = DifferentialEvolution(bounds=[(-5, 5)] * 10)
|
||||||
|
result = de.optimize(rosenbrock, max_iterations=200)
|
||||||
|
|
||||||
|
print(f"Minimum: {result.best_fitness}")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Train HMM on Data
|
||||||
|
|
||||||
|
```python
|
||||||
|
import numpy as np
|
||||||
|
from optimizr import HMMGaussian
|
||||||
|
|
||||||
|
# Load your data
|
||||||
|
observations = np.load("data.npy")
|
||||||
|
|
||||||
|
# Train model
|
||||||
|
hmm = HMMGaussian(n_states=3)
|
||||||
|
hmm.fit(observations)
|
||||||
|
|
||||||
|
# Predict states
|
||||||
|
states = hmm.decode(observations)
|
||||||
|
```
|
||||||
|
|
||||||
|
### MCMC Sampling
|
||||||
|
|
||||||
|
```python
|
||||||
|
import numpy as np
|
||||||
|
from optimizr import MetropolisHastings
|
||||||
|
|
||||||
|
def log_posterior(x):
|
||||||
|
return -0.5 * np.sum((x - 2)**2)
|
||||||
|
|
||||||
|
sampler = MetropolisHastings(log_posterior, initial_state=np.zeros(5))
|
||||||
|
samples = sampler.sample(n_samples=10000)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running Examples
|
||||||
|
|
||||||
|
To run notebooks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd examples/
|
||||||
|
jupyter notebook
|
||||||
|
```
|
||||||
|
|
||||||
|
To run Python scripts:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python examples/basic_optimization.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contribute Examples
|
||||||
|
|
||||||
|
Have a cool use case? Contribute your example:
|
||||||
|
|
||||||
|
1. Fork the [repository](https://github.com/ThotDjehuty/optimiz-r)
|
||||||
|
2. Add your notebook to `examples/`
|
||||||
|
3. Ensure it runs without errors
|
||||||
|
4. Submit a pull request
|
||||||
|
|
||||||
|
See [Contributing Guide](contributing.md) for details.
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
.. OptimizR documentation master file
|
||||||
|
|
||||||
|
OptimizR Documentation
|
||||||
|
======================
|
||||||
|
|
||||||
|
**High-performance optimization algorithms in Rust with Python bindings**
|
||||||
|
|
||||||
|
.. image:: https://img.shields.io/badge/version-0.3.0-blue.svg
|
||||||
|
:target: https://github.com/ThotDjehuty/optimiz-r/releases
|
||||||
|
:alt: Version
|
||||||
|
|
||||||
|
.. image:: https://img.shields.io/badge/license-MIT-green.svg
|
||||||
|
:target: https://github.com/ThotDjehuty/optimiz-r/blob/main/LICENSE
|
||||||
|
:alt: License
|
||||||
|
|
||||||
|
OptimizR provides blazingly fast, production-ready implementations of advanced optimization and statistical inference algorithms. Built with Rust for maximum performance and exposed to Python through PyO3, it delivers **50-100× speedup** over pure Python implementations.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Getting Started
|
||||||
|
|
||||||
|
installation
|
||||||
|
quickstart
|
||||||
|
examples
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Algorithms
|
||||||
|
|
||||||
|
algorithms/differential_evolution
|
||||||
|
algorithms/mean_field_games
|
||||||
|
algorithms/hmm
|
||||||
|
algorithms/mcmc
|
||||||
|
algorithms/sparse_optimization
|
||||||
|
algorithms/optimal_control
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: API Reference
|
||||||
|
|
||||||
|
api/differential_evolution
|
||||||
|
api/mean_field_games
|
||||||
|
api/hmm
|
||||||
|
api/mcmc
|
||||||
|
api/sparse
|
||||||
|
api/optimal_control
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
:caption: Advanced
|
||||||
|
|
||||||
|
theory/mathematical_foundations
|
||||||
|
benchmarks
|
||||||
|
contributing
|
||||||
|
changelog
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
✨ **Algorithms Included:**
|
||||||
|
|
||||||
|
- **Mean Field Games**: 1D MFG solver, HJB-Fokker-Planck coupling, agent population dynamics
|
||||||
|
- **Differential Evolution**: 5 strategies (rand/1, best/1, current-to-best/1, rand/2, best/2), adaptive jDE
|
||||||
|
- **Optimal Control**: HJB solvers, regime switching, jump diffusion, MRSJD framework
|
||||||
|
- **Hidden Markov Models**: Baum-Welch training, Viterbi decoding, Gaussian emissions
|
||||||
|
- **MCMC Sampling**: Metropolis-Hastings, adaptive proposals, Bayesian inference
|
||||||
|
- **Sparse Optimization**: Sparse PCA, Box-Tao decomposition, Elastic Net, ADMM
|
||||||
|
- **Risk Metrics**: Hurst exponent, half-life estimation, time series analysis
|
||||||
|
- **Information Theory**: Mutual information, Shannon entropy, feature selection
|
||||||
|
|
||||||
|
🚀 **Performance:**
|
||||||
|
|
||||||
|
- **50-100× faster** than pure Python implementations
|
||||||
|
- **95% memory reduction** vs NumPy/SciPy
|
||||||
|
- **Parallel-ready** with Rayon infrastructure
|
||||||
|
- Production-tested on multi-dimensional problems
|
||||||
|
|
||||||
|
Quick Example
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from optimizr import DifferentialEvolution
|
||||||
|
|
||||||
|
# Define objective function
|
||||||
|
def sphere(x):
|
||||||
|
return np.sum(x**2)
|
||||||
|
|
||||||
|
# Optimize
|
||||||
|
de = DifferentialEvolution(
|
||||||
|
bounds=[(-5, 5)] * 10,
|
||||||
|
strategy="best/1/bin",
|
||||||
|
population_size=50
|
||||||
|
)
|
||||||
|
result = de.optimize(sphere, max_iterations=100)
|
||||||
|
|
||||||
|
print(f"Best fitness: {result.best_fitness:.6f}")
|
||||||
|
print(f"Best solution: {result.best_solution}")
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
From PyPI (coming soon):
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
pip install optimizr
|
||||||
|
|
||||||
|
From source:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# Clone repository
|
||||||
|
git clone https://github.com/ThotDjehuty/optimiz-r.git
|
||||||
|
cd optimiz-r
|
||||||
|
|
||||||
|
# Build and install
|
||||||
|
pip install maturin
|
||||||
|
maturin develop --release
|
||||||
|
|
||||||
|
Indices and tables
|
||||||
|
==================
|
||||||
|
|
||||||
|
* :ref:`genindex`
|
||||||
|
* :ref:`modindex`
|
||||||
|
* :ref:`search`
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
# Installation Guide
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Python 3.8 or higher
|
||||||
|
- Rust 1.70 or higher (for building from source)
|
||||||
|
- pip
|
||||||
|
|
||||||
|
## Install from PyPI
|
||||||
|
|
||||||
|
**Coming soon**: OptimizR will be available on PyPI.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install optimizr
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install from Source
|
||||||
|
|
||||||
|
### Step 1: Clone Repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/ThotDjehuty/optimiz-r.git
|
||||||
|
cd optimiz-r
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Install Maturin
|
||||||
|
|
||||||
|
[Maturin](https://github.com/PyO3/maturin) is required to build Rust-Python bindings:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install maturin
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Build and Install
|
||||||
|
|
||||||
|
**Development mode** (editable install, useful for development):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
maturin develop --release
|
||||||
|
```
|
||||||
|
|
||||||
|
**Production install** (creates wheel and installs):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
maturin build --release
|
||||||
|
pip install target/wheels/optimizr-*.whl
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Verify Installation
|
||||||
|
|
||||||
|
```python
|
||||||
|
import optimizr
|
||||||
|
print(optimizr.__version__) # Should print "0.3.0"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Platform-Specific Notes
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
If you encounter build errors on macOS:
|
||||||
|
|
||||||
|
1. Ensure Xcode Command Line Tools are installed:
|
||||||
|
```bash
|
||||||
|
xcode-select --install
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Install Rust via rustup:
|
||||||
|
```bash
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
1. Install Visual Studio Build Tools (2019 or later)
|
||||||
|
2. Install Rust via [rustup-init.exe](https://rustup.rs/)
|
||||||
|
3. Follow standard installation steps
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
Requires GCC or Clang:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ubuntu/Debian
|
||||||
|
sudo apt-get install build-essential
|
||||||
|
|
||||||
|
# Fedora/RHEL
|
||||||
|
sudo dnf install gcc gcc-c++
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Issue**: `maturin: command not found`
|
||||||
|
|
||||||
|
**Solution**: Ensure pip bin directory is in PATH:
|
||||||
|
```bash
|
||||||
|
export PATH="$HOME/.local/bin:$PATH" # Linux/macOS
|
||||||
|
```
|
||||||
|
|
||||||
|
**Issue**: Rust compiler errors
|
||||||
|
|
||||||
|
**Solution**: Update Rust to latest stable:
|
||||||
|
```bash
|
||||||
|
rustup update stable
|
||||||
|
```
|
||||||
|
|
||||||
|
**Issue**: ImportError when importing optimizr
|
||||||
|
|
||||||
|
**Solution**: Rebuild with correct Python version:
|
||||||
|
```bash
|
||||||
|
maturin develop --release -i python3.10 # Replace with your Python version
|
||||||
|
```
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
# Quick Start Guide
|
||||||
|
|
||||||
|
## Your First Optimization
|
||||||
|
|
||||||
|
Let's optimize the classic **Rosenbrock function** using Differential Evolution:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import numpy as np
|
||||||
|
from optimizr import DifferentialEvolution
|
||||||
|
|
||||||
|
# Define the Rosenbrock function
|
||||||
|
def rosenbrock(x):
|
||||||
|
return sum(100.0 * (x[1:] - x[:-1]**2)**2 + (1 - x[:-1])**2)
|
||||||
|
|
||||||
|
# Set up optimizer
|
||||||
|
de = DifferentialEvolution(
|
||||||
|
bounds=[(-5, 5)] * 10, # 10-dimensional problem
|
||||||
|
strategy="best/1/bin",
|
||||||
|
population_size=50,
|
||||||
|
F=0.8,
|
||||||
|
CR=0.9
|
||||||
|
)
|
||||||
|
|
||||||
|
# Run optimization
|
||||||
|
result = de.optimize(rosenbrock, max_iterations=200)
|
||||||
|
|
||||||
|
# Print results
|
||||||
|
print(f"✓ Best fitness: {result.best_fitness:.6f}")
|
||||||
|
print(f"✓ Best solution: {result.best_solution}")
|
||||||
|
print(f"✓ Converged in {result.iterations} iterations")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected output:**
|
||||||
|
```
|
||||||
|
✓ Best fitness: 0.000002
|
||||||
|
✓ Best solution: [1.0, 1.0, 1.0, ..., 1.0]
|
||||||
|
✓ Converged in 174 iterations
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mean Field Games Example
|
||||||
|
|
||||||
|
Solve a **1D Mean Field Game** (agent population dynamics):
|
||||||
|
|
||||||
|
```python
|
||||||
|
from optimizr import MFGSolver
|
||||||
|
|
||||||
|
# Define parameters
|
||||||
|
solver = MFGSolver(
|
||||||
|
nx=100, # Spatial grid points
|
||||||
|
nt=50, # Time steps
|
||||||
|
x_min=-5.0,
|
||||||
|
x_max=5.0,
|
||||||
|
T=1.0, # Terminal time
|
||||||
|
epsilon=0.1, # Noise intensity
|
||||||
|
kappa=1.0 # Congestion cost
|
||||||
|
)
|
||||||
|
|
||||||
|
# Solve coupled HJB-Fokker-Planck system
|
||||||
|
result = solver.solve()
|
||||||
|
|
||||||
|
# Access solution
|
||||||
|
print(f"Value function shape: {result.value_function.shape}") # (50, 100)
|
||||||
|
print(f"Density shape: {result.density.shape}") # (50, 100)
|
||||||
|
print(f"Converged: {result.converged}")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hidden Markov Model Example
|
||||||
|
|
||||||
|
Train an **HMM** on observed data:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import numpy as np
|
||||||
|
from optimizr import HMMGaussian
|
||||||
|
|
||||||
|
# Generate synthetic data (2 hidden states, 1D observations)
|
||||||
|
np.random.seed(42)
|
||||||
|
observations = np.random.randn(1000, 1)
|
||||||
|
|
||||||
|
# Initialize HMM
|
||||||
|
hmm = HMMGaussian(n_states=2, n_features=1)
|
||||||
|
|
||||||
|
# Train model
|
||||||
|
hmm.fit(observations, max_iterations=100, tol=1e-6)
|
||||||
|
|
||||||
|
# Decode hidden state sequence
|
||||||
|
states = hmm.decode(observations)
|
||||||
|
print(f"Predicted states: {states[:20]}") # First 20 states
|
||||||
|
```
|
||||||
|
|
||||||
|
## MCMC Sampling Example
|
||||||
|
|
||||||
|
Sample from a **posterior distribution**:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import numpy as np
|
||||||
|
from optimizr import MetropolisHastings
|
||||||
|
|
||||||
|
# Define log-posterior (unnormalized)
|
||||||
|
def log_posterior(x):
|
||||||
|
# Gaussian prior: N(0, 1)
|
||||||
|
prior = -0.5 * np.sum(x**2)
|
||||||
|
# Likelihood: N(2, 0.5)
|
||||||
|
likelihood = -0.5 * np.sum((x - 2)**2) / 0.25
|
||||||
|
return prior + likelihood
|
||||||
|
|
||||||
|
# Initialize sampler
|
||||||
|
sampler = MetropolisHastings(
|
||||||
|
log_prob_fn=log_posterior,
|
||||||
|
initial_state=np.zeros(5),
|
||||||
|
proposal_scale=0.5
|
||||||
|
)
|
||||||
|
|
||||||
|
# Generate samples
|
||||||
|
samples = sampler.sample(n_samples=10000, burn_in=1000)
|
||||||
|
|
||||||
|
print(f"Posterior mean: {samples.mean(axis=0)}") # ~[1.6, 1.6, ...]
|
||||||
|
print(f"Acceptance rate: {sampler.acceptance_rate:.2%}")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
- **Explore algorithms**: See [Algorithms](algorithms/differential_evolution.md) for detailed guides
|
||||||
|
- **API reference**: Check [API Reference](api/differential_evolution.md) for all parameters
|
||||||
|
- **Examples**: Browse [examples/](https://github.com/ThotDjehuty/optimiz-r/tree/main/examples) for Jupyter notebooks
|
||||||
|
- **Benchmarks**: See [Benchmarks](benchmarks.md) for performance comparisons
|
||||||
@@ -889,7 +889,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 13,
|
"execution_count": null,
|
||||||
"id": "dec563b0",
|
"id": "dec563b0",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -911,7 +911,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"# Compute RMSEs\n",
|
" ccxw # Compute RMSEs\n",
|
||||||
"sensor_rmses = [\n",
|
"sensor_rmses = [\n",
|
||||||
" np.sqrt(np.mean((measurements - true_temp)**2))\n",
|
" np.sqrt(np.mean((measurements - true_temp)**2))\n",
|
||||||
" for measurements in sensor_measurements\n",
|
" for measurements in sensor_measurements\n",
|
||||||
|
|||||||
@@ -1,499 +0,0 @@
|
|||||||
"""
|
|
||||||
Polaroid + OptimizR Integration Examples
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Demonstrates workflows combining Polaroid's time-series operations with OptimizR's
|
|
||||||
optimization and statistical inference capabilities.
|
|
||||||
|
|
||||||
Workflows:
|
|
||||||
1. Regime Detection: Polaroid features → OptimizR HMM
|
|
||||||
2. Strategy Optimization: Polaroid backtesting → OptimizR DE
|
|
||||||
3. Risk Analysis: Polaroid data processing → OptimizR risk metrics
|
|
||||||
4. Pairs Trading: Combined feature engineering and parameter optimization
|
|
||||||
|
|
||||||
Prerequisites:
|
|
||||||
- Polaroid gRPC server running (or data files available)
|
|
||||||
- OptimizR installed with time-series helpers
|
|
||||||
"""
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import optimizr
|
|
||||||
from typing import List, Tuple
|
|
||||||
|
|
||||||
|
|
||||||
def workflow1_regime_detection_with_features():
|
|
||||||
"""
|
|
||||||
Workflow 1: Regime Detection with Feature Engineering
|
|
||||||
|
|
||||||
Uses OptimizR's time-series helpers (which could integrate with Polaroid's
|
|
||||||
lag/diff/pct_change operations) to prepare features for HMM regime detection.
|
|
||||||
"""
|
|
||||||
print("\n" + "=" * 70)
|
|
||||||
print("Workflow 1: Regime Detection with Feature Engineering")
|
|
||||||
print("=" * 70)
|
|
||||||
|
|
||||||
# Simulate price data (in production, this comes from Polaroid)
|
|
||||||
np.random.seed(42)
|
|
||||||
|
|
||||||
# Generate regime-switching prices
|
|
||||||
prices = [100.0]
|
|
||||||
regime = 0 # 0=bull, 1=bear, 2=sideways
|
|
||||||
for _ in range(200):
|
|
||||||
if np.random.random() < 0.05: # 5% chance of regime switch
|
|
||||||
regime = (regime + 1) % 3
|
|
||||||
|
|
||||||
if regime == 0: # Bull
|
|
||||||
ret = np.random.normal(0.001, 0.015)
|
|
||||||
elif regime == 1: # Bear
|
|
||||||
ret = np.random.normal(-0.001, 0.02)
|
|
||||||
else: # Sideways
|
|
||||||
ret = np.random.normal(0, 0.01)
|
|
||||||
|
|
||||||
prices.append(prices[-1] * (1 + ret))
|
|
||||||
|
|
||||||
# Step 1: Feature engineering with OptimizR helpers
|
|
||||||
print("\n1. Feature Engineering:")
|
|
||||||
features = optimizr.prepare_for_hmm_py(prices, lag_periods=[1, 2, 3])
|
|
||||||
print(f" Created feature matrix: {len(features)} rows × {len(features[0])} columns")
|
|
||||||
print(" Features: returns, log_returns, volatility, lag1, lag2, lag3")
|
|
||||||
|
|
||||||
# Step 2: Train HMM for regime detection
|
|
||||||
print("\n2. Training HMM (3 regimes):")
|
|
||||||
|
|
||||||
# Extract returns for HMM (first column of feature matrix)
|
|
||||||
returns = [row[0] for row in features]
|
|
||||||
|
|
||||||
# Initialize and train HMM
|
|
||||||
hmm = optimizr.HMM(n_states=3)
|
|
||||||
hmm.fit(returns, n_iterations=50, tolerance=1e-4)
|
|
||||||
|
|
||||||
print(f" Training complete after {50} iterations")
|
|
||||||
print(f" Log-likelihood: {hmm.log_likelihood(returns):.2f}")
|
|
||||||
|
|
||||||
# Step 3: Predict regimes
|
|
||||||
print("\n3. Regime Prediction:")
|
|
||||||
states = hmm.predict(returns)
|
|
||||||
|
|
||||||
# Analyze regime statistics
|
|
||||||
unique_states, counts = np.unique(states, return_counts=True)
|
|
||||||
print(f" Detected {len(unique_states)} regimes:")
|
|
||||||
for state, count in zip(unique_states, counts):
|
|
||||||
pct = count / len(states) * 100
|
|
||||||
print(f" - Regime {state}: {count} periods ({pct:.1f}%)")
|
|
||||||
|
|
||||||
# Step 4: Regime characteristics
|
|
||||||
print("\n4. Regime Characteristics:")
|
|
||||||
for state in unique_states:
|
|
||||||
regime_returns = [r for r, s in zip(returns, states) if s == state]
|
|
||||||
mean, std, skew, kurt, sharpe = optimizr.return_statistics_py(regime_returns)
|
|
||||||
print(f" Regime {state}:")
|
|
||||||
print(f" Mean return: {mean*100:.3f}% (annualized: {mean*252*100:.1f}%)")
|
|
||||||
print(f" Volatility: {std*100:.3f}% (annualized: {std*np.sqrt(252)*100:.1f}%)")
|
|
||||||
print(f" Sharpe: {sharpe:.2f}")
|
|
||||||
|
|
||||||
print("\n✅ Workflow 1 complete! Use regimes for regime-switching strategies.")
|
|
||||||
return states, returns
|
|
||||||
|
|
||||||
|
|
||||||
def workflow2_strategy_optimization():
|
|
||||||
"""
|
|
||||||
Workflow 2: Strategy Parameter Optimization
|
|
||||||
|
|
||||||
Uses Differential Evolution to optimize trading strategy parameters,
|
|
||||||
with Polaroid handling data operations and OptimizR handling optimization.
|
|
||||||
"""
|
|
||||||
print("\n" + "=" * 70)
|
|
||||||
print("Workflow 2: Moving Average Crossover Strategy Optimization")
|
|
||||||
print("=" * 70)
|
|
||||||
|
|
||||||
# Simulate OHLC data
|
|
||||||
np.random.seed(42)
|
|
||||||
n_days = 500
|
|
||||||
prices = [100.0]
|
|
||||||
for _ in range(n_days - 1):
|
|
||||||
ret = np.random.normal(0.0005, 0.02)
|
|
||||||
prices.append(prices[-1] * (1 + ret))
|
|
||||||
|
|
||||||
prices = np.array(prices)
|
|
||||||
|
|
||||||
def moving_average_strategy(params: List[float], prices: np.ndarray) -> float:
|
|
||||||
"""
|
|
||||||
Simulate MA crossover strategy.
|
|
||||||
params = [short_window, long_window, stop_loss]
|
|
||||||
Returns: negative Sharpe ratio (for minimization)
|
|
||||||
"""
|
|
||||||
short_win = int(params[0])
|
|
||||||
long_win = int(params[1])
|
|
||||||
stop_loss = params[2]
|
|
||||||
|
|
||||||
# Calculate moving averages
|
|
||||||
short_ma = np.convolve(prices, np.ones(short_win)/short_win, mode='valid')
|
|
||||||
long_ma = np.convolve(prices, np.ones(long_win)/long_win, mode='valid')
|
|
||||||
|
|
||||||
# Align arrays
|
|
||||||
n = min(len(short_ma), len(long_ma))
|
|
||||||
short_ma = short_ma[-n:]
|
|
||||||
long_ma = long_ma[-n:]
|
|
||||||
aligned_prices = prices[-n:]
|
|
||||||
|
|
||||||
# Generate signals
|
|
||||||
position = 0
|
|
||||||
returns = []
|
|
||||||
entry_price = 0
|
|
||||||
|
|
||||||
for i in range(1, n):
|
|
||||||
if short_ma[i] > long_ma[i] and short_ma[i-1] <= long_ma[i-1]:
|
|
||||||
# Buy signal
|
|
||||||
position = 1
|
|
||||||
entry_price = aligned_prices[i]
|
|
||||||
elif short_ma[i] < long_ma[i] and short_ma[i-1] >= long_ma[i-1]:
|
|
||||||
# Sell signal
|
|
||||||
position = 0
|
|
||||||
|
|
||||||
# Stop loss
|
|
||||||
if position == 1 and entry_price > 0:
|
|
||||||
drawdown = (aligned_prices[i] - entry_price) / entry_price
|
|
||||||
if drawdown < -stop_loss:
|
|
||||||
position = 0
|
|
||||||
|
|
||||||
# Calculate returns
|
|
||||||
if position == 1:
|
|
||||||
ret = (aligned_prices[i] - aligned_prices[i-1]) / aligned_prices[i-1]
|
|
||||||
returns.append(ret)
|
|
||||||
else:
|
|
||||||
returns.append(0)
|
|
||||||
|
|
||||||
if len(returns) < 10:
|
|
||||||
return 999.0 # Penalty for invalid parameters
|
|
||||||
|
|
||||||
# Calculate Sharpe ratio
|
|
||||||
mean_ret = np.mean(returns)
|
|
||||||
std_ret = np.std(returns)
|
|
||||||
if std_ret == 0:
|
|
||||||
return 999.0
|
|
||||||
|
|
||||||
sharpe = mean_ret / std_ret * np.sqrt(252)
|
|
||||||
return -sharpe # Negative for minimization
|
|
||||||
|
|
||||||
print("\n1. Setting up optimization:")
|
|
||||||
print(" Parameters: [short_window, long_window, stop_loss]")
|
|
||||||
print(" Bounds: short=[5, 50], long=[20, 200], stop_loss=[0.02, 0.15]")
|
|
||||||
|
|
||||||
# Define objective function for OptimizR
|
|
||||||
def objective(x: List[float]) -> float:
|
|
||||||
return moving_average_strategy(x, prices)
|
|
||||||
|
|
||||||
# Optimize with Differential Evolution
|
|
||||||
print("\n2. Running Differential Evolution:")
|
|
||||||
result = optimizr.differential_evolution(
|
|
||||||
objective,
|
|
||||||
bounds=[(5, 50), (20, 200), (0.02, 0.15)],
|
|
||||||
strategy="best1",
|
|
||||||
max_iterations=50,
|
|
||||||
population_size=20,
|
|
||||||
convergence_threshold=1e-6
|
|
||||||
)
|
|
||||||
|
|
||||||
print(f" Optimization complete!")
|
|
||||||
print(f" Best parameters:")
|
|
||||||
print(f" Short window: {int(result['x'][0])} days")
|
|
||||||
print(f" Long window: {int(result['x'][1])} days")
|
|
||||||
print(f" Stop loss: {result['x'][2]*100:.1f}%")
|
|
||||||
print(f" Best Sharpe ratio: {-result['fun']:.3f}")
|
|
||||||
print(f" Iterations: {result['nit']}")
|
|
||||||
|
|
||||||
print("\n✅ Workflow 2 complete! Optimal strategy parameters found.")
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def workflow3_risk_analysis():
|
|
||||||
"""
|
|
||||||
Workflow 3: Comprehensive Risk Analysis
|
|
||||||
|
|
||||||
Combines Polaroid's data processing with OptimizR's risk metrics
|
|
||||||
for portfolio risk assessment.
|
|
||||||
"""
|
|
||||||
print("\n" + "=" * 70)
|
|
||||||
print("Workflow 3: Portfolio Risk Analysis")
|
|
||||||
print("=" * 70)
|
|
||||||
|
|
||||||
# Simulate multi-asset portfolio returns
|
|
||||||
np.random.seed(42)
|
|
||||||
n_days = 252
|
|
||||||
n_assets = 3
|
|
||||||
|
|
||||||
print("\n1. Simulating 3-asset portfolio (1 year daily data):")
|
|
||||||
|
|
||||||
# Generate correlated returns
|
|
||||||
corr_matrix = np.array([
|
|
||||||
[1.0, 0.6, 0.3],
|
|
||||||
[0.6, 1.0, 0.4],
|
|
||||||
[0.3, 0.4, 1.0]
|
|
||||||
])
|
|
||||||
|
|
||||||
# Cholesky decomposition for correlation
|
|
||||||
L = np.linalg.cholesky(corr_matrix)
|
|
||||||
uncorrelated = np.random.randn(n_days, n_assets) * 0.015
|
|
||||||
returns = uncorrelated @ L.T
|
|
||||||
|
|
||||||
# Add drift
|
|
||||||
returns[:, 0] += 0.0008 # Asset 1: 20% annual
|
|
||||||
returns[:, 1] += 0.0004 # Asset 2: 10% annual
|
|
||||||
returns[:, 2] += 0.0006 # Asset 3: 15% annual
|
|
||||||
|
|
||||||
print(f" Asset 1: Expected 20% annual return")
|
|
||||||
print(f" Asset 2: Expected 10% annual return")
|
|
||||||
print(f" Asset 3: Expected 15% annual return")
|
|
||||||
|
|
||||||
# Step 2: Individual asset statistics
|
|
||||||
print("\n2. Individual Asset Analysis:")
|
|
||||||
for i in range(n_assets):
|
|
||||||
mean, std, skew, kurt, sharpe = optimizr.return_statistics_py(
|
|
||||||
returns[:, i].tolist()
|
|
||||||
)
|
|
||||||
print(f"\n Asset {i+1}:")
|
|
||||||
print(f" Return (annual): {mean*252*100:.1f}%")
|
|
||||||
print(f" Volatility (annual): {std*np.sqrt(252)*100:.1f}%")
|
|
||||||
print(f" Skewness: {skew:.3f}")
|
|
||||||
print(f" Kurtosis: {kurt:.3f}")
|
|
||||||
print(f" Sharpe ratio: {sharpe:.3f}")
|
|
||||||
|
|
||||||
# Step 3: Mean-reversion analysis
|
|
||||||
print("\n3. Mean-Reversion Analysis:")
|
|
||||||
prices = [np.cumprod(1 + returns[:, i]) * 100 for i in range(n_assets)]
|
|
||||||
|
|
||||||
for i in range(n_assets):
|
|
||||||
hurst = optimizr.rolling_hurst_exponent_py(
|
|
||||||
returns[:, i].tolist(),
|
|
||||||
window_size=60
|
|
||||||
)
|
|
||||||
avg_hurst = np.mean(hurst)
|
|
||||||
|
|
||||||
half_life = optimizr.rolling_half_life_py(
|
|
||||||
prices[i].tolist(),
|
|
||||||
window_size=60
|
|
||||||
)
|
|
||||||
# Filter out infinities
|
|
||||||
finite_hl = [hl for hl in half_life if np.isfinite(hl)]
|
|
||||||
avg_hl = np.mean(finite_hl) if finite_hl else float('inf')
|
|
||||||
|
|
||||||
print(f"\n Asset {i+1}:")
|
|
||||||
print(f" Hurst exponent: {avg_hurst:.3f}", end="")
|
|
||||||
if avg_hurst < 0.45:
|
|
||||||
print(" (mean-reverting)")
|
|
||||||
elif avg_hurst > 0.55:
|
|
||||||
print(" (trending)")
|
|
||||||
else:
|
|
||||||
print(" (random walk)")
|
|
||||||
|
|
||||||
if np.isfinite(avg_hl):
|
|
||||||
print(f" Half-life: {avg_hl:.1f} days")
|
|
||||||
|
|
||||||
# Step 4: Correlation analysis
|
|
||||||
print("\n4. Correlation Matrix (rolling 60-day):")
|
|
||||||
for i in range(n_assets):
|
|
||||||
for j in range(i+1, n_assets):
|
|
||||||
corr = optimizr.rolling_correlation_py(
|
|
||||||
returns[:, i].tolist(),
|
|
||||||
returns[:, j].tolist(),
|
|
||||||
window_size=60
|
|
||||||
)
|
|
||||||
avg_corr = np.mean(corr)
|
|
||||||
print(f" Asset {i+1} ↔ Asset {j+1}: {avg_corr:.3f}")
|
|
||||||
|
|
||||||
# Step 5: Portfolio optimization weights (equal risk contribution)
|
|
||||||
print("\n5. Portfolio Construction:")
|
|
||||||
weights = [1/n_assets] * n_assets
|
|
||||||
portfolio_returns = returns @ np.array(weights)
|
|
||||||
|
|
||||||
mean, std, skew, kurt, sharpe = optimizr.return_statistics_py(
|
|
||||||
portfolio_returns.tolist()
|
|
||||||
)
|
|
||||||
|
|
||||||
print(f" Equal-weight portfolio:")
|
|
||||||
print(f" Return (annual): {mean*252*100:.1f}%")
|
|
||||||
print(f" Volatility (annual): {std*np.sqrt(252)*100:.1f}%")
|
|
||||||
print(f" Sharpe ratio: {sharpe:.3f}")
|
|
||||||
|
|
||||||
print("\n✅ Workflow 3 complete! Comprehensive risk analysis finished.")
|
|
||||||
|
|
||||||
|
|
||||||
def workflow4_pairs_trading_pipeline():
|
|
||||||
"""
|
|
||||||
Workflow 4: Complete Pairs Trading Pipeline
|
|
||||||
|
|
||||||
End-to-end pairs trading: cointegration check, parameter optimization,
|
|
||||||
and risk management using OptimizR's integrated tools.
|
|
||||||
"""
|
|
||||||
print("\n" + "=" * 70)
|
|
||||||
print("Workflow 4: Pairs Trading Pipeline")
|
|
||||||
print("=" * 70)
|
|
||||||
|
|
||||||
# Generate cointegrated pair
|
|
||||||
np.random.seed(42)
|
|
||||||
n_days = 500
|
|
||||||
|
|
||||||
# Asset 1: Random walk with drift
|
|
||||||
returns1 = np.random.normal(0.0003, 0.015, n_days)
|
|
||||||
prices1 = 100 * np.cumprod(1 + returns1)
|
|
||||||
|
|
||||||
# Asset 2: Cointegrated with Asset 1
|
|
||||||
spread_noise = np.random.normal(0, 0.01, n_days)
|
|
||||||
prices2 = prices1 * 0.9 + np.cumsum(spread_noise)
|
|
||||||
|
|
||||||
# Calculate spread
|
|
||||||
spread = prices1 - prices2
|
|
||||||
|
|
||||||
print("\n1. Cointegration Analysis:")
|
|
||||||
|
|
||||||
# Check mean-reversion
|
|
||||||
spread_returns = np.diff(spread) / spread[:-1]
|
|
||||||
hurst = optimizr.rolling_hurst_exponent_py(
|
|
||||||
spread_returns.tolist(),
|
|
||||||
window_size=60
|
|
||||||
)
|
|
||||||
avg_hurst = np.mean(hurst)
|
|
||||||
print(f" Hurst exponent: {avg_hurst:.3f}", end="")
|
|
||||||
|
|
||||||
if avg_hurst < 0.5:
|
|
||||||
print(" ✅ Mean-reverting (good for pairs trading)")
|
|
||||||
else:
|
|
||||||
print(" ⚠️ Not clearly mean-reverting")
|
|
||||||
|
|
||||||
# Estimate half-life
|
|
||||||
half_lives = optimizr.rolling_half_life_py(
|
|
||||||
spread.tolist(),
|
|
||||||
window_size=60
|
|
||||||
)
|
|
||||||
finite_hl = [hl for hl in half_lives if np.isfinite(hl) and hl > 0]
|
|
||||||
avg_hl = np.mean(finite_hl) if finite_hl else float('inf')
|
|
||||||
|
|
||||||
if np.isfinite(avg_hl):
|
|
||||||
print(f" Half-life: {avg_hl:.1f} days (reversion speed)")
|
|
||||||
|
|
||||||
# Correlation check
|
|
||||||
returns2 = np.diff(prices2) / prices2[:-1]
|
|
||||||
corr = optimizr.rolling_correlation_py(
|
|
||||||
returns1[1:].tolist(),
|
|
||||||
returns2.tolist(),
|
|
||||||
window_size=60
|
|
||||||
)
|
|
||||||
avg_corr = np.mean(corr)
|
|
||||||
print(f" Correlation: {avg_corr:.3f}", end="")
|
|
||||||
|
|
||||||
if avg_corr > 0.7:
|
|
||||||
print(" ✅ Strong correlation")
|
|
||||||
elif avg_corr > 0.5:
|
|
||||||
print(" ⚠️ Moderate correlation")
|
|
||||||
else:
|
|
||||||
print(" ❌ Weak correlation")
|
|
||||||
|
|
||||||
# Step 2: Optimize strategy parameters
|
|
||||||
print("\n2. Strategy Parameter Optimization:")
|
|
||||||
|
|
||||||
def pairs_strategy(params: List[float]) -> float:
|
|
||||||
"""
|
|
||||||
Pairs trading with mean-reversion.
|
|
||||||
params = [entry_z, exit_z, stop_loss]
|
|
||||||
Returns: negative Sharpe (for minimization)
|
|
||||||
"""
|
|
||||||
entry_z = params[0]
|
|
||||||
exit_z = params[1]
|
|
||||||
stop_loss = params[2]
|
|
||||||
|
|
||||||
# Calculate z-score
|
|
||||||
window = 20
|
|
||||||
spread_ma = np.convolve(spread, np.ones(window)/window, mode='valid')
|
|
||||||
spread_std = np.array([
|
|
||||||
np.std(spread[i:i+window])
|
|
||||||
for i in range(len(spread) - window + 1)
|
|
||||||
])
|
|
||||||
|
|
||||||
aligned_spread = spread[window-1:]
|
|
||||||
z_score = (aligned_spread - spread_ma) / (spread_std + 1e-6)
|
|
||||||
|
|
||||||
# Trading logic
|
|
||||||
position = 0 # 1 = long spread, -1 = short spread
|
|
||||||
returns = []
|
|
||||||
entry_value = 0
|
|
||||||
|
|
||||||
for i in range(1, len(z_score)):
|
|
||||||
# Entry signals
|
|
||||||
if z_score[i] > entry_z and position == 0:
|
|
||||||
position = -1 # Short spread (short asset1, long asset2)
|
|
||||||
entry_value = aligned_spread[i]
|
|
||||||
elif z_score[i] < -entry_z and position == 0:
|
|
||||||
position = 1 # Long spread (long asset1, short asset2)
|
|
||||||
entry_value = aligned_spread[i]
|
|
||||||
|
|
||||||
# Exit signals
|
|
||||||
if abs(z_score[i]) < exit_z and position != 0:
|
|
||||||
position = 0
|
|
||||||
|
|
||||||
# Stop loss
|
|
||||||
if position != 0 and entry_value != 0:
|
|
||||||
pnl = position * (aligned_spread[i] - entry_value) / abs(entry_value)
|
|
||||||
if pnl < -stop_loss:
|
|
||||||
position = 0
|
|
||||||
|
|
||||||
# Calculate returns
|
|
||||||
if position != 0:
|
|
||||||
spread_ret = (aligned_spread[i] - aligned_spread[i-1]) / aligned_spread[i-1]
|
|
||||||
returns.append(position * spread_ret)
|
|
||||||
else:
|
|
||||||
returns.append(0)
|
|
||||||
|
|
||||||
if len(returns) < 10:
|
|
||||||
return 999.0
|
|
||||||
|
|
||||||
mean_ret = np.mean(returns)
|
|
||||||
std_ret = np.std(returns)
|
|
||||||
if std_ret == 0:
|
|
||||||
return 999.0
|
|
||||||
|
|
||||||
sharpe = mean_ret / std_ret * np.sqrt(252)
|
|
||||||
return -sharpe
|
|
||||||
|
|
||||||
print(" Optimizing: [entry_z, exit_z, stop_loss]")
|
|
||||||
|
|
||||||
result = optimizr.differential_evolution(
|
|
||||||
pairs_strategy,
|
|
||||||
bounds=[(1.5, 3.0), (0.1, 1.0), (0.02, 0.1)],
|
|
||||||
strategy="best1",
|
|
||||||
max_iterations=30,
|
|
||||||
population_size=15
|
|
||||||
)
|
|
||||||
|
|
||||||
print(f" Optimal parameters:")
|
|
||||||
print(f" Entry z-score: {result['x'][0]:.2f}")
|
|
||||||
print(f" Exit z-score: {result['x'][1]:.2f}")
|
|
||||||
print(f" Stop loss: {result['x'][2]*100:.1f}%")
|
|
||||||
print(f" Expected Sharpe: {-result['fun']:.3f}")
|
|
||||||
|
|
||||||
print("\n✅ Workflow 4 complete! Pairs trading strategy optimized.")
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
print("=" * 70)
|
|
||||||
print("Polaroid + OptimizR Integration Examples")
|
|
||||||
print("=" * 70)
|
|
||||||
print("\nDemonstrating 4 integrated workflows combining time-series")
|
|
||||||
print("operations with optimization and statistical inference.")
|
|
||||||
|
|
||||||
# Run all workflows
|
|
||||||
workflow1_regime_detection_with_features()
|
|
||||||
workflow2_strategy_optimization()
|
|
||||||
workflow3_risk_analysis()
|
|
||||||
workflow4_pairs_trading_pipeline()
|
|
||||||
|
|
||||||
print("\n" + "=" * 70)
|
|
||||||
print("✅ All integration workflows completed successfully!")
|
|
||||||
print("=" * 70)
|
|
||||||
print("\nThese examples show how to combine:")
|
|
||||||
print(" • Polaroid's time-series operations (lag, diff, pct_change)")
|
|
||||||
print(" • OptimizR's optimization (DE, grid search)")
|
|
||||||
print(" • OptimizR's inference (HMM, MCMC)")
|
|
||||||
print(" • OptimizR's time-series helpers (Hurst, half-life, etc.)")
|
|
||||||
print("\nFor production use, connect to Polaroid gRPC for data processing.")
|
|
||||||
print("=" * 70)
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Helper functions for common workflows combining time-series preprocessing
|
//! Helper functions for common workflows combining time-series preprocessing
|
||||||
//! with optimization and statistical inference. Designed to work seamlessly
|
//! with optimization and statistical inference. Designed to work seamlessly
|
||||||
//! with Polaroid time-series operations and OptimizR algorithms.
|
//! with Polarway time-series operations and OptimizR algorithms.
|
||||||
//!
|
//!
|
||||||
//! # Use Cases
|
//! # Use Cases
|
||||||
//!
|
//!
|
||||||
|
|||||||
Reference in New Issue
Block a user