use crate::discretizedasset::{DiscretizedAsset, DiscretizedAssetBase, DiscretizedOption};
use crate::errors::QlResult;
use crate::fail;
use crate::instruments::SwaptionArguments;
use crate::settings::Settings;
use crate::shared::{SharedMut, shared_mut};
use crate::time::date::Date;
use crate::time::daycounter::DayCounter;
use crate::types::{Size, Time};
use super::DiscretizedSwap;
pub struct DiscretizedSwaption {
option: DiscretizedOption,
last_payment: Time,
}
impl DiscretizedSwaption {
pub fn new(
args: &SwaptionArguments,
reference_date: Date,
day_counter: &DayCounter,
settings: &Settings<Date>,
) -> QlResult<Self> {
let Some(exercise) = args.exercise.as_ref() else {
fail!("exercise not set");
};
let swap_args = &args.swap_arguments;
let exercise_times: Vec<Time> = exercise
.dates()
.iter()
.map(|&date| day_counter.year_fraction(reference_date, date))
.collect();
let exercise_type = exercise.exercise_type();
let Some(&last_fixed_date) = swap_args.fixed_pay_dates.last() else {
fail!("swap has no fixed coupons");
};
let Some(&last_floating_date) = swap_args.floating_pay_dates.last() else {
fail!("swap has no floating coupons");
};
let last_fixed = day_counter.year_fraction(reference_date, last_fixed_date);
let last_floating = day_counter.year_fraction(reference_date, last_floating_date);
let last_payment = last_fixed.max(last_floating);
let swap = DiscretizedSwap::new(swap_args, reference_date, day_counter, settings)?;
let underlying: SharedMut<dyn DiscretizedAsset> = shared_mut(swap);
let option = DiscretizedOption::new(underlying, exercise_type, exercise_times);
Ok(DiscretizedSwaption {
option,
last_payment,
})
}
}
impl DiscretizedAsset for DiscretizedSwaption {
fn base(&self) -> &DiscretizedAssetBase {
self.option.base()
}
fn base_mut(&mut self) -> &mut DiscretizedAssetBase {
self.option.base_mut()
}
fn as_asset_mut(&mut self) -> &mut dyn DiscretizedAsset {
self
}
fn reset(&mut self, size: Size) -> QlResult<()> {
let method = self.require_method()?;
let underlying = SharedMut::clone(self.option.underlying());
underlying
.borrow_mut()
.initialize(method, self.last_payment)?;
self.option.reset(size)
}
fn mandatory_times(&self) -> Vec<Time> {
self.option.mandatory_times()
}
fn pre_adjust_values_impl(&mut self) -> QlResult<()> {
self.option.pre_adjust_values_impl()
}
fn post_adjust_values_impl(&mut self) -> QlResult<()> {
self.option.post_adjust_values_impl()
}
}