Advertisement
Guest User

Untitled

a guest
Mar 24th, 2019
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.65 KB | None | 0 0
  1. use chrono::prelude::*;
  2.  
  3. struct Arguments {
  4. // milli-dollars ( $15 = 15000)
  5. starting_value: i64,
  6. // milli-dollars
  7. contrib: i64,
  8. // percentage in milli-percent ( 13% = 13_000, 100% = 100_000 )
  9. apr: i64,
  10. // deci-cents and milli-percent gives us a maximum balance near 922 billion dollars before we overflow
  11. contrib_years: usize,
  12. }
  13.  
  14. struct Transaction {
  15. amount: i64,
  16. time: DateTime<Utc>,
  17. memo: String,
  18. }
  19.  
  20. struct Account {
  21. transactions: Vec<Transaction>,
  22. }
  23.  
  24. impl Account {
  25. fn get_balance_at(&self, time: &DateTime<Utc>) -> i64 {
  26. // TODO - walk through transactions and update running balance until we get to a date that is greater than the passed in time
  27. let mut running_balance = 0;
  28. for mut i in 0..self.transactions.len() {
  29. let transaction = self.transactions.get(i).unwrap();
  30. if transaction.time <= *time {
  31. running_balance += transaction.amount;
  32. } else {
  33. i = self.transactions.len();
  34. }
  35. }
  36. running_balance
  37. }
  38. }
  39.  
  40. fn main() {
  41. let args = Arguments {
  42. starting_value: 16_000_000,
  43. contrib: 1_200_000,
  44. apr: 5_000,
  45. contrib_years: 20,
  46. };
  47.  
  48. let mut account: Account = Account {
  49. transactions: Vec::new(),
  50. };
  51.  
  52. let months = args.contrib_years * 12;
  53. let mpr = args.apr / 12;
  54. // println!("Final monthly milli percentage is {}", mpr);
  55.  
  56. let mut date = Utc.ymd(2019, 3, 1).and_hms(0, 0, 0);
  57.  
  58. let mut balance: i64 = args.starting_value;
  59.  
  60. for i in 1..=months {
  61. date = next_month_truncate(&date);
  62. // println!("{}",&date.to_rfc2822());
  63. // apply last months percentage first
  64. let interest = (balance * mpr) / 100_000;
  65. // add this months contribution
  66. let new = balance + interest + args.contrib;
  67. //println!("{}. Increase by {} and contribute {} makes about {}.", i, interest as f64 / 1000f64, args.contrib as f64 / 1000f64, new as f64 / 1000f64);
  68. balance = new;
  69. account.transactions.push(Transaction {
  70. amount: interest,
  71. time: date,
  72. memo: "Simulated interest calculation".to_string(),
  73. });
  74. account.transactions.push(Transaction {
  75. amount: args.contrib,
  76. time: date,
  77. memo: "Simulated contribution".to_string(),
  78. });
  79. if i % 12 == 0 {
  80. println!("Year {} : {}", i / 12, &format_milli_dollars(balance));
  81. }
  82. }
  83.  
  84. println!("Max balance is {}", &format_milli_dollars(balance));
  85.  
  86. let query_date = Utc.ymd(2021, 6, 8).and_hms(0, 0, 0);
  87. println!(
  88. "Balance at {} is {}",
  89. &query_date.to_rfc2822(),
  90. &format_milli_dollars(account.get_balance_at(&query_date))
  91. );
  92.  
  93. // start burn down
  94. }
  95.  
  96. fn format_milli_dollars(dollars: i64) -> String {
  97. format!("${}.{}", dollars / 1000, (dollars % 1000) / 10)
  98. }
  99.  
  100. fn next_month_truncate(date_time: &DateTime<Utc>) -> DateTime<Utc> {
  101. let date = date_time.date();
  102. let time = date_time.time();
  103.  
  104. // December to month '0' first
  105. let n_month = (date.month() % 12) + 1;
  106. let n_year = if date.month() == 12 {
  107. date.year() + 1
  108. } else {
  109. date.year()
  110. };
  111.  
  112. let n_month_next = (n_month % 12) + 1;
  113. let n_year_next = if n_month == 12 { n_year + 1 } else { n_year };
  114.  
  115. // check length of the next month
  116. let max_day: u32 = Utc
  117. .ymd(n_year_next, n_month_next, 1)
  118. .signed_duration_since(Utc.ymd(n_year, n_month, 1))
  119. .num_days() as u32;
  120.  
  121. let n_day = if date.day() > max_day {
  122. max_day
  123. } else {
  124. date.day()
  125. };
  126.  
  127. Utc.ymd(n_year, n_month, n_day).and_time(time).unwrap()
  128. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement