logisheets_controller/calc_engine/calculator/funcs/bonds/
yielddisc.rs

1use crate::calc_engine::calculator::math::bond::yielddisc;
2use crate::calc_engine::calculator::math::day_count::{
3    Actual360, Actual365, ActualActual, Europe30_360, UsPsa30_360,
4};
5use logisheets_parser::ast;
6
7use super::super::{CalcValue, CalcVertex, Value};
8use crate::calc_engine::connector::Connector;
9
10pub fn calc<C>(args: Vec<CalcVertex>, fetcher: &mut C) -> CalcVertex
11where
12    C: Connector,
13{
14    assert_or_return!(args.len() >= 4 && args.len() <= 5, ast::Error::Unspecified);
15    let mut args_iter = args.into_iter();
16
17    let first = fetcher.get_calc_value(args_iter.next().unwrap());
18    assert_f64_from_calc_value!(settlement, first);
19    assert_or_return!(settlement > 0., ast::Error::Value);
20
21    let second = fetcher.get_calc_value(args_iter.next().unwrap());
22    assert_f64_from_calc_value!(maturity, second);
23    assert_or_return!(maturity > 0., ast::Error::Value);
24
25    let third = fetcher.get_calc_value(args_iter.next().unwrap());
26    assert_f64_from_calc_value!(pr, third);
27    assert_or_return!(pr > 0., ast::Error::Num);
28
29    let fourth = fetcher.get_calc_value(args_iter.next().unwrap());
30    assert_f64_from_calc_value!(redemption, fourth);
31    assert_or_return!(redemption > 0., ast::Error::Num);
32
33    assert_or_return!(settlement < maturity, ast::Error::Num);
34
35    let settle = settlement.floor() as u32;
36    let maturity = maturity.floor() as u32;
37
38    let result = if let Some(arg) = args_iter.next() {
39        assert_f64_from_calc_value!(b, fetcher.get_calc_value(arg));
40        assert_or_return!(b >= 0. && b <= 4., ast::Error::Num);
41        match b.floor() as u8 {
42            0 => yielddisc::<UsPsa30_360>(settle, maturity, pr, redemption),
43            1 => yielddisc::<ActualActual>(settle, maturity, pr, redemption),
44            2 => yielddisc::<Actual360>(settle, maturity, pr, redemption),
45            3 => yielddisc::<Actual365>(settle, maturity, pr, redemption),
46            4 => yielddisc::<Europe30_360>(settle, maturity, pr, redemption),
47            _ => unreachable!(),
48        }
49    } else {
50        yielddisc::<UsPsa30_360>(settle, maturity, pr, redemption)
51    };
52    CalcVertex::from_number(result)
53}