-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
31 changed files
with
1,050 additions
and
910 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use ndarray::Array1; | ||
|
||
use crate::{noises::fgn::FgnFft, utils::Generator}; | ||
|
||
/// Generates a path of the fractional Cox-Ingersoll-Ross (fCIR) process. | ||
/// | ||
/// The fCIR process incorporates fractional Brownian motion, which introduces long-range dependence. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `hurst`: Hurst parameter for fractional Brownian motion, must be in (0, 1). | ||
/// - `theta`: Speed of mean reversion. | ||
/// - `mu`: Long-term mean level. | ||
/// - `sigma`: Volatility parameter. | ||
/// - `n`: Number of time steps. | ||
/// - `x0`: Initial value of the process (optional, defaults to 0.0). | ||
/// - `t`: Total time (optional, defaults to 1.0). | ||
/// - `use_sym`: Whether to use symmetric noise (optional, defaults to false). | ||
/// | ||
/// # Returns | ||
/// | ||
/// A `Array1<f64>` representing the generated fCIR process path. | ||
/// | ||
/// # Panics | ||
/// | ||
/// Panics if `hurst` is not in (0, 1). | ||
/// Panics if `2 * theta * mu < sigma^2`. | ||
/// | ||
/// # Example | ||
/// | ||
/// ``` | ||
/// let fcir_path = fcir(0.75, 0.5, 0.02, 0.1, 1000, Some(0.01), Some(1.0), Some(false)); | ||
/// ``` | ||
#[derive(Default)] | ||
pub struct Fcir { | ||
pub hurst: f64, | ||
pub theta: f64, | ||
pub mu: f64, | ||
pub sigma: f64, | ||
pub n: usize, | ||
pub x0: Option<f64>, | ||
pub t: Option<f64>, | ||
pub use_sym: Option<bool>, | ||
} | ||
|
||
pub fn fcir(params: &Fcir) -> Array1<f64> { | ||
let Fcir { | ||
hurst, | ||
theta, | ||
mu, | ||
sigma, | ||
n, | ||
x0, | ||
t, | ||
use_sym, | ||
} = *params; | ||
|
||
assert!( | ||
hurst > 0.0 && hurst < 1.0, | ||
"Hurst parameter must be in (0, 1)" | ||
); | ||
assert!(2.0 * theta * mu < sigma.powi(2), "2 * theta * mu < sigma^2"); | ||
|
||
let fgn = FgnFft::new(hurst, n - 1, t, None).sample(); | ||
let dt = t.unwrap_or(1.0) / n as f64; | ||
|
||
let mut fcir = Array1::<f64>::zeros(n); | ||
fcir[0] = x0.unwrap_or(0.0); | ||
|
||
for i in 1..n { | ||
let random = match use_sym.unwrap_or(false) { | ||
true => sigma * (fcir[i - 1]).abs().sqrt() * fgn[i - 1], | ||
false => sigma * (fcir[i - 1]).max(0.0) * fgn[i - 1], | ||
}; | ||
fcir[i] = fcir[i - 1] + theta * (mu - fcir[i - 1]) * dt + random | ||
} | ||
|
||
fcir | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
use ndarray::Array1; | ||
|
||
use crate::{noises::fgn::FgnFft, utils::Generator}; | ||
|
||
/// Generates a path of the fractional Geometric Brownian Motion (fGBM) process. | ||
/// | ||
/// The fGBM process incorporates fractional Brownian motion, which introduces long-range dependence. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `hurst`: Hurst parameter for fractional Brownian motion, must be in (0, 1). | ||
/// - `mu`: Drift parameter. | ||
/// - `sigma`: Volatility parameter. | ||
/// - `n`: Number of time steps. | ||
/// - `x0`: Initial value of the process (optional, defaults to 100.0). | ||
/// - `t`: Total time (optional, defaults to 1.0). | ||
/// | ||
/// # Returns | ||
/// | ||
/// A `Array1<f64>` representing the generated fGBM process path. | ||
/// | ||
/// # Panics | ||
/// | ||
/// Panics if `hurst` is not in (0, 1). | ||
/// | ||
/// # Example | ||
/// | ||
/// ``` | ||
/// let fgbm_path = fgbm(0.75, 0.05, 0.2, 1000, Some(100.0), Some(1.0)); | ||
/// ``` | ||
#[derive(Default)] | ||
pub struct Fgbm { | ||
pub hurst: f64, | ||
pub mu: f64, | ||
pub sigma: f64, | ||
pub n: usize, | ||
pub x0: Option<f64>, | ||
pub t: Option<f64>, | ||
} | ||
|
||
pub fn fgbm(params: &Fgbm) -> Array1<f64> { | ||
let Fgbm { | ||
hurst, | ||
mu, | ||
sigma, | ||
n, | ||
x0, | ||
t, | ||
} = *params; | ||
|
||
assert!( | ||
hurst > 0.0 && hurst < 1.0, | ||
"Hurst parameter must be in (0, 1)" | ||
); | ||
|
||
let fgn = FgnFft::new(hurst, n - 1, t, None).sample(); | ||
let dt = t.unwrap_or(1.0) / n as f64; | ||
|
||
let mut fgbm = Array1::<f64>::zeros(n); | ||
fgbm[0] = x0.unwrap_or(100.0); | ||
|
||
for i in 1..n { | ||
fgbm[i] = fgbm[i - 1] + mu * fgbm[i - 1] * dt + sigma * fgbm[i - 1] * fgn[i - 1] | ||
} | ||
|
||
fgbm | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
use ndarray::Array1; | ||
|
||
use crate::{noises::fgn::FgnFft, utils::Generator}; | ||
|
||
/// Generates a path of the fractional Jacobi (fJacobi) process. | ||
/// | ||
/// The fJacobi process incorporates fractional Brownian motion, which introduces long-range dependence. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `hurst`: Hurst parameter for fractional Brownian motion, must be in (0, 1). | ||
/// - `alpha`: Speed of mean reversion. | ||
/// - `beta`: Long-term mean level. | ||
/// - `sigma`: Volatility parameter. | ||
/// - `n`: Number of time steps. | ||
/// - `x0`: Initial value of the process (optional, defaults to 0.0). | ||
/// - `t`: Total time (optional, defaults to 1.0). | ||
/// | ||
/// # Returns | ||
/// | ||
/// A `Array1<f64>` representing the generated fJacobi process path. | ||
/// | ||
/// # Panics | ||
/// | ||
/// Panics if `hurst` is not in (0, 1). | ||
/// Panics if `alpha`, `beta`, or `sigma` are not positive. | ||
/// Panics if `alpha` is greater than `beta`. | ||
/// | ||
/// # Example | ||
/// | ||
/// ``` | ||
/// let fjacobi_path = fjacobi(0.75, 0.5, 1.0, 0.2, 1000, Some(0.5), Some(1.0)); | ||
/// ``` | ||
#[derive(Default)] | ||
pub struct Fjacobi { | ||
pub hurst: f64, | ||
pub alpha: f64, | ||
pub beta: f64, | ||
pub sigma: f64, | ||
pub n: usize, | ||
pub x0: Option<f64>, | ||
pub t: Option<f64>, | ||
} | ||
|
||
pub fn fjacobi(params: &Fjacobi) -> Array1<f64> { | ||
let Fjacobi { | ||
hurst, | ||
alpha, | ||
beta, | ||
sigma, | ||
n, | ||
x0, | ||
t, | ||
} = *params; | ||
|
||
assert!( | ||
hurst > 0.0 && hurst < 1.0, | ||
"Hurst parameter must be in (0, 1)" | ||
); | ||
assert!(alpha > 0.0, "alpha must be positive"); | ||
assert!(beta > 0.0, "beta must be positive"); | ||
assert!(sigma > 0.0, "sigma must be positive"); | ||
assert!(alpha < beta, "alpha must be less than beta"); | ||
|
||
let fgn = FgnFft::new(hurst, n - 1, t, None).sample(); | ||
let dt = t.unwrap_or(1.0) / n as f64; | ||
|
||
let mut fjacobi = Array1::<f64>::zeros(n); | ||
fjacobi[0] = x0.unwrap_or(0.0); | ||
|
||
for i in 1..n { | ||
fjacobi[i] = match fjacobi[i - 1] { | ||
_ if fjacobi[i - 1] <= 0.0 && i > 0 => 0.0, | ||
_ if fjacobi[i - 1] >= 1.0 && i > 0 => 1.0, | ||
_ => { | ||
fjacobi[i - 1] | ||
+ (alpha - beta * fjacobi[i - 1]) * dt | ||
+ sigma * (fjacobi[i - 1] * (1.0 - fjacobi[i - 1])).sqrt() * fgn[i - 1] | ||
} | ||
} | ||
} | ||
|
||
fjacobi | ||
} |
Oops, something went wrong.