I am learning rust and I thought I would try to make a mortgage calculator with it.
/*
input:
home sale price: 100k
down payment amount: 0
interest rate and the terms of interest rate, ie 5yr 5% fixed, so 60 payments
amortization period: 30 yr mortgage
payment frequency: monthly
*/
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(unused_must_use)]
use std::process;
use std::error::Error;
struct Mortgage {
f64_purchase_price: f64,
f64_down_payment: f64,
i32_amortization_period: i32,
f64_interest_rate1: f64,
i32_interest_rate_term1: i32,
}
impl Mortgage {
fn parse_args(args: &[String]) -> Result<Mortgage, &'static str> {
if args.len() < 5 {
return Err("not enough arguments");
}
let purchase_price= &args[1];
let down_payment= &args[2];
let amortization_period= &args[3]; // in months
let interest_rate1 = &args[4];
let interest_rate_term1 = &args[5];// in months
let f64_purchase_price: f64 = purchase_price.parse().unwrap();
let f64_down_payment: f64 = down_payment.parse().unwrap();
let i32_amortization_period: i32 = amortization_period.parse().unwrap();
let f64_interest_rate1_annual: f64= interest_rate1.parse().unwrap(); //assume monthly
let f64_interest_rate1=f64_interest_rate1_annual/12.0;
let i32_interest_rate_term1 :i32= interest_rate_term1.parse().unwrap();
println!("purchase price {:?} down payment {:?} amortization period {:?} interest rate montly {:?} term {:?} ", f64_purchase_price, f64_down_payment, i32_amortization_period, f64_interest_rate1,i32_interest_rate_term1);
Ok(Mortgage{f64_purchase_price, f64_down_payment,i32_amortization_period,f64_interest_rate1,i32_interest_rate_term1})
}
}
fn calculate(mortgage: Mortgage) -> Result<(), Box<dyn Error>> {
let principle: f64 = mortgage.f64_purchase_price-mortgage.f64_down_payment;
let bottom_rate: f64 = 1.0+mortgage.f64_interest_rate1;
let bottom_rate_power: f64 = bottom_rate.powf(f64::from(mortgage.i32_interest_rate_term1));
let bottom = bottom_rate_power - 1.0;
let top: f64 = mortgage.f64_interest_rate1*bottom_rate_power;
let monthly_payment=principle*(top/bottom);
println!("principle payment: {:?}", principle);
println!("top: {:?}", top);
println!("bottom: {:?}", bottom);
println!("monthly payment: {:?}", monthly_payment);
Ok(())
}
fn main() {
let args: Vec<String> = std::env::args().collect(); // get all arguments passed to app
let mortgage = Mortgage::parse_args(&args).unwrap_or_else(|err| {
println!("Problem parsing arguments: {err}");
process::exit(1);
});
calculate(mortgage);
}
So I ran it with 100k, 30 yr mortgage, 5% interest, 5 yr term
cargo run -- 100000 0 360 0.05 60
purchase price 100000.0 down payment 0.0 amortization period 360 interest rate montly 0.004166666666666667 term 60
principle payment: 100000.0
top: 0.0053473278270979654
bottom: 0.2833586785035118
monthly payment: 1887.1233644010988
This payment is off from the online calculator here: https://itools-ioutils.fcac-acfc.gc.ca/MC-CH/MCCalc-CHCalc-eng.aspx. My program's monthly payment is 1887 while the online tool is closer to 500 dollars.
the top and bottom mentioned in the code corresponds to this formula:
M = P [ i(1 + i)^n ] / [ (1 + i)^n – 1]
the P is the principle, top is the stuff above the division line and bottom is the stuff below the division line.
So is the issue I am having because I am using float 64? I don't think I implemented the formula wrong but why I am getting 41k for motnly payment. I thought float 64 would make sense because you can have 100000.34 for price, and interest rate is 5.5%.