aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs129
-rw-r--r--src/main.rs22
2 files changed, 80 insertions, 71 deletions
diff --git a/src/lib.rs b/src/lib.rs
index aa4ee79..66ebe32 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,8 +2,9 @@ use std::collections::HashMap;
use std::fmt;
pub struct Simulation {
- history: Vec<Mortgage>,
+ mortgage: Mortgage,
updates: MortgageUpdates,
+ history: Vec<Quota>,
topay_total: f64,
topay_interest: f64,
payed_principal: f64,
@@ -12,13 +13,41 @@ pub struct Simulation {
}
impl Simulation {
- fn run(&mut self, mut mortgage: Mortgage) {
- while mortgage.quotas > 0 && mortgage.principal > 0. {
- self.history.push(mortgage.clone());
+ pub fn new(principal: f64, i1: f64, years: u32) -> Self {
+ let pending_quotas = years * 12;
+ let i12 = i1 / 12.0;
+
+ let mortgage = Mortgage {
+ period: 0,
+ principal,
+ i12,
+ monthly: Mortgage::monthly(principal, i12, pending_quotas),
+ pending_quotas,
+ };
+
+ let topay_total = mortgage.monthly * pending_quotas as f64;
+
+ Simulation {
+ mortgage,
+ topay_total,
+ topay_interest: topay_total - principal,
+ payed_principal: 0.,
+ payed_interest: 0.,
+ payed_amortized: 0.,
+ history: vec![],
+ updates: HashMap::new(),
+ }
+ }
+
+ pub fn run(&mut self, updates: MortgageUpdates) {
+ self.updates = updates;
+ let mut mortgage = self.mortgage.clone();
+ while mortgage.pending_quotas > 0 && mortgage.principal > 0. {
+ let quota = mortgage.step();
+ self.payed_principal += quota.principal;
+ self.payed_interest += quota.interest;
+ self.history.push(quota);
self.apply_updates(&mut mortgage);
- self.payed_principal += mortgage.quota_principal();
- self.payed_interest += mortgage.quota_interest();
- mortgage.step();
}
}
@@ -30,7 +59,7 @@ impl Simulation {
};
mortgage.principal -= *principal;
mortgage.monthly =
- Mortgage::monthly(mortgage.principal, mortgage.i12, mortgage.quotas);
+ Mortgage::monthly(mortgage.principal, mortgage.i12, mortgage.pending_quotas);
self.payed_amortized += *principal;
}
@@ -39,19 +68,19 @@ impl Simulation {
}
pub fn render_table(&self) {
- let mortgage = &self.history[0];
+ let mortgage = &self.mortgage;
println!("\n========================================================");
println!(
"=== HIPOTECA: {}€, A {} AÑOS, INTERÉS FIJO {:.2}% ===",
mortgage.principal,
- mortgage.quotas / 12,
+ mortgage.pending_quotas / 12,
mortgage.i12 * 12. * 100.,
);
println!("========================================================");
println!("\n\n# SIMULACIÓN CUOTAS\n");
- println!("Year | Mon | Quota ( Intrst + Amrtzd) | Principal");
+ println!("Year | Mon | Quota ( Amrtzd + Intrst) | Pending");
for mortgage in self.history.iter() {
print!("{mortgage}");
if let Some(update) = self.updates.get(&mortgage.period) {
@@ -64,7 +93,7 @@ impl Simulation {
println!("\n\n# A PRIORI\n");
println!(
- "== Total a pagar: {:.2} ({} cap + {:.2} int)",
+ "== Total a pagar: {:.2} ({:.2} cap + {:.2} int)",
self.topay_total, mortgage.principal, self.topay_interest
);
println!(
@@ -86,73 +115,61 @@ impl Simulation {
}
#[derive(Clone)]
-pub struct Mortgage {
+pub struct Quota {
period: u32,
+ interest: f64,
principal: f64,
- i12: f64,
- monthly: f64,
- quotas: u32,
+ pending_principal: f64,
}
-impl fmt::Display for Mortgage {
+impl fmt::Display for Quota {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{:4} | {:3} | {:7.2} ({:7.2} + {:7.2}) | {:10.2}",
- if self.period % 12 == 0 {
+ if (self.period - 1) % 12 == 0 {
format!("Y{}", (self.period / 12) + 1)
} else {
// return Ok(());
"".to_string()
},
self.period,
- self.monthly,
- self.quota_interest(),
- self.quota_principal(),
- self.principal
+ self.interest + self.principal,
+ self.principal,
+ self.interest,
+ self.pending_principal
)
}
}
-impl Mortgage {
- pub fn new(principal: f64, i1: f64, years: u32) -> Self {
- let quotas = years * 12;
- let i12 = i1 / 12.0;
- Mortgage {
- period: 0,
- principal,
- i12,
- monthly: Self::monthly(principal, i12, quotas),
- quotas,
- }
- }
-
- pub fn simulate(&mut self, updates: MortgageUpdates) -> Simulation {
- let topay_total = self.monthly * self.quotas as f64;
-
- let mut sim = Simulation {
- topay_total,
- topay_interest: topay_total - self.principal,
- payed_principal: 0.,
- payed_interest: 0.,
- payed_amortized: 0.,
- history: vec![],
- updates,
- };
-
- sim.run(self.clone());
+#[derive(Clone)]
+pub struct Mortgage {
+ period: u32,
+ principal: f64,
+ i12: f64,
+ monthly: f64,
+ pending_quotas: u32,
+}
- sim
+impl Mortgage {
+ fn monthly(principal: f64, i12: f64, pending_quotas: u32) -> f64 {
+ principal * i12 / (1.0 - (1.0 + i12).powi(-(pending_quotas as i32)))
}
- fn monthly(principal: f64, i12: f64, quotas: u32) -> f64 {
- principal * i12 / (1.0 - (1.0 + i12).powi(-(quotas as i32)))
- }
+ fn step(&mut self) -> Quota {
+ let interest = self.quota_interest();
+ let principal = self.quota_principal();
- fn step(&mut self) {
self.period += 1;
- self.quotas -= 1;
+ self.pending_quotas -= 1;
self.principal = (1.0 + self.i12) * self.principal - self.monthly;
+
+ Quota {
+ period: self.period,
+ interest,
+ principal,
+ pending_principal: self.principal,
+ }
}
fn quota_interest(&self) -> f64 {
@@ -176,7 +193,7 @@ impl fmt::Display for MortgageUpdate {
write!(f, "[MORTGAGE UPDATE: ")?;
match self {
Self::Amortize(principal) => {
- write!(f, "{principal:.2} amortized to reduce quotas]")
+ write!(f, "{principal:.2} amortized to reduce pending_quotas]")
}
}
}
diff --git a/src/main.rs b/src/main.rs
index 66ce418..f785bb0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,25 +1,17 @@
-use hiccup::Mortgage;
use hiccup::MortgageUpdate::*;
-use hiccup::MortgageUpdates;
+use hiccup::{MortgageUpdates, Simulation};
use std::collections::HashMap;
-fn h1() {
- let m = Mortgage::new(390_000., 0.028, 30);
-
+fn main() {
+ let mut sim = Simulation::new(390_000., 0.028, 30);
let updates: MortgageUpdates = HashMap::from_iter((0..29).map(|y| match y {
0 => (0, Amortize(30_000.)),
_ => (y * 12, Amortize(12_000.)),
}));
- let sim = m.clone().simulate(updates);
- sim.render_table();
-}
-fn h2() {
- let m = Mortgage::new(200_000., 0.01621, 30);
- let sim = m.clone().simulate(HashMap::new());
- sim.render_table();
-}
+ // let mut sim = Simulation::new(200_000., 0.01621, 30);
+ // let updates: MortgageUpdates = HashMap::new();
-fn main() {
- h1();
+ sim.run(updates);
+ sim.render_table();
}