Crates.io | finance-solution |
lib.rs | finance-solution |
version | 0.0.0 |
source | src |
created_at | 2020-05-25 03:21:19.79437 |
updated_at | 2020-05-25 03:21:19.79437 |
description | A library for finance time-value-of-money functions with detailed solutions and pretty-printed tables. |
homepage | |
repository | https://github.com/shan-alexander/finance-solution |
max_upload_size | |
id | 245438 |
size | 522,607 |
People who will find this crate helpful include:
Currently, this library is geared towards the basic financial equations, regarding:
present_value
, future_value
, rate
, and periods
(known as NPER in Excel).present_value_annuity
, future_value_annuity
, net_present_value
, and payment
(known as PMT in Excel).apr
, ear
, and epr
, and also includes conversion for continuous compounding (apr_continuous
, ear_continuous
).A business partner will give you $4,000 in 3 years. Your rate-of-return in the market is 5%. How much is the deal worth to you right now?
present_value()
to return f64 valuelet future_value = 4_000;
let periods = 3;
let rate = 0.05;
let pv = present_value(rate, periods, future_value);
dbg!(pv);
// PRINTS TO TERMINAL:
// pv = 3455.350394125904
The crate also provides helper functions for rounding, such as
round_4
to round to four decimals places. Seeround
for more details.
For the same problem above, you can use the _solution function to see a better output and provide additional functionality.
present_value_solution()
to return a custom "solution" structlet future_value = 4_000;
let periods = 3;
let rate = 0.05;
let answer = present_value_solution(rate, periods, future_value);
dbg!(answer);
// PRINTS TO TERMINAL:
// answer = TvmSolution {
// calculated_field: PresentValue,
// rate: 0.05,
// periods: 3,
// fractional_periods: 3.0,
// present_value: 3455.350394125904,
// future_value: 4000.0,
// formula: "3455.3504 = 4000.0000 / (1.050000 ^ 3)",
// formula_symbolic: "pv = fv / (1 + r)^n",
//}
If you want to explore what happens in each period of the calculation, you can use the .series()
method on any solution output:
present_value_solution().series()
to return a vec of each periodlet future_value = 4_000;
let periods = 3;
let rate = 0.05;
let answer = present_value_solution(rate, periods, future_value);
dbg!(answer.series());
// PRINTS TO TERMINAL:
// answer.series() = TvmSeries(
// [
// TvmPeriod {
// period: 0,
// rate: 0.0,
// value: 3455.3503941259037,
// formula: "3455.3504 = 3628.1179 / 1.050000",
// formula_symbolic: "value = {next period value} / (1 + r)",
// },
// TvmPeriod {
// period: 1,
// rate: 0.05,
// value: 3628.117913832199,
// formula: "3628.1179 = 3809.5238 / 1.050000",
// formula_symbolic: "value = {next period value} / (1 + r)",
// },
// TvmPeriod {
// period: 2,
// rate: 0.05,
// value: 3809.523809523809,
// formula: "3809.5238 = 4000.0000 / 1.050000",
// formula_symbolic: "value = {next period value} / (1 + r)",
// },
// TvmPeriod {
// period: 3,
// rate: 0.05,
// value: 4000.0,
// formula: "4000.0000",
// formula_symbolic: "value = fv",
// },
// ],
// )
To view each period in a table format, use the .print_table()
method.
present_value_solution().series().print_table()
to return a pretty-print tableuse num_format::{Locale};
let future_value = 4_000;
let periods = 3;
let rate = 0.05;
let answer = present_value_solution(rate, periods, future_value);
dbg!(answer.series().print_table());
// or use .print_table_locale() to specify your formatting preferences.
dbg!(answer.series().print_table_locale(&Locale::en, 4));
// PRINTS TO TERMINAL:
// period rate value
// ------ ------ ----------
// 0 0.0000 3,455.3504
// 1 0.0500 3,628.1179
// 2 0.0500 3,809.5238
// 3 0.0500 4,000.0000
In the table above, you can specify the locale, if you prefer a different format for the money values. For example, your country may prefer 8.532,11
instead of 8,532.11
. The pretty-printed tables are easily copy&pasted into a spreadsheet.
The .print_table()
function can be especially helpful when analyzing payment
and cashflow
information.
payment_solution().series().print_table()
to return a pretty-print tablelet present_value = 13_000;
let periods = 5;
let rate = 0.08;
let answer = payment_solution(rate, periods, present_value, 0);
dbg!(answer.series().print_table());
// PRINTS TO TERMINAL:
// period payments_to_date payments_remaining principal principal_to_date principal_remaining interest interest_to_date interest_remaining
// ------ ---------------- ------------------ ----------- ----------------- ------------------- ----------- ---------------- ------------------
// 1 -3,255.9339 -13,023.7356 -2,215.9339 -2,215.9339 -10,784.0661 -1,040.0000 -1,040.0000 -2,239.6695
// 2 -6,511.8678 -9,767.8017 -2,393.2086 -4,609.1425 -8,390.8575 -862.7253 -1,902.7253 -1,376.9443
// 3 -9,767.8017 -6,511.8678 -2,584.6653 -7,193.8078 -5,806.1922 -671.2686 -2,573.9939 -705.6757
// 4 -13,023.7356 -3,255.9339 -2,791.4385 -9,985.2464 -3,014.7536 -464.4954 -3,038.4893 -241.1803
// 5 -16,279.6695 0.0000 -3,014.7536 -12,999.0000 -0.0000 -241.1803 -3,279.6695 0.0000
As you can see in the table above, the finance-solution
library offers more than "just the answer" to the problem (-3,255.9339) but also provides a detailed visual of what is happening in each period.
This library has undergone hundreds of hours spent designing the library to be ergonomic, rustic, and accurate.
Bonus highlights include:
_solution
to the function name to provide a more helpful output, with additional functionality. We highly recommend you use the _solution
functions when you can!_solution
structs add a trivial amount of time to the code execution, 12-30 nanoseconds... as shown in our benches
section._solution().series().print_table()
allows the user to specify locale for specific currency formatting, and the output can easily be copy&pasted into spreadsheets (Excel, Google Sheet, etc).examples
folder of the repo, which allows users to see how finance-solution can be used to solve financial problems.warn!
logs to prevent users from making common mistakes, especially with rates.warn!
for situations when we believe the inputs may create inaccuracies in the final output. It is up to the user to enable warn logs.We have a backlog of items we intend to include in this crate: