ledger_models/fintekkers/wrappers/models/
floating_rate_note.rs1use chrono::{Datelike, NaiveDate};
8use rust_decimal::Decimal;
9
10use crate::fintekkers::models::security::index::IndexTypeProto;
11use crate::fintekkers::models::security::{
12 BondDetailsProto, CouponFrequencyProto, CouponTypeProto, FrnExtensionProto,
13 ProductTypeProto, SecurityProto,
14};
15use crate::fintekkers::models::util::{DecimalValueProto, LocalDateProto};
16use crate::fintekkers::wrappers::models::utils::errors::Error;
17use crate::fintekkers::wrappers::models::utils::serialization::ProtoSerializationUtil;
18
19pub struct FloatingRateNote {
20 pub proto: SecurityProto,
21}
22
23impl FloatingRateNote {
24 pub fn from_proto(proto: SecurityProto) -> Result<Self, Error> {
25 let pt = ProductTypeProto::from_i32(proto.product_type)
26 .unwrap_or(ProductTypeProto::ProductTypeUnknown);
27 if pt == ProductTypeProto::TreasuryFrn {
28 Ok(FloatingRateNote { proto })
29 } else {
30 Err(Error::NotABondSecurity)
31 }
32 }
33
34 pub fn spread(&self) -> Option<Decimal> {
35 self.proto
36 .frn_extension
37 .as_ref()
38 .and_then(|f| f.spread.as_ref())
39 .and_then(|d| ProtoSerializationUtil::deserialize_decimal(d).ok())
40 }
41
42 pub fn reference_rate_index(&self) -> IndexTypeProto {
43 self.proto
44 .frn_extension
45 .as_ref()
46 .and_then(|f| IndexTypeProto::from_i32(f.reference_rate_index))
47 .unwrap_or(IndexTypeProto::UnknownIndexType)
48 }
49
50 pub fn reset_frequency(&self) -> CouponFrequencyProto {
51 self.proto
52 .frn_extension
53 .as_ref()
54 .and_then(|f| CouponFrequencyProto::from_i32(f.reset_frequency))
55 .unwrap_or(CouponFrequencyProto::UnknownCouponFrequency)
56 }
57
58 pub fn from_pricer_inputs(
59 face_value: Decimal,
60 coupon_rate: Decimal,
61 coupon_type: CouponTypeProto,
62 coupon_frequency: CouponFrequencyProto,
63 issue_date: NaiveDate,
64 maturity_date: NaiveDate,
65 spread: Decimal,
66 reference_rate_index: IndexTypeProto,
67 reset_frequency: CouponFrequencyProto,
68 ) -> SecurityProto {
69 SecurityProto {
70 product_type: ProductTypeProto::TreasuryFrn as i32,
71 bond_details: Some(BondDetailsProto {
72 coupon_rate: Some(decimal_proto(coupon_rate)),
73 coupon_type: coupon_type as i32,
74 coupon_frequency: coupon_frequency as i32,
75 face_value: Some(decimal_proto(face_value)),
76 issue_date: Some(date_proto(issue_date)),
77 dated_date: None,
78 maturity_date: Some(date_proto(maturity_date)),
79 issuance_info: vec![],
80 }),
81 frn_extension: Some(FrnExtensionProto {
82 spread: Some(decimal_proto(spread)),
83 reference_rate_index: reference_rate_index as i32,
84 reset_frequency: reset_frequency as i32,
85 }),
86 ..Default::default()
87 }
88 }
89}
90
91fn decimal_proto(d: Decimal) -> DecimalValueProto {
92 DecimalValueProto {
93 arbitrary_precision_value: d.to_string(),
94 }
95}
96
97fn date_proto(d: NaiveDate) -> LocalDateProto {
98 LocalDateProto {
99 year: d.year() as u32,
100 month: d.month(),
101 day: d.day(),
102 }
103}