#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DayCount {
Act365F,
Act365,
Act360,
Thirty360US,
Thirty360E,
ActActISDA,
ActActICMA,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CashFlowType {
Coupon,
Principal,
CallPayment,
Other,
}
#[derive(Debug, Clone)]
pub enum BondPricingError {
InvalidYield(f64),
SettlementAfterMaturity {
settlement: chrono::NaiveDate,
maturity: chrono::NaiveDate,
},
InvalidFrequency(u32),
NegativeInput(String),
ScheduleGenerationError(String),
CalculationError(String),
InvalidDayCount,
MissingParameter(String),
}
impl std::fmt::Display for BondPricingError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BondPricingError::InvalidYield(ytm) => {
write!(f, "Invalid yield to maturity: {ytm}")
}
BondPricingError::SettlementAfterMaturity {
settlement,
maturity,
} => {
write!(
f,
"Settlement date ({settlement}) must be before maturity date ({maturity})"
)
}
BondPricingError::InvalidFrequency(freq) => {
write!(
f,
"Invalid coupon frequency: {freq}. Must be 1, 2, 4, or 12"
)
}
BondPricingError::NegativeInput(param) => {
write!(f, "Negative input not allowed for: {param}")
}
BondPricingError::ScheduleGenerationError(msg) => {
write!(f, "Schedule generation error: {msg}")
}
BondPricingError::CalculationError(msg) => {
write!(f, "Calculation error: {msg}")
}
BondPricingError::InvalidDayCount => {
write!(f, "Invalid day count convention")
}
BondPricingError::MissingParameter(param) => {
write!(f, "Missing required parameter: {param}")
}
}
}
}
impl std::error::Error for BondPricingError {}
impl BondPricingError {
pub fn invalid_yield(ytm: f64) -> Self {
Self::InvalidYield(ytm)
}
pub fn settlement_after_maturity(
settlement: chrono::NaiveDate,
maturity: chrono::NaiveDate,
) -> Self {
Self::SettlementAfterMaturity {
settlement,
maturity,
}
}
pub fn negative_input(param: &str) -> Self {
Self::NegativeInput(param.to_string())
}
}