use serde::{Deserialize, Serialize};
use crate::{
core::{
collateral::HasCurrency,
instrument::{AssetClass, Instrument},
trade::{Side, Trade},
},
currencies::currency::Currency,
indices::marketindex::MarketIndex,
rates::interestrate::RateDefinition,
time::date::Date,
volatility::volatilityindexing::Strike,
};
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum CapletFloorletType {
Caplet,
Floorlet,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CapletFloorlet {
name: String,
market_index: MarketIndex,
currency: Currency,
start_date: Date,
end_date: Date,
payment_date: Date,
option_type: CapletFloorletType,
strike: Strike,
rate_definition: RateDefinition,
}
impl CapletFloorlet {
#[must_use]
#[allow(clippy::too_many_arguments)]
pub const fn new(
name: String,
market_index: MarketIndex,
currency: Currency,
start_date: Date,
end_date: Date,
payment_date: Date,
option_type: CapletFloorletType,
strike: Strike,
rate_definition: RateDefinition,
) -> Self {
Self {
name,
market_index,
currency,
start_date,
end_date,
payment_date,
option_type,
strike,
rate_definition,
}
}
#[must_use]
pub fn market_index(&self) -> MarketIndex {
self.market_index.clone()
}
#[must_use]
pub const fn start_date(&self) -> Date {
self.start_date
}
#[must_use]
pub const fn end_date(&self) -> Date {
self.end_date
}
#[must_use]
pub const fn payment_date(&self) -> Date {
self.payment_date
}
#[must_use]
pub const fn option_type(&self) -> CapletFloorletType {
self.option_type
}
#[must_use]
pub const fn strike(&self) -> Strike {
self.strike
}
#[must_use]
pub const fn rate_definition(&self) -> RateDefinition {
self.rate_definition
}
#[must_use]
pub fn accrual_factor(&self) -> f64 {
self.rate_definition
.day_counter()
.year_fraction(self.start_date, self.end_date)
}
}
impl HasCurrency for CapletFloorlet {
fn currency(&self) -> Currency {
self.currency
}
}
impl Instrument for CapletFloorlet {
fn identifier(&self) -> String {
self.name.clone()
}
fn asset_class(&self) -> AssetClass {
AssetClass::InterestRate
}
}
#[derive(Clone)]
pub struct CapletFloorletTrade {
instrument: CapletFloorlet,
trade_date: Date,
notional: f64,
side: Side,
}
impl CapletFloorletTrade {
#[must_use]
pub const fn new(
instrument: CapletFloorlet,
trade_date: Date,
notional: f64,
side: Side,
) -> Self {
Self {
instrument,
trade_date,
notional,
side,
}
}
#[must_use]
pub const fn notional(&self) -> f64 {
self.notional
}
}
impl Trade<CapletFloorlet> for CapletFloorletTrade {
fn instrument(&self) -> &CapletFloorlet {
&self.instrument
}
fn trade_date(&self) -> Date {
self.trade_date
}
fn side(&self) -> Side {
self.side
}
}