use crate::{
core::marketdatahandling::{
discountrequest::DiscountRequest, forwardraterequest::ForwardRateRequest,
fxrequest::FxRequest, pathdependentrequest::PathDependentRequest,
spotrequest::SpotRequest,
},
xva::nettingset::NettingSet,
};
use super::{
claimcompressionpreprocessor::ClaimCompressionPreprocessor,
claimpreprocessor::ClaimPreprocessor,
};
#[derive(Default, Clone)]
pub struct SimulationRequest {
pub discount_request: Option<DiscountRequest>,
pub forward_rate_request: Option<ForwardRateRequest>,
pub fx_request: Option<FxRequest>,
pub spot_request: Option<SpotRequest>,
pub path_dependent_request: Option<PathDependentRequest>,
}
pub struct PreprocessorExecutor {
requests: Vec<SimulationRequest>,
preprocessors: Vec<Box<dyn ClaimPreprocessor>>,
compress: bool,
}
impl Default for PreprocessorExecutor {
fn default() -> Self {
Self::new()
}
}
impl PreprocessorExecutor {
#[must_use]
pub fn new() -> Self {
Self {
requests: Vec::new(),
preprocessors: Vec::new(),
compress: false,
}
}
#[must_use]
pub fn with_preprocessor(mut self, preprocessor: Box<dyn ClaimPreprocessor>) -> Self {
self.preprocessors.push(preprocessor);
self
}
#[must_use]
pub const fn with_compression(mut self) -> Self {
self.compress = true;
self
}
pub fn visit<'a>(&mut self, netting_sets: impl IntoIterator<Item = &'a mut NettingSet>) {
self.requests.clear();
let mut global_idx = 0;
for ns in netting_sets {
for claim in ns.claims_mut() {
for pp in &self.preprocessors {
pp.process(claim);
}
}
if self.compress {
ClaimCompressionPreprocessor::compress(ns.claims_vec_mut());
}
let (policy, claims) = ns.discount_policy_and_claims_mut();
for claim in claims {
let mut request = claim.simulation_request();
if let Ok(discount_index) = policy.accept(claim) {
request.discount_request =
Some(DiscountRequest::new(discount_index, claim.payment_date()));
}
claim.set_idx(global_idx);
self.requests.push(request);
global_idx += 1;
}
}
}
#[must_use]
pub fn requests(&self) -> &[SimulationRequest] {
&self.requests
}
}