Skip to main content

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.

Current Release Python 3.10+ rustc 1.89+ Test Linux Test Windows Test MacOS Lints License

[!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(&params)?;
    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

  1. Install Rust (1.74 or newer recommended) and Python 3.10–3.14.
  2. Create/activate a virtual environment.
  3. Install the build backend:
    pip install "maturin[patchelf]"
    
  4. Build and install the extension in editable mode:
    maturin develop --release
    
    The command compiles the Rust sources with the python feature enabled and installs the dervflow package 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dervflow-0.1.2.tar.gz (2.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dervflow-0.1.2-cp310-abi3-win_amd64.whl (897.0 kB view details)

Uploaded CPython 3.10+Windows x86-64

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

Hashes for dervflow-0.1.2.tar.gz
Algorithm Hash digest
SHA256 fd68284431d1dc46017141bcbbb0bf6172443f84d1dc3924cef5627b7c3376c0
MD5 9a8fa22a02dc695786b9f4928dff7cbf
BLAKE2b-256 10b6b5b4965ee725c7e85330f4cb00dd7047b3f692d69374d12b2ab5407857a5

See more details on using hashes here.

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

Hashes for dervflow-0.1.2-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 ecfada35af37994b644f18ab3240510b0b2d0e53c05067819700bbe6dfc1eb48
MD5 b600c7f934b85e3902f946772ddc6e4d
BLAKE2b-256 ccfdd396fbc4da96efd888d525b88b47fc9853e3e4e02d97036adfb3764d7e60

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page