This module provides a minimal‑memory C++ backend for portfolio optimization.
Delivered bindings
- NSGA‑II multi‑objective optimizer:
nsga2_optimize(returns, objectives, params, lo, hi, popsize, ngen, seed, crossover_prob, mutation_prob, w_prev=None)
- Projection utility:
prop_box_sum1(w, lo, hi, iters=6)
Design goals
- C++17 + pybind11 module (
opt_cpp
) - Zero‑copy NumPy views; no STL copies of inputs
- Reuse preallocated buffers; O(T·N + popsize·N) working memory
- Optional OpenMP parallel evaluation
- Deterministic for fixed seed
Build
-
Ensure a C++17 compiler and Python dev headers are available.
-
From repo root:
mkdir -p build && cd build cmake -S ../cpp -B . -DOPTCPP_USE_OPENMP=ON cmake --build . --config Release
-
Add the build dir to PYTHONPATH or install the built module
export PYTHONPATH=$PWD:$PYTHONPATH python -c "import opt_cpp; print(opt_cpp)"
Usage
Python
import numpy as np, opt_cpp R = np.random.normal(0, 0.01, size=(2000, 30)).astype(np.float64) W, S = opt_cpp.nsga2_optimize(R, ["sharpe","min_vol","cvar"], {"alpha":0.05, "ann":252.0}, lo=0.0, hi=0.3, popsize=64, ngen=20, seed=42, crossover_prob=0.9, mutation_prob=0.1) print(W.shape, S.shape) # Pareto front sizes
Notes
- Objectives match Python implementations used in this repo (annualized Sharpe/Sortino/Calmar, CVaR, Kelly, diversification ratio, target‑min‑vol, etc.).
- For
return_to_turnover
, ifw_prev
is None the L1 norm ofw
is used in the denominator. - Diversification ratio uses per‑asset standard deviations from the input returns (no full covariance allocation).
- Compile with
-DOPTCPP_FLOAT32=ON
to switch to float32.
Local build and run of the full app (API + Next.js UI):
-
Build and start services
docker compose up --build
-
Data cache persistence
Parquet data downloaded by the API is persisted on the host in
data_management/data/
via a bind mount. -
Environment
- Frontend proxies
/opt/*
and/data/*
to the API usingAPI_URL
(defaults tohttp://backend:8000
in compose). - You can toggle API debug logs by setting
DM_DEBUG=true
indocker-compose.yml
.
- Frontend proxies
This repo now includes a comprehensive .gitignore
to exclude venv/
, node_modules/
, build artifacts, and cached parquet data.
Initialize and push to your remote:
-
Initialize the repository
git init git add . git commit -m "Initial commit"
-
Add your remote and push
git remote add origin <YOUR_REMOTE_URL> git branch -M main git push -u origin main