Shared Rust kernels
ported/discount_bill_yearfrac_family
All modules · quoted at commit 9e1884369a67 of DnaCalc/DnaCalc. Comments are the source's own.
max_excel_serial · 3 lines · calc-func/src/ported/discount_bill_yearfrac_family.rs on GitHubfn max_excel_serial() -> i64 {
excel_serial_from_ymd(WorkbookDateSystem::System1900, 9999, 12, 31).unwrap() as i64
}
Used by 7 functions.
parse_basis · 17 lines · calc-func/src/ported/discount_bill_yearfrac_family.rs on GitHubfn parse_basis(value: f64) -> Result<DayCountBasis, DiscountBillYearfracEvalError> {
if !value.is_finite() {
return Err(DiscountBillYearfracEvalError::Domain(
WorksheetErrorCode::Num,
));
}
match value.trunc() as i64 {
0 => Ok(DayCountBasis::Us30_360),
1 => Ok(DayCountBasis::ActualActual),
2 => Ok(DayCountBasis::Actual360),
3 => Ok(DayCountBasis::Actual365),
4 => Ok(DayCountBasis::European30_360),
_ => Err(DiscountBillYearfracEvalError::Domain(
WorksheetErrorCode::Num,
)),
}
}
Used by 4 functions.
parse_date_serial · 17 lines · calc-func/src/ported/discount_bill_yearfrac_family.rs on GitHubfn parse_date_serial(value: f64, minimum: i64) -> Result<i64, DiscountBillYearfracEvalError> {
if !value.is_finite() {
return Err(DiscountBillYearfracEvalError::Domain(
WorksheetErrorCode::Value,
));
}
let serial = value.trunc() as i64;
if serial < minimum || serial > max_excel_serial() {
return Err(DiscountBillYearfracEvalError::Domain(
WorksheetErrorCode::Value,
));
}
ymd_from_excel_serial(WorkbookDateSystem::System1900, serial as f64).ok_or(
DiscountBillYearfracEvalError::Domain(WorksheetErrorCode::Value),
)?;
Ok(serial)
}
Used by 7 functions.
actual_days · 3 lines · calc-func/src/ported/discount_bill_yearfrac_family.rs on GitHubfn actual_days(start: i64, end: i64) -> f64 {
(end - start) as f64
}
Used by 7 functions.
days360_us · 4 lines · calc-func/src/ported/discount_bill_yearfrac_family.rs on GitHubfn days360_us(start: i64, end: i64) -> Result<f64, DiscountBillYearfracEvalError> {
crate::ported::day_count_common::us_30_360(start, end)
.map_err(DiscountBillYearfracEvalError::Domain)
}
Used by 4 functions.
days360_eu · 17 lines · calc-func/src/ported/discount_bill_yearfrac_family.rs on GitHubfn days360_eu(start: i64, end: i64) -> Result<f64, DiscountBillYearfracEvalError> {
let (sy, sm, mut sd) = ymd_from_excel_serial(WorkbookDateSystem::System1900, start as f64)
.ok_or(DiscountBillYearfracEvalError::Domain(
WorksheetErrorCode::Value,
))?;
let (ey, em, mut ed) = ymd_from_excel_serial(WorkbookDateSystem::System1900, end as f64)
.ok_or(DiscountBillYearfracEvalError::Domain(
WorksheetErrorCode::Value,
))?;
if sd == 31 {
sd = 30;
}
if ed == 31 {
ed = 30;
}
Ok(((ey - sy) * 360 + (em - sm) * 30 + (ed - sd)) as f64)
}
Used by 4 functions.
security_days_and_year · 26 lines · calc-func/src/ported/discount_bill_yearfrac_family.rs on GitHub/// The security's day count as the pair (days `D`, year basis `B`), whose quotient is
/// [`security_fraction`]: DISC, INTRATE, RECEIVED and PRICEDISC use the two apart (dc-j9k).
fn security_days_and_year(
settlement: f64,
maturity: f64,
basis: Option<f64>,
) -> Result<(f64, f64), DiscountBillYearfracEvalError> {
let settlement = parse_date_serial(settlement, 1)?;
let maturity = parse_date_serial(maturity, 1)?;
let basis = parse_basis(basis.unwrap_or(0.0))?;
if settlement >= maturity {
return Err(DiscountBillYearfracEvalError::Domain(
WorksheetErrorCode::Num,
));
}
match basis {
DayCountBasis::Us30_360 => Ok((days360_us(settlement, maturity)?, 360.0)),
DayCountBasis::ActualActual => {
crate::ported::day_count_common::excel_actual_actual_year(settlement, maturity)
.map_err(DiscountBillYearfracEvalError::Domain)
}
DayCountBasis::Actual360 => Ok((actual_days(settlement, maturity), 360.0)),
DayCountBasis::Actual365 => Ok((actual_days(settlement, maturity), 365.0)),
DayCountBasis::European30_360 => Ok((days360_eu(settlement, maturity)?, 360.0)),
}
}
Used by 4 functions.
tbill_days · 23 lines · calc-func/src/ported/discount_bill_yearfrac_family.rs on GitHubfn tbill_days(settlement: f64, maturity: f64) -> Result<f64, DiscountBillYearfracEvalError> {
let settlement = parse_date_serial(settlement, 0)?;
let maturity = parse_date_serial(maturity, 0)?;
if settlement >= maturity {
return Err(DiscountBillYearfracEvalError::Domain(
WorksheetErrorCode::Num,
));
}
// "More than one year after settlement" is DATE(year+1, month, day) with Excel's day
// rollover, not a month-end-clamped add: from 2044-02-29 the limit is 2045-03-01, and from
// 1991-02-28 it is 1992-02-28 (live Excel 20430, W111-5 G8-02/G8-03).
let num = || DiscountBillYearfracEvalError::Domain(WorksheetErrorCode::Num);
let (year, month, day) =
ymd_from_excel_serial(WorkbookDateSystem::System1900, settlement as f64).ok_or_else(num)?;
let one_year_out = excel_serial_from_ymd(WorkbookDateSystem::System1900, year + 1, month, day)
.ok_or_else(num)? as i64;
if maturity > one_year_out {
return Err(DiscountBillYearfracEvalError::Domain(
WorksheetErrorCode::Num,
));
}
Ok(actual_days(settlement, maturity))
}
Used by 3 functions.
map_discount_bill_yearfrac_error_to_ws · 8 lines · calc-func/src/ported/discount_bill_yearfrac_family.rs on GitHubpub fn map_discount_bill_yearfrac_error_to_ws(
error: &DiscountBillYearfracEvalError,
) -> WorksheetErrorCode {
match error {
DiscountBillYearfracEvalError::ArityMismatch { .. } => WorksheetErrorCode::Value,
DiscountBillYearfracEvalError::Domain(code) => *code,
}
}
Used by 7 functions.