Skip to content

Commit e217084

Browse files
committed
feat: add ADG model
1 parent 81760f2 commit e217084

File tree

8 files changed

+95
-3
lines changed

8 files changed

+95
-3
lines changed

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ The library is organized into several modules, each targeting specific areas of
2424
## Features
2525

2626
Planned features and models under development:
27-
28-
- **Rough Heston Model**: Combines the Heston model with rough volatility, capturing the fine structure of volatility movements.
29-
- **Hull-White Model**: An interest rate model with time-dependent parameters, providing a good fit to initial term structures.
3027
- **Barndorff-Nielsen & Shephard Model**: A stochastic volatility model with non-Gaussian Ornstein-Uhlenbeck processes.
3128
- **Multi-factor CIR Model**: Extends the CIR model to multiple factors, providing greater flexibility in interest rate modeling.
3229
- **Brace-Gatarek-Musiela (BGM) Model**: A market model for interest rates, modeling the evolution of forward rates.

src/stochastic.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,28 @@ pub trait Sampling<T: Clone + Send + Sync + Zero>: Send + Sync {
7171
}
7272
}
7373

74+
pub trait SamplingVector<T: Clone + Send + Sync + Zero>: Send + Sync {
75+
/// Sample the vector process
76+
fn sample(&self) -> Array2<T>;
77+
78+
/// Parallel sampling
79+
fn sample_par(&self) -> Array2<T> {
80+
unimplemented!()
81+
}
82+
83+
/// Number of time steps
84+
fn n(&self) -> usize;
85+
86+
/// Number of samples for parallel sampling
87+
fn m(&self) -> Option<usize>;
88+
89+
/// Malliavin derivative of the process
90+
#[cfg(feature = "malliavin")]
91+
fn malliavin(&self) -> Array1<T> {
92+
unimplemented!()
93+
}
94+
}
95+
7496
pub trait Sampling2D<T: Clone + Send + Sync + Zero>: Send + Sync {
7597
/// Sample the process
7698
fn sample(&self) -> [Array1<T>; 2];

src/stochastic/interest.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
pub mod adg;
2+
pub mod bgm;
13
pub mod cir;
4+
pub mod cir_2f;
25
pub mod duffie_kan;
36
pub mod fvasicek;
47
pub mod ho_lee;
58
pub mod hull_white;
69
pub mod hull_white_2f;
10+
pub mod mod_duffie_kan;
711
pub mod vasicek;
12+
pub mod wu_zhang;

src/stochastic/interest/adg.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use impl_new_derive::ImplNew;
2+
use ndarray::{Array1, Array2};
3+
use ndarray_rand::RandomExt;
4+
use rand_distr::Normal;
5+
6+
use crate::stochastic::SamplingVector;
7+
8+
/// Ahn-Dittmar-Gallant (ADG) model
9+
///
10+
#[derive(ImplNew)]
11+
pub struct ADG {
12+
pub k: fn(f64) -> f64,
13+
pub theta: fn(f64) -> f64,
14+
pub sigma: Array1<f64>,
15+
pub phi: fn(f64) -> f64,
16+
pub b: fn(f64) -> f64,
17+
pub c: fn(f64) -> f64,
18+
pub n: usize,
19+
pub xn: usize,
20+
pub x0: Array1<f64>,
21+
pub t: Option<f64>,
22+
pub m: Option<usize>,
23+
}
24+
25+
impl SamplingVector<f64> for ADG {
26+
fn sample(&self) -> Array2<f64> {
27+
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;
28+
29+
let mut adg = Array2::<f64>::zeros((self.xn, self.n));
30+
for i in 0..self.xn {
31+
adg[(i, 0)] = self.x0[i];
32+
}
33+
34+
for i in 0..self.xn {
35+
let gn = Array1::random(self.n, Normal::new(0.0, dt.sqrt()).unwrap());
36+
37+
for j in 1..self.n {
38+
let t = j as f64 * dt;
39+
adg[(i, j)] = adg[(i, j - 1)]
40+
+ ((self.k)(t) - (self.theta)(t) * adg[(i, j - 1)]) * dt
41+
+ self.sigma[i] * gn[j - 1];
42+
}
43+
}
44+
45+
let mut r = Array2::zeros((self.xn, self.n));
46+
47+
for i in 0..self.xn {
48+
let phi = Array1::<f64>::from_shape_fn(self.n, |j| (self.phi)(j as f64 * dt));
49+
let b = Array1::<f64>::from_shape_fn(self.n, |j| (self.b)(j as f64 * dt));
50+
let c = Array1::<f64>::from_shape_fn(self.n, |j| (self.c)(j as f64 * dt));
51+
52+
r.row_mut(i)
53+
.assign(&(phi + b * adg.row(i).t().to_owned() * c * adg.row(i)));
54+
}
55+
56+
r
57+
}
58+
59+
/// Number of time steps
60+
fn n(&self) -> usize {
61+
self.n
62+
}
63+
64+
/// Number of samples for parallel sampling
65+
fn m(&self) -> Option<usize> {
66+
self.m
67+
}
68+
}

src/stochastic/interest/bgm.rs

Whitespace-only changes.

src/stochastic/interest/cir_2f.rs

Whitespace-only changes.

src/stochastic/interest/mod_duffie_kan.rs

Whitespace-only changes.

src/stochastic/interest/wu_zhang.rs

Whitespace-only changes.

0 commit comments

Comments
 (0)