use crate::{
ad::{dual::DualFwd, scalar::Scalar},
core::{
collateral::Discountable,
instrument::{AssetClass, Instrument},
request::LegsProvider,
trade::{Side, Trade},
},
currencies::currency::Currency,
indices::marketindex::MarketIndex,
instruments::cashflows::leg::Leg,
rates::interestrate::InterestRate,
time::date::Date,
};
#[derive(Clone)]
pub struct FixedRateDeposit<T: Scalar> {
identifier: String,
units: f64,
leg: Leg<T>,
discount_index: Option<MarketIndex>,
start_date: Date,
maturity_date: Date,
currency: Currency,
}
impl<T> FixedRateDeposit<T>
where
T: Scalar,
{
#[must_use]
pub const fn new(
identifier: String,
units: f64,
leg: Leg<T>,
discount_index: Option<MarketIndex>,
start_date: Date,
maturity_date: Date,
currency: Currency,
) -> Self {
Self {
identifier,
units,
leg,
discount_index,
start_date,
maturity_date,
currency,
}
}
#[must_use]
pub const fn units(&self) -> f64 {
self.units
}
#[must_use]
pub const fn rate(&self) -> Option<InterestRate<T>> {
self.leg.interest_rate()
}
#[must_use]
pub const fn leg(&self) -> &Leg<T> {
&self.leg
}
#[must_use]
pub const fn start_date(&self) -> Date {
self.start_date
}
#[must_use]
pub const fn maturity_date(&self) -> Date {
self.maturity_date
}
}
impl<T> Discountable for FixedRateDeposit<T>
where
T: Scalar,
{
fn currency(&self) -> Currency {
self.currency
}
fn asset_class(&self) -> AssetClass {
AssetClass::FixedIncome
}
fn discount_index(&self) -> Option<MarketIndex> {
self.discount_index.clone()
}
}
impl<T> Instrument for FixedRateDeposit<T>
where
T: Scalar,
{
fn identifier(&self) -> String {
self.identifier.clone()
}
}
impl<T> LegsProvider<T> for FixedRateDeposit<T>
where
T: Scalar,
{
fn legs(&self) -> &[Leg<T>] {
std::slice::from_ref(&self.leg)
}
}
pub struct FixedRateDepositTrade<T: Scalar> {
instrument: FixedRateDeposit<T>,
trade_date: Date,
notional: f64,
side: Side,
}
impl<T> LegsProvider<T> for FixedRateDepositTrade<T>
where
T: Scalar,
{
fn legs(&self) -> &[Leg<T>] {
self.instrument.legs()
}
}
impl<T> FixedRateDepositTrade<T>
where
T: Scalar,
{
#[must_use]
pub const fn new(
instrument: FixedRateDeposit<T>,
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<T> Trade<FixedRateDeposit<T>> for FixedRateDepositTrade<T>
where
T: Scalar,
{
fn instrument(&self) -> &FixedRateDeposit<T> {
&self.instrument
}
fn trade_date(&self) -> Date {
self.trade_date
}
fn side(&self) -> Side {
self.side
}
}
impl From<FixedRateDeposit<f64>> for FixedRateDeposit<DualFwd> {
fn from(value: FixedRateDeposit<f64>) -> Self {
Self::new(
value.identifier,
value.units,
value.leg.into(),
value.discount_index,
value.start_date,
value.maturity_date,
value.currency,
)
}
}
impl From<FixedRateDeposit<DualFwd>> for FixedRateDeposit<f64> {
fn from(value: FixedRateDeposit<DualFwd>) -> Self {
Self::new(
value.identifier,
value.units,
value.leg.into(),
value.discount_index,
value.start_date,
value.maturity_date,
value.currency,
)
}
}
impl From<FixedRateDepositTrade<f64>> for FixedRateDepositTrade<DualFwd> {
fn from(value: FixedRateDepositTrade<f64>) -> Self {
Self::new(
value.instrument.into(),
value.trade_date,
value.notional,
value.side,
)
}
}
impl From<FixedRateDepositTrade<DualFwd>> for FixedRateDepositTrade<f64> {
fn from(value: FixedRateDepositTrade<DualFwd>) -> Self {
Self::new(
value.instrument.into(),
value.trade_date,
value.notional,
value.side,
)
}
}