#![deny(missing_docs)]
use crate::{
ad::scalar::Scalar,
core::marketdatahandling::{
discountrequest::DiscountRequest, forwardraterequest::ForwardRateRequest,
fxrequest::FxRequest, pathdependentrequest::PathDependentRequest, spotrequest::SpotRequest,
},
time::date::Date,
utils::errors::Result,
xva::visitors::preprocessorexecutor::SimulationRequest,
};
pub type PathScenario<T> = Vec<Vec<SimulationResponse<T>>>;
pub struct SimulationResponse<T: Scalar> {
pub discounts: Option<T>,
pub forward_rates: Option<T>,
pub fx_rates: Option<T>,
pub spots: Option<T>,
pub path_dependent_observations: Option<T>,
pub numeraire: Option<T>,
}
impl<T: Scalar> Default for SimulationResponse<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> SimulationResponse<T>
where
T: Scalar,
{
#[must_use]
pub const fn new() -> Self {
Self {
discounts: None,
forward_rates: None,
fx_rates: None,
spots: None,
path_dependent_observations: None,
numeraire: None,
}
}
}
pub trait MarketModel<T: Scalar>: Send + Sync {
fn n_paths(&self) -> usize;
fn generate_path(&self, index: usize) -> Option<PathScenario<T>>;
fn set_evaluation_dates(&mut self, dates: Vec<Date>);
fn set_requests(&mut self, requests: Vec<SimulationRequest>);
fn set_request_dates(&mut self, _request_dates: Vec<Option<Date>>) {}
fn uses_compact_dated_requests(&self) -> bool {
false
}
fn resolve_request(
&self,
eval_date: Date,
request: &SimulationRequest,
) -> Result<SimulationResponse<T>> {
let mut response = SimulationResponse::new();
match &request.forward_rate_request {
Some(req) => {
let rate = self.resolve_forward_rate_request(eval_date, req)?;
response.forward_rates = Some(rate);
}
None => response.forward_rates = None,
}
match &request.fx_request {
Some(req) => {
let rate = self.resolve_fx_request(eval_date, req)?;
response.fx_rates = Some(rate);
}
None => response.fx_rates = None,
}
match &request.spot_request {
Some(req) => {
let spot = self.resolve_spot_request(eval_date, req)?;
response.spots = Some(spot);
}
None => response.spots = None,
}
match &request.path_dependent_request {
Some(req) => {
let obs = self.resolve_path_dependent_request(eval_date, req)?;
response.path_dependent_observations = Some(obs);
}
None => response.path_dependent_observations = None,
}
Ok(response)
}
fn resolve_discount_request(&self, eval_date: Date, request: &DiscountRequest) -> Result<T>;
fn resolve_forward_rate_request(
&self,
eval_date: Date,
request: &ForwardRateRequest,
) -> Result<T>;
fn resolve_fx_request(&self, eval_date: Date, request: &FxRequest) -> Result<T>;
fn resolve_spot_request(&self, eval_date: Date, request: &SpotRequest) -> Result<T>;
fn resolve_path_dependent_request(
&self,
eval_date: Date,
request: &PathDependentRequest,
) -> Result<T>;
}