Skip to main content

License GitHub Workflow Status Crates.io GitHub Repo stars Crates.io Codecov Dependencies

Rust library for quantitative finance tools.

🎯 I want to hit a stable and legitimate v1.0.0 by the end of 2023, so any and all feedback, suggestions, or contributions are strongly welcomed!

Contact: rustquantcontact@gmail.com

Disclaimer: This is currently a free-time project and not a professional financial software library. Nothing in this library should be taken as financial advice, and I do not recommend you to use it for trading or making financial decisions.

📰 Latest features

  • Download time series data from Yahoo! Finance.
  • Read (write) from (to) .csv, .json, and .parquet files, using Polars DataFrames.
  • Arithmetic Brownian Motion generator.
  • Gamma, exponential, and chi-squared distributions.
  • Forward start option pricer (Rubinstein 1990 formula).
  • Gap option and cash-or-nothing option pricers (currently adding more binary options).
  • Asian option pricer (closed-form solution for continuous geometric average).
  • Heston Model option pricer (uses the tanh-sinh quadrature numerical integrator).
  • Tanh-sinh (double exponential) quadrature for evaluating integrals.
    • Plus other basic numerical integrators (midpoint, trapezoid, Simpson's 3/8).
  • Characteristic functions and density functions for common distributions:
    • Gaussian, Bernoulli, Binomial, Poisson, Uniform, Chi-Squared, Gamma, and Exponential.

Table of Contents

  1. Automatic Differentiation
  2. Option Pricers
  3. Stochastic Processes and Short Rate Models
  4. Bonds
  5. Distributions
  6. Mathematics
  7. Helper Functions and Macros
  8. How-tos
  9. References

🔗 Automatic Differentiation

Currently only gradients can be computed. Suggestions on how to extend the functionality to Hessian matrices are definitely welcome.

  • Reverse (Adjoint) Mode
    • Implementation via Operator and Function Overloading.
    • Useful when number of outputs is smaller than number of inputs.
      • i.e for functions $f:\mathbb{R}^n \rightarrow \mathbb{R}^m$, where $m \ll n$
  • Forward (Tangent) Mode
    • Implementation via Dual Numbers.
    • Useful when number of outputs is larger than number of inputs.
      • i.e. for functions $f:\mathbb{R}^n \rightarrow \mathbb{R}^m$, where $m \gg n$

💸 Option Pricers

  • Closed-form price solutions:

    • Heston Model
    • Barrier
    • European
    • Greeks/Sensitivities
    • Lookback
    • Asian: Continuous Geometric Average
    • Forward Start
    • Basket
    • Rainbow
    • American
  • Lattice models:

    • Binomial Tree (Cox-Ross-Rubinstein)

The stochastic process generators can be used to price path-dependent options via Monte-Carlo.

  • Monte Carlo pricing:
    • Lookback
    • Asian
    • Chooser
    • Barrier

📈 Stochastic Processes and Short Rate Models

The following is a list of stochastic processes that can be generated.

  • Brownian Motion
  • Arithmetic Brownian Motion
    • $dX_t = \mu dt + \sigma dW_t$
  • Geometric Brownian Motion
    • $dX_t = \mu X_t dt + \sigma X_t dW_t$
    • Models: Black-Scholes (1973), Rendleman-Bartter (1980)
  • Cox-Ingersoll-Ross (1985)
    • $dX_t = (\theta - \alpha X_t)dt + \sqrt{r_t} \sigma dW_t$
  • Ornstein-Uhlenbeck process
    • $dX_t = \theta(\mu - X_t)dt + \sigma dW_t$
    • Models: Vasicek (1977)
  • Ho-Lee (1986)
    • $dX_t = \theta_t dt + \sigma dW_t$
  • Hull-White (1990)
    • $dX_t = (\theta - \alpha X_t)dt + \sigma_t dW_t$
  • Black-Derman-Toy (1990)
    • $d\ln(X) = \left[ \theta_t + \frac{\sigma_t'}{\sigma_t}\ln(X) \right]dt + \sigma_t dW_t$
    • $d\ln(X) = \theta_t dt + \sigma dW_t$
  • Merton's model (1973)
    • $X_t = X_0 + at + \sigma W_t^*$
    • $dX_t = adt + \sigma dW_t^*$

📉 Bonds

  • Prices:
    • The Vasicek Model
    • The Cox, Ingersoll, and Ross Model
    • The Rendleman and Bartter Model
    • The Ho–Lee Model
    • The Hull–White (One-Factor) Model
    • The Black–Derman–Toy Model
    • The Black–Karasinski Model
  • Duration
  • Convexity

📊 Distributions

Probability density/mass functions, distribution functions, characteristic functions, etc.

  • Gaussian
  • Bernoulli
  • Binomial
  • Poisson
  • Uniform (discrete & continuous)
  • Chi-Squared
  • Gamma
  • Exponential

📐 Mathematics

  • Numerical Integration (needed for Heston model, for example):
    • Tanh-Sinh (double exponential) quadrature
    • Composite Midpoint Rule
    • Composite Trapezoidal Rule
    • Composite Simpson's 3/8 Rule
  • Risk-Reward Measures (Sharpe, Treynor, Sortino, etc)
  • Newton-Raphson
  • Standard Normal Distribution (Distribution/Density functions, and generation of variates)
  • Interpolation

🤝 Helper Functions and Macros

A collection of utility functions and macros.

  • Plot a vector.
  • Write vector to file.
  • Cumulative sum of vector.
  • Linearly spaced sequence.
  • assert_approx_equal!

✔️ How-tos

I would not recommend using RustQuant within any other libraries for some time, as it will most likely go through many breaking changes as I learn more Rust and settle on a decent structure for the library.

🙏 I would greatly appreciate contributions so it can get to the v1.0.0 mark ASAP.

Download data from Yahoo! Finance:

You can download data from Yahoo! Finance into a Polars DataFrame.

use RustQuant::data::*;
use time::macros::date;

fn main() {
    // New YahooFinanceData instance. 
    // By default, date range is: 1970-01-01 to present. 
    let mut yfd = YahooFinanceData::new("AAPL".to_string());

    // Can specify custom dates (optional). 
    yfd.set_start_date(time::macros::datetime!(2019 - 01 - 01 0:00 UTC));
    yfd.set_end_date(time::macros::datetime!(2020 - 01 - 01 0:00 UTC));

    // Download the historical data. 
    yfd.get_price_history();

    println!("Apple's quotes: {:?}", yfd.price_history)
}
Apple's quotes: Some(shape: (252, 7)
┌────────────┬───────────┬───────────┬───────────┬───────────┬────────────┬───────────┐
│ date       ┆ open      ┆ high      ┆ low       ┆ close     ┆ volume     ┆ adjusted  │
│ ---        ┆ ---       ┆ ---       ┆ ---       ┆ ---       ┆ ---        ┆ ---       │
│ date       ┆ f64       ┆ f64       ┆ f64       ┆ f64       ┆ f64        ┆ f64       │
╞════════════╪═══════════╪═══════════╪═══════════╪═══════════╪════════════╪═══════════╡
│ 2019-01-02 ┆ 38.7225   ┆ 39.712502 ┆ 38.557499 ┆ 39.48     ┆ 1.481588e8 ┆ 37.994499 │
│ 2019-01-03 ┆ 35.994999 ┆ 36.43     ┆ 35.5      ┆ 35.547501 ┆ 3.652488e8 ┆ 34.209969 │
│ 2019-01-04 ┆ 36.1325   ┆ 37.137501 ┆ 35.950001 ┆ 37.064999 ┆ 2.344284e8 ┆ 35.670372 │
│ 2019-01-07 ┆ 37.174999 ┆ 37.2075   ┆ 36.474998 ┆ 36.982498 ┆ 2.191112e8 ┆ 35.590965 │
│ …          ┆ …         ┆ …         ┆ …         ┆ …         ┆ …          ┆ …         │
│ 2019-12-26 ┆ 71.205002 ┆ 72.495003 ┆ 71.175003 ┆ 72.477501 ┆ 9.31212e7  ┆ 70.798401 │
│ 2019-12-27 ┆ 72.779999 ┆ 73.4925   ┆ 72.029999 ┆ 72.449997 ┆ 1.46266e8  ┆ 70.771545 │
│ 2019-12-30 ┆ 72.364998 ┆ 73.172501 ┆ 71.305    ┆ 72.879997 ┆ 1.441144e8 ┆ 71.191582 │
│ 2019-12-31 ┆ 72.482498 ┆ 73.419998 ┆ 72.379997 ┆ 73.412498 ┆ 1.008056e8 ┆ 71.711739 │
└────────────┴───────────┴───────────┴───────────┴───────────┴────────────┴───────────┘)

Read/write data:

use RustQuant::data::*;

fn main() {
    // New `Data` instance.
    let mut data = Data::new(
        format: DataFormat::CSV, // Can also be JSON or PARQUET.
        path: String::from("./file/path/read.csv")
    )

    // Read from the given file. 
    data.read().unwrap();

    // New path to write the data to. 
    data.path = String::from("./file/path/write.csv")
    data.write().unwrap();

    println!("{:?}", data.data)
}

Compute gradients:

use RustQuant::autodiff::*;

fn main() {
    // Create a new Tape.
    let t = Tape::new();

    // Assign variables.
    let x = t.var(0.5);
    let y = t.var(4.2);

    // Define a function.
    let z = x * y + x.sin();

    // Accumulate the gradient.
    let grad = z.accumulate();

    println!("Function = {}", z);
    println!("Gradient = {:?}", grad.wrt([x, y]));
}

Compute integrals:

use RustQuant::math::*;

fn main() {
    // Define a function to integrate: e^(sin(x))
    fn f(x: f64) -> f64 {
        (x.sin()).exp()
    }

    // Integrate from 0 to 5.
    let integral = integrate(f, 0.0, 5.0);

    // ~ 7.18911925
    println!("Integral = {}", integral); 
}

Price options:

use RustQuant::options::*;

fn main() {
    let VanillaOption = EuropeanOption {
        initial_price: 100.0,
        strike_price: 110.0,
        risk_free_rate: 0.05,
        volatility: 0.2,
        dividend_rate: 0.02,
        time_to_maturity: 0.5,
    };

    let prices = VanillaOption.price();

    println!("Call price = {}", prices.0);
    println!("Put price = {}", prices.1);
}

Generate stochastic processes:

use RustQuant::stochastics::*;

fn main() {
    // Create new GBM with mu and sigma.
    let gbm = GeometricBrownianMotion::new(0.05, 0.9);

    // Generate path using Euler-Maruyama scheme.
    // Parameters: x_0, t_0, t_n, n, sims, parallel.
    let output = (&gbm).euler_maruyama(10.0, 0.0, 0.5, 10, 1, false);

    println!("GBM = {:?}", output.trajectories);
}

📖 References:

  • John C. Hull - Options, Futures, and Other Derivatives
  • Damiano Brigo & Fabio Mercurio - Interest Rate Models - Theory and Practice (With Smile, Inflation and Credit)
  • Paul Glasserman - Monte Carlo Methods in Financial Engineering
  • Andreas Griewank & Andrea Walther - Evaluating Derivatives - Principles and Techniques of Algorithmic Differentiation
  • Steven E. Shreve - Stochastic Calculus for Finance II: Continuous-Time Models
  • Espen Gaarder Haug - Option Pricing Formulas
  • Antoine Savine - Modern Computational Finance: AAD and Parallel Simulations

Metadata

Release files for rustquant 0.0.17

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rustquant 0.0.17
File Size Uploaded
RustQuant-0.0.17.tar.gz 24.8 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for rustquant 0.0.17
File Interpreter ABI Platform
RustQuant-0.0.17-cp37-abi3-manylinux_2_34_x86_64.whl CPython 3.7 abi3 Linux glibc 2.34+ x86-64 Details

Total release size: 25.7 MB

Release files / RustQuant-0.0.17.tar.gz

Download URL RustQuant-0.0.17.tar.gz
Size 24.8 MB
Tags Source
SHA-256 checksum
How to use checksums
2264900b4c14e64c58eaf2d035860e87ae2dc254e57ae0f674f33e997f04998d
BLAKE2b-256 checksum
How to use checksums
76b7e64ed301cbf1c186fc4b9e6dfdaec34abdc69797cfb7cf14e447cba9be1f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.0.1

Release files / RustQuant-0.0.17-cp37-abi3-manylinux_2_34_x86_64.whl

Download URL RustQuant-0.0.17-cp37-abi3-manylinux_2_34_x86_64.whl
Size 917.6 kB
Tags CPython 3.7 Linux glibc 2.34+ x86-64 abi3
SHA-256 checksum
How to use checksums
09af85d0602096e3a6d2edb50ab6a58d20f1b1f12fcabdc50590b713dbe777bf
BLAKE2b-256 checksum
How to use checksums
85f5e50aa702018a7c4c62b0efc16397ddfead28d6b8307606972562113bec73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.0.1

Release history Release notifications | RSS feed

This release

0.0.17 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page