Skip to content

Commit

Permalink
feat: add rbergomi model
Browse files Browse the repository at this point in the history
  • Loading branch information
dancixx committed Sep 12, 2024
1 parent 3897d63 commit 58ae108
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 31 deletions.
33 changes: 2 additions & 31 deletions stochastic-rs-core/src/volatility.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,4 @@
//! This module contains the implementations of various diffusion processes.
//!
//! The following diffusion processes are implemented:
//!
//! - Duffie-Kan Model
//! - The Duffie-Kan model is a multifactor interest rate model incorporating correlated Brownian motions.
//! - SDE: `dr(t) = (a1 * r(t) + b1 * x(t) + c1) * dt + sigma1 * (alpha * r(t) + beta * x(t) + gamma) * dW_r(t)`
//! - SDE: `dx(t) = (a2 * r(t) + b2 * x(t) + c2) * dt + sigma2 * (alpha * r(t) + beta * x(t) + gamma) * dW_x(t)`
//! - where Corr(W_r(t), W_x(t)) = rho
//!
//! - **Heston Model**
//! - A stochastic volatility model used to describe the evolution of the volatility of an underlying asset.
//! - SDE: `dS(t) = mu * S(t) * dt + S(t) * sqrt(V(t)) * dW_1(t)`
//! - SDE: `dV(t) = kappa * (theta - V(t)) * dt + eta * sqrt(V(t)) * dW_2(t)`
//!
//! - SABR (Stochastic Alpha, Beta, Rho) Model
//! - Widely used in financial mathematics for modeling stochastic volatility.
//! - SDE: `dF(t) = V(t) * F(t)^beta * dW_F(t)`
//! - SDE: `dV(t) = alpha * V(t) * dW_V(t)`
//! - where Corr(W_F(t), W_V(t)) = rho
//!
//! - **Vasicek Model**
//! - An Ornstein-Uhlenbeck process used to model interest rates.
//! - SDE: `dX(t) = theta * (mu - X(t)) * dt + sigma * dW(t)`
//!
//! - **Fractional Vasicek (fVasicek) Model**
//! - Incorporates fractional Brownian motion into the Vasicek model.
//! - SDE: `dX(t) = theta * (mu - X(t)) * dt + sigma * dW^H(t)`
//!
//! Each process has its own module and functions to generate sample paths.
pub mod fheston;
pub mod heston;
pub mod rbergomi;
pub mod sabr;
71 changes: 71 additions & 0 deletions stochastic-rs-core/src/volatility/rbergomi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use ndarray::{s, Array1};

use crate::{noise::cgns::Cgns, Sampling2D};

#[derive(Default)]
pub struct RoughBergomi {
pub hurst: f64,
pub nu: f64,
pub sigma_0: f64,
pub r: f64,
pub rho: f64,
pub n: usize,
pub t: Option<f64>,
pub m: Option<usize>,
pub cgns: Cgns,
}

impl RoughBergomi {
#[must_use]
pub fn new(params: &Self) -> Self {
let cgns = Cgns::new(&Cgns {
rho: params.rho,
n: params.n,
t: params.t,
m: params.m,
});

Self {
hurst: params.hurst,
nu: params.nu,
sigma_0: params.sigma_0,
r: params.r,
rho: params.rho,
n: params.n,
t: params.t,
m: params.m,
cgns,
}
}
}

impl Sampling2D<f64> for RoughBergomi {
fn sample(&self) -> [Array1<f64>; 2] {
let dt = self.t.unwrap_or(1.0) / self.n as f64;
let [cgn1, z] = self.cgns.sample();

let mut s = Array1::<f64>::zeros(self.n + 1);
let mut sigma2 = Array1::<f64>::zeros(self.n + 1);

for i in 1..(self.n + 1) {
s[i] = s[i - 1] + self.r * s[i - 1] + sigma2[i - 1] * cgn1[i - 1];

let sum_z = z.slice(s![..i]).sum();
let t = i as f64 * dt;
sigma2[i] = self.sigma_0.powi(2)
* (self.nu * (2.0 * self.hurst).sqrt() * t.powf(self.hurst - 0.5) * sum_z
- 0.5 * self.nu.powi(2) * t.powf(2.0 * self.hurst))
.exp();
}

[s, sigma2]
}

fn n(&self) -> usize {
self.n
}

fn m(&self) -> Option<usize> {
self.m
}
}

0 comments on commit 58ae108

Please sign in to comment.