use super::bsm::Option;
use crate::stochastics::gbm::{GeoBrown, Stochastic};
extern crate nalgebra as na;
use crate::tools::tool;
use na::*;
use rand::thread_rng;
use rand_distr::{Distribution, Normal, NormalError};
use rayon::prelude::*;
use std::cmp;
extern crate docify;
fn init_standart_arr(n: usize) -> Vec<f64> {
let mut res = Vec::new();
for i in 0..n {
let v = tool::random_from_stdnorm();
res.push(v);
}
res
}
#[doc = docify::embed!("src/option_price/mont_carlo.rs", test_mont)]
impl Option {
fn geo_brown(&self, sigma: f64, steps: usize) -> GeoBrown {
let geo = GeoBrown {
S0: self.S,
T: self.T,
steps: steps,
sigma: sigma,
mu: self.r - self.divdend - sigma.powf(2.0) / 2.0,
};
geo
}
pub fn mont_price(&self, sigma: f64, steps: usize, sample_size: usize) -> f64 {
let geo = self.geo_brown(sigma, steps);
let price: Vec<f64> = (0..sample_size)
.into_par_iter()
.map(|i| -> f64 {
let simu = geo.gen_path();
let vv = if self.is_call {
simu[steps - 1] - self.K
} else {
self.K - simu[steps - 1]
};
let v = if vv > 0.0 { vv } else { 0.0 };
v
})
.collect();
let mean = price.iter().sum::<f64>() / price.len() as f64;
mean
}
pub fn asia_price(&self, sigma: f64, steps: usize, sample_size: usize) -> f64 {
let geo = self.geo_brown(sigma, steps);
let price: Vec<f64> = (0..sample_size)
.into_par_iter()
.map(|i| -> f64 {
let simu = geo.gen_path();
let av = simu.iter().sum::<f64>() / simu.len() as f64;
let vv = if self.is_call {
av - self.K
} else {
self.K - av
};
let v = if vv > 0.0 { vv } else { 0.0 };
v
})
.collect();
let mean = price.iter().sum::<f64>() / price.len() as f64;
mean
}
pub fn lookback_price(&self, sigma: f64, steps: usize, sample_size: usize) -> f64 {
let geo = self.geo_brown(sigma, steps);
let price: Vec<f64> = (0..sample_size)
.into_par_iter()
.map(|i| -> f64 {
let simu = geo.gen_path();
let mx = simu.iter().max_by(|a, b| a.total_cmp(b)).unwrap();
let vv = if self.is_call {
mx - self.K
} else {
self.K - mx
};
let v = if vv > 0.0 { vv } else { 0.0 };
v
})
.collect();
let mean = price.iter().sum::<f64>() / price.len() as f64;
mean
}
}
#[test]
#[docify::export]
fn test_mont() {
let op = Option {
is_call: true,
S: 217.36, K: 220.0, T: 13.0 / 365.0,
divdend: 0.44 / 100.0, r: 4.62 / 100.0, };
let vol = 35.23 / 100.0;
let a = op.mont_price(vol, 14, 100);
}