use crate::ONE;
use rust_decimal::prelude::*;
pub fn pv_prime_r(rate: Decimal, n: Decimal, cash_flow: Decimal) -> Decimal {
-cash_flow * n / (rate + ONE).powd(n + ONE)
}
pub fn pv_prime2_r(rate: Decimal, n: Decimal, cash_flow: Decimal) -> Decimal {
cash_flow * n * (n + ONE) / (rate + ONE).powd(n + Decimal::TWO)
}
pub fn wacc_prime_de(r_e: Decimal, r_d: Decimal, de_ratio: Decimal, tax: Decimal) -> Decimal {
-(tax * r_d + r_e - r_d) / (de_ratio + ONE).powd(Decimal::TWO)
}
pub fn wacc_prime2_de(r_e: Decimal, r_d: Decimal, de_ratio: Decimal, tax: Decimal) -> Decimal {
Decimal::TWO * (tax * r_d + r_e - r_d) / (de_ratio + ONE).powd(Decimal::from_u8(3u8).unwrap())
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(not(feature = "std"))]
extern crate std;
use rust_decimal_macros::dec;
#[cfg(not(feature = "std"))]
use std::assert;
#[cfg(not(feature = "std"))]
use std::prelude::v1::*;
#[test]
fn test_pv_prime() {
let rate = dec!(0.05);
let n = dec!(5);
let cash_flow = dec!(1000);
let result = pv_prime_r(rate, n, cash_flow);
let expected = dec!(-3731.07698);
assert!(
(result - expected).abs() < dec!(1e-5),
"Failed on case: {}. Expected: {}, Result: {}",
"Rate of 5%, 5th period, cash flow of $1000",
expected,
result
);
}
#[test]
fn test_pv_double_prime() {
let rate = dec!(0.05);
let n = dec!(5);
let cash_flow = dec!(1000);
let result = pv_prime2_r(rate, n, cash_flow);
let expected = dec!(21320.43990);
assert!(
(result - expected).abs() < dec!(1e-5),
"Failed on case: {}. Expected: {}, Result: {}",
"Rate of 5%, 5th period, cash flow of $1000",
expected,
result
);
}
#[test]
fn test_wacc_prime() {
let r_e = dec!(0.05);
let r_d = dec!(0.07);
let de_ratio = dec!(0.7);
let tax = dec!(0.25);
let result = wacc_prime_de(r_e, r_d, de_ratio, tax);
let expected = dec!(0.00086);
assert!(
(result - expected).abs() < dec!(1e-5),
"Failed on case: {}. Expected{}, Result: {}",
"Cost of Equity 5%, Cost of Debt 7%, D/E 0.7, Tax Rate 25%",
expected,
result
);
}
}