use std::collections::HashMap;
use crate::{
core::trade::Side,
currencies::currency::Currency,
time::date::Date,
xva::{claimevaluationstrategy::ClaimEvaluationStrategy, contigentclaim::ContingentClaim},
};
pub struct ClaimCompressionPreprocessor;
impl ClaimCompressionPreprocessor {
pub fn compress(claims: &mut Vec<ContingentClaim>) {
type Key = (Date, Currency, Option<Currency>);
let mut deterministic: Vec<ContingentClaim> = Vec::new();
let mut others: Vec<ContingentClaim> = Vec::new();
for claim in claims.drain(..) {
if matches!(
claim.evaluation_strategy(),
ClaimEvaluationStrategy::Deterministic { .. }
) {
deterministic.push(claim);
} else {
others.push(claim);
}
}
let mut groups: HashMap<Key, Vec<ContingentClaim>> = HashMap::new();
for claim in deterministic {
let key = (
claim.payment_date(),
claim.currency(),
claim.foreign_currency(),
);
groups.entry(key).or_default().push(claim);
}
for ((payment_date, currency, foreign_currency), group) in groups {
if group.len() == 1 {
claims.extend(group);
} else {
let mut effective = 0.0_f64;
for c in &group {
if let ClaimEvaluationStrategy::Deterministic { amount } =
c.evaluation_strategy()
{
effective += c.notional() * c.side().sign() * amount;
}
}
let merged = ContingentClaim::new(
"compressed".to_string(),
0,
payment_date,
None,
None,
None,
currency,
foreign_currency,
1.0,
Side::LongReceive,
ClaimEvaluationStrategy::Deterministic { amount: effective },
None,
);
claims.push(merged);
}
}
claims.extend(others);
}
}