A Lightweight, High-Performance Mathematics & Quantitative Finance Toolkit
Project description
DervFlow
A Lightweight, High-Performance Mathematics & Quantitative Finance Toolkit
DervFlow delivers production-ready option pricers, risk analytics, portfolio construction utilities, time-series diagnostics, and yield-curve analytics backed by rigorously tested numerical kernels.
[!CAUTION] Active development. APIs may evolve before a 1.0 release.
Highlights
- Options pricing – Black-Scholes-Merton analytics, implied volatility solvers, binomial trees, Longstaff–Schwartz Monte Carlo, and exotic payoffs (Asian, barrier, lookback, digital) exposed through ergonomic Python classes.
- Risk analytics – Portfolio Greeks aggregation, historical/parametric/Monte Carlo VaR and CVaR, drawdown analytics, and performance ratios.
- Portfolio construction – Mean-variance optimisation with constraints, efficient frontiers, risk parity allocation, and Black–Litterman blending of market and investor views.
- Yield curves – Bootstrapping from bonds or swaps, Nelson–Siegel(-Svensson) parametrisations, zero/forward/discount curve queries, and bond analytics (duration, convexity, DV01).
- Time series – Return transformations, rolling and EW statistics, autocorrelation diagnostics, hypothesis tests, and GARCH-family volatility models.
- Monte Carlo – High-throughput stochastic process simulators (GBM, Ornstein–Uhlenbeck, CIR, Vasicek) with optional parallel path generation.
- Numerical kernels – Deterministic integrators, root-finders, optimisers, quasi-random generators, and dense linear-algebra helpers implemented in Rust for safety and speed.
Python quick start
The package exposes the compiled extension as dervflow.
Option pricing and risk
from dervflow import BlackScholesModel, MonteCarloOptionPricer, RiskMetrics
import numpy as np
# Analytical Black–Scholes pricing with Greeks
bs = BlackScholesModel()
call_price = bs.price(
spot=100.0,
strike=100.0,
rate=0.05,
dividend=0.02,
volatility=0.20,
time=1.0,
option_type="call",
)
call_greeks = bs.greeks(100.0, 100.0, 0.05, 0.02, 0.20, 1.0, "call")
print(f"Call price: {call_price:.2f}")
print(f"Delta: {call_greeks['delta']:.4f}, Vega: {call_greeks['vega']:.4f}")
# Monte Carlo pricing with antithetic variates and parallel execution
mc = MonteCarloOptionPricer()
mc_result = mc.price_european(
spot=100.0,
strike=100.0,
rate=0.05,
dividend=0.02,
volatility=0.20,
time=1.0,
option_type="call",
num_paths=100_000,
use_antithetic=True,
seed=7,
parallel=True,
)
print(f"MC price: {mc_result['price']:.2f} ± {mc_result['std_error']:.4f}")
# Historical Value at Risk on simulated P&L
rng = np.random.default_rng(seed=123)
pl = rng.normal(0.0, 0.02, size=10_000)
risk = RiskMetrics()
var = risk.var(pl, confidence_level=0.95, method="historical")
print(f"95% VaR: {var['var']:.4%}")
Monte Carlo simulation
from dervflow import MonteCarloEngine
import matplotlib.pyplot as plt
engine = MonteCarloEngine(seed=42)
paths = engine.simulate_gbm(
s0=100.0,
mu=0.05,
sigma=0.20,
T=1.0,
steps=252,
paths=2_000,
parallel=True,
)
plt.figure(figsize=(10, 6))
plt.plot(paths[:10].T)
plt.title("Sample GBM paths")
plt.xlabel("Time step")
plt.ylabel("Price")
plt.tight_layout()
plt.show()
Portfolio optimisation
from dervflow import PortfolioOptimizer
import numpy as np
rng = np.random.default_rng(seed=0)
# Daily returns for four assets (252 trading days)
returns = rng.normal(loc=0.0005, scale=0.015, size=(252, 4))
optimizer = PortfolioOptimizer(returns)
min_weights = np.zeros(returns.shape[1])
max_weights = np.full(returns.shape[1], 0.6)
result = optimizer.optimize(
target_return=float(returns.mean(axis=0).mean()),
min_weights=min_weights,
max_weights=max_weights,
)
print("Optimal weights:", result["weights"])
print(f"Expected return: {result['expected_return']:.2%}")
print(f"Volatility: {result['volatility']:.2%}")
frontier = optimizer.efficient_frontier(num_points=10, min_weights=min_weights, max_weights=max_weights)
for point in frontier[:3]:
print(
f"Frontier portfolio → return: {point['expected_return']:.2%}, volatility: {point['volatility']:.2%}"
)
Yield curves and fixed income
from dervflow import YieldCurve, YieldCurveBuilder, BondAnalytics
import numpy as np
# Interpolate zero rates
times = np.array([0.5, 1.0, 2.0, 5.0, 10.0])
rates = np.array([0.020, 0.024, 0.028, 0.034, 0.038])
curve = YieldCurve(times, rates, method="cubic_spline_natural")
print(f"5Y discount factor: {curve.discount_factor(5.0):.6f}")
# Bootstrap from bond quotes (maturity, coupon, clean price, frequency)
bonds = [
(0.5, 0.02, 99.50, 2),
(1.0, 0.025, 99.80, 2),
(2.0, 0.030, 100.20, 2),
(5.0, 0.035, 101.10, 2),
]
builder = YieldCurveBuilder()
bootstrapped = builder.bootstrap_from_bonds(bonds)
print(f"2Y zero rate: {bootstrapped.zero_rate(2.0):.4%}")
analytics = BondAnalytics()
duration = analytics.duration(
yield_rate=0.032,
coupon_rate=0.03,
years_to_maturity=5.0,
frequency=2,
duration_type="modified",
)
print(f"Modified duration: {duration:.4f}")
Time-series analytics
from dervflow import TimeSeriesAnalyzer
import numpy as np
prices = np.array([100.0, 102.0, 101.5, 103.0, 104.5, 103.8, 105.2])
analyzer = TimeSeriesAnalyzer(prices)
log_returns = analyzer.returns(method="log")
summary = analyzer.stat()
print(f"Mean: {summary['mean']:.5f}, Std Dev: {summary['std_dev']:.5f}")
acf = analyzer.autocorrelation(max_lag=5)
print("Autocorrelation (lags 0–5):", acf)
Rust crate usage
The Rust crate can be used directly without the Python bindings. Enable the domains you need via feature flags:
use dervflow::options::analytical::black_scholes_price;
use dervflow::common::types::{OptionParams, OptionType};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let params = OptionParams::new(100.0, 100.0, 0.05, 0.02, 0.20, 1.0, OptionType::Call);
let price = black_scholes_price(¶ms)?;
println!("Call price: {:.2}", price);
Ok(())
}
When depending on DervFlow from another Rust project, disable the default Python bindings and opt into the domains you require:
[dependencies]
dervflow = { path = "../dervflow", default-features = false, features = ["options", "numerical"] }
Installation
Python development workflow
- Install Rust (1.74 or newer recommended) and Python 3.10–3.14.
- Create/activate a virtual environment.
- Install the build backend:
pip install "maturin[patchelf]"
- Build and install the extension in editable mode:
maturin develop --release
The command compiles the Rust sources with thepythonfeature enabled and installs thedervflowpackage into the active environment.
Using the Rust crate only
If you only need the Rust APIs, compile without the Python bindings:
cargo build --no-default-features --features core
You can further narrow the domains (for example --features options,portfolio) depending on your needs.
Feature flags
DervFlow exposes granular Cargo features:
| Feature | Enables |
|---|---|
python |
PyO3 bindings (pyo3, numpy) for the Python extension module. Enabled by default. |
core |
Umbrella that enables every domain-specific module listed below. Enabled by default. |
numerical |
Foundational numerical routines (integration, optimisation, random generation). |
options |
Option pricing engines and volatility analytics. Depends on numerical. |
risk |
Greeks aggregation, VaR/CVaR, and portfolio risk metrics. Depends on numerical. |
portfolio |
Mean-variance optimisation, efficient frontier, risk parity, Black–Litterman. |
yield_curve |
Yield-curve bootstrapping, interpolation, and bond analytics. Depends on numerical. |
timeseries |
Returns, rolling statistics, correlation diagnostics, GARCH models. |
monte_carlo |
Stochastic process simulators and Monte Carlo pricing. Depends on numerical. |
Development and testing
Run the full test suite locally before opening a pull request:
# Ensure PyO3 uses the intended interpreter
export PYO3_PYTHON="$(which python3)"
# Rust unit and integration tests (all domains + Python bindings)
cargo test --all-features
# Python tests (requires maturin develop)
pytest tests/python -v
# Linting and formatting
cargo fmt
cargo clippy --all-targets --all-features
black python/
mypy python/dervflow
If linking against CPython fails when building with the python feature, install the appropriate python3.x-dev package and export PYO3_PYTHON to the desired interpreter before invoking cargo.
Citation
If you use dervflow in your work and wish to refer to it, please use the following BibTeX entry.
@software{dervflow,
author = {Soumyadip Sarkar},
title = {DervFlow: A Lightweight, High-Performance Mathematics & Quantitative Finance Toolkit},
year = {2025},
url = {https://github.com/alphavelocity/dervflow}
}
License
This project is licensed under the Apache License - see the LICENSE file for details.
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 dervflow-0.1.2.tar.gz.
File metadata
- Download URL: dervflow-0.1.2.tar.gz
- Upload date:
- Size: 2.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd68284431d1dc46017141bcbbb0bf6172443f84d1dc3924cef5627b7c3376c0
|
|
| MD5 |
9a8fa22a02dc695786b9f4928dff7cbf
|
|
| BLAKE2b-256 |
10b6b5b4965ee725c7e85330f4cb00dd7047b3f692d69374d12b2ab5407857a5
|
File details
Details for the file dervflow-0.1.2-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: dervflow-0.1.2-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 897.0 kB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ecfada35af37994b644f18ab3240510b0b2d0e53c05067819700bbe6dfc1eb48
|
|
| MD5 |
b600c7f934b85e3902f946772ddc6e4d
|
|
| BLAKE2b-256 |
ccfdd396fbc4da96efd888d525b88b47fc9853e3e4e02d97036adfb3764d7e60
|