[][src]Struct finance_solution::tvm::TvmSolution

pub struct TvmSolution { /* fields omitted */ }

Implementations

impl TvmSolution[src]

pub fn series(&self) -> TvmSeries[src]

Calculates the value of an investment after each period.

Examples

Calculates the period-by-period details of a future value calculation. Uses future_value_solution.

// The initial investment is $10,000.12, the interest rate is 1.5% per month, and the
// investment will grow for 24 months using simple compounding.
let solution = finance_solution::future_value_solution(0.015, 24, 10_000.12, false);

// Calculate the value at the end of each period.
let series = solution.series();
dbg!(&series);

// Confirm that we have one entry for the initial value and one entry for each period.
assert_eq!(25, series.len());

// Print the period-by-period numbers in a formatted table.
series.print_table();

// Create a vector with every fourth period.
let filtered_series = series
    .iter()
    .filter(|x| x.period() % 4 == 0)
    .collect::<Vec<_>>();
dbg!(&filtered_series);
assert_eq!(7, filtered_series.len());

Calculate a present value with a fixed rate then examine the period-by-period values. Uses present_value_solution.

// The interest rate is 7.8% per year, the investment will grow for 10 years using simple
// compounding, and the final value will be 8_112.75.
let solution = finance_solution::present_value_solution(0.078, 10, 8_112.75, false);

// Calculate the value at the end of each period.
let series = solution.series();
dbg!(&series);

// Confirm that we have one entry for the present value, that is the
// initial value before any interest is applied, and one entry for each
// period.
assert_eq!(11, series.len());

// Create a reduced vector with every other period not including period 0,
// the initial state.
let filtered_series = series
    .iter()
    .filter(|x| x.period() % 2 == 0 && x.period() != 0)
    .collect::<Vec<_>>();
dbg!(&filtered_series);
assert_eq!(5, filtered_series.len());

Calculate a present value with varying rates then examine the period-by-period values. Uses present_value_schedule.

// The annual rate varies from -12% to 11%.
let rates = [0.04, 0.07, -0.12, -0.03, 0.11];

// The value of the investment after applying all of these periodic rates
// will be $100_000.25.
let future_value = 100_000.25;

// Calculate the present value and keep track of the inputs and the formula
// in a struct.
let solution = finance_solution::present_value_schedule_solution(&rates, future_value);
dbg!(&solution);

// Calculate the value at the end of each period.
let series = solution.series();
dbg!(&series);
// There is one entry for each period and one entry for period 0 containing
// the present value.
assert_eq!(6, series.len());

// Create a filtered list of periods, only those with a negative rate.
let filtered_series = series
    .iter()
    .filter(|x| x.rate() < 0.0)
    .collect::<Vec<_>>();
dbg!(&filtered_series);
assert_eq!(2, filtered_series.len());

pub fn print_series_table(&self)[src]

Prints a formatted table with the period-by-period details of a time-value-of-money calculation.

Money amounts are rounded to four decimal places, rates to six places, and numbers are formatted similar to Rust constants such as "10_000.0322". For more control over formatting use [`TvmSolution::print_series_table_locale'].

Examples

finance_solution::future_value_solution(0.045, 5, 10_000, false)
    .print_series_table();

Output:

period      rate        value
------  --------  -----------
     0  0.000000  10_000.0000
     1  0.045000  10_450.0000
     2  0.045000  10_920.2500
     3  0.045000  11_411.6612
     4  0.045000  11_925.1860
     5  0.045000  12_461.8194

pub fn print_series_table_locale(&self, locale: &Locale, precision: usize)[src]

Prints a formatted table with the period-by-period details of a time-value-of-money calculation.

For a simpler function that doesn't require a locale use [`TvmSolution::print_series_table'].

Arguments

  • locale - A locale constant from the num-format crate such as Locale::en for English or Locale::vi for Vietnamese. The locale determines the thousands separator and decimal separator.
  • precision - The number of decimal places for money amounts. Rates will appear with at least six places regardless of this argument.

Examples

// English formatting with "," for the thousands separator and "." for the decimal
// separator.
let locale = finance_solution::num_format::Locale::en;

// Show money amounts to two decimal places.
let precision = 2;

finance_solution::future_value_solution(0.11, 4, 5_000, false)
    .print_series_table_locale(&locale, precision);

Output:

period      rate     value
------  --------  --------
     0  0.000000  5,000.00
     1  0.110000  5,550.00
     2  0.110000  6,160.50
     3  0.110000  6,838.16
     4  0.110000  7,590.35

pub fn calculated_field(&self) -> &TvmVariable[src]

Returns a variant of TvmVariable showing which value was calculated, either the periodic rate, number of periods, present value, or future value. To test for the enum variant use functions like TvmVariable::is_rate.

Examples

// Calculate the future value of $25,000 that grows at 5% for 12 yeors.
let solution = finance_solution::future_value_solution(0.05, 12, 25_000, false);
assert!(solution.calculated_field().is_future_value());

pub fn continuous_compounding(&self) -> bool[src]

Returns true if the value is compounded continuously rather than period-by-period.

pub fn rate(&self) -> f64[src]

Returns the periodic rate which is a calculated value if this TvmSolution struct is the result of a call to rate_solution and otherwise is one of the input values.

pub fn periods(&self) -> u32[src]

Returns the number of periods as a whole number. This is a calculated value if this TvmSolution struct is the result of a call to periods_solution and otherwise it's one of the input values. If the value was calculated the true result may not have been a whole number so this is that number rounded away from zero.

pub fn fractional_periods(&self) -> f64[src]

Returns the number of periods as a floating point number. This is a calculated value if this TvmSolution struct is the result of a call to periods_solution and otherwise it's one of the input values.

pub fn present_value(&self) -> f64[src]

Returns the present value which is a calculated value if this TvmSolution struct is the result of a call to present_value_solution and otherwise is one of the input values.

pub fn future_value(&self) -> f64[src]

Returns the future value which is a calculated value if this TvmSolution struct is the result of a call to future_value_solution and otherwise is one of the input values.

pub fn formula(&self) -> &str[src]

Returns a text version of the formula used to calculate the result which may have been the periodic rate, number of periods, present value, or future value depending on which function was called. The formula includes the actual values rather than variable names. For the formula with variables such as r for rate call symbolic_formula.

pub fn symbolic_formula(&self) -> &str[src]

Returns a text version of the formula used to calculate the result which may have been the periodic rate, number of periods, present value, or future value depending on which function was called. The formula uses variables such as n for the number of periods. For the formula with the actual values rather than variables call formula.

pub fn rate_solution(
    &self,
    continuous_compounding: bool,
    compounding_periods: Option<u32>
) -> TvmSolution
[src]

pub fn periods_solution(&self, continuous_compounding: bool) -> TvmSolution[src]

pub fn present_value_solution(
    &self,
    continuous_compounding: bool,
    compounding_periods: Option<u32>
) -> TvmSolution
[src]

pub fn future_value_solution(
    &self,
    continuous_compounding: bool,
    compounding_periods: Option<u32>
) -> TvmSolution
[src]

pub fn present_value_vary_compounding_periods(
    &self,
    compounding_periods: &[u32],
    include_continuous_compounding: bool
) -> ScenarioList
[src]

Returns a struct with a set of what-if scenarios for the present value needed with a variety of compounding periods.

Arguments

  • compounding_periods - The compounding periods to include in the scenarios. The result will have a computed present value for each compounding period in this list.
  • include_continuous_compounding - If true, adds one scenario at the end of the results with continuous compounding instead of a given number of compounding periods.

Examples

For a more detailed example with a related function see future_value_vary_compounding_periods

// Calculate the future value of an investment that starts at $83.33 and grows 20% in one
// year using simple compounding. Note that we're going to examine how the present value
// varies by the number of compounding periods but we're starting with a future value
// calculation. It would have been fine to start with a rate, periods, or present value
// calculation as well. It just depends on what information we have to work with.
let solution = finance_solution::future_value_solution(0.20, 1, -83.333, false);
dbg!(&solution);

// The present value of $83.33 gives us a future value of about $100.00.
finance_solution::assert_rounded_2!(100.00, solution.future_value());

// We'll experiment with compounding annually, quarterly, monthly, weekly, and daily.
let compounding_periods = [1, 4, 12, 52, 365];

// Add a final scenario with continuous compounding.
let include_continuous_compounding = true;

// Compile a list of the present values needed to arrive at the calculated future value of $100
// each of the above compounding periods as well a continous compounding.
let scenarios = solution.present_value_vary_compounding_periods(&compounding_periods, include_continuous_compounding);
dbg!(&scenarios);

// Print the results in a formatted table.
scenarios.print_table();

Output from the last line:

Periods  Present Value
-------  -------------
      1        83.3330
      4        82.2699
     12        82.0078
     52        81.9042
    365        81.8772
    inf        81.8727

As we compound the interest more frequently we need a slightly smaller initial value to reach the same final value of $100 in one year. With more frequent compounding the required initial value approaches $81.87, the present value needed with continuous compounding.

If we plot this using between 1 and 12 compounding periods it's clear that the required present value drops sharply if we go from compounding annually to compounding semiannually or quarterly but then is affected less and less as we compound more frequently:

pub fn future_value_vary_compounding_periods(
    &self,
    compounding_periods: &[u32],
    include_continuous_compounding: bool
) -> ScenarioList
[src]

Returns a struct with a set of what-if scenarios for the future value of an investment given a variety of compounding periods.

Arguments

  • compounding_periods - The compounding periods to include in the scenarios. The result will have a computed future value for each compounding period in this list.
  • include_continuous_compounding - If true, adds one scenario at the end of the results with continuous compounding instead of a given number of compounding periods.

Examples

// The interest rate is 5% per quarter.
let rate = 0.05;

// The interest will be applied once per quarter for one year.
let periods = 4;

// The starting value is $100.00.
let present_value = 100;

let continuous_compounding = false;

let solution = finance_solution::future_value_solution(rate, periods, present_value, continuous_compounding);
dbg!(&solution);

// We'll experiment with compounding annually, quarterly, monthly, weekly, and daily.
let compounding_periods = [1, 4, 12, 52, 365];

// Add a final scenario with continuous compounding.
let include_continuous_compounding = true;

// Compile a list of the future values with each of the above compounding periods as well as
// continous compounding.
let scenarios = solution.future_value_vary_compounding_periods(&compounding_periods, include_continuous_compounding);
// The description in the `setup` field states that the rate is 20% since that's 5% times the
// number of periods in the original calculation. The final entry has `input: inf` indicating
// that we used continuous compounding.
dbg!(&scenarios);

// Print the results in a formatted table.
scenarios.print_table();

Output:

&solution = FutureValueSolution {
    tvm_solution: TvmSolution {
    calculated_field: FutureValue,
    continuous_compounding: false,
    rate: 0.05,
    periods: 4,
    fractional_periods: 4.0,
    present_value: 100.0,
    future_value: 121.55062500000003,
    formula: "121.5506 = 100.0000 * (1.050000 ^ 4)",
    symbolic_formula: "fv = pv * (1 + r)^n",
},

&scenarios = ScenarioList {
    setup: "Compare future values with different compounding periods where the rate is 0.200000 and the present value is 100.0000.",
    input_variable: Periods,
    output_variable: FutureValue,
    entries: [
        { input: 1, output: 120.0000 },
        { input: 4, output: 121.5506 },
        { input: 12, output: 121.9391 },
        { input: 52, output: 122.0934 },
        { input: 365, output: 122.1336 },
        { input: inf, output: 122.1403 },
    ],
}

Periods  Future Value
-------  ------------
      1      120.0000
      4      121.5506
     12      121.9391
     52      122.0934
    365      122.1336
    inf      122.1403

With the same interest rate and overall time period, an amount grows faster if we compound the interest more frequently. As the number of compounding periods grows the future value approaches the limit of $122.14 that we get with continuous compounding.

As a chart it looks like this, here using only 1 through 12 compounding periods for clarity:

pub fn print_ab_comparison(&self, other: &TvmSolution)[src]

pub fn print_ab_comparison_locale(
    &self,
    other: &TvmSolution,
    locale: &Locale,
    precision: usize
)
[src]

Trait Implementations

impl Clone for TvmSolution[src]

impl Debug for TvmSolution[src]

impl PartialEq<TvmSolution> for TvmSolution[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.