Time Value of Money (TVM) Module

The qfinbox.tvm module provides comprehensive Time Value of Money calculations across five specialized submodules. Each module contains functions optimized for specific types of financial calculations.

Submodules Overview

basic

Basic Time Value of Money calculations.

annuities

Annuity calculations.

bonds

Bond valuation and analysis.

loans

Loan calculations and amortization.

cashflow

Cash flow analysis and investment evaluation.

Basic TVM Calculations (qfinbox.tvm.basic)

Fundamental time value of money calculations for present value, future value, interest rates, and time periods.

Basic Time Value of Money calculations.

qfinbox.tvm.basic.future_value(present_value: float, rate: float, periods: int, compounding_frequency: int = 1) float[source]

Calculate future value of a present amount.

Parameters:
  • present_value (float) – Present value amount.

  • rate (float) – Annual interest rate (as decimal, e.g., 0.05 for 5%).

  • periods (int) – Number of periods.

  • compounding_frequency (int, default 1) – Number of times interest is compounded per period.

Returns:

Future value.

Return type:

float

Raises:

ValidationError – If any parameter is invalid.

Examples

>>> future_value(1000, 0.05, 10)
1628.89
qfinbox.tvm.basic.present_value(future_value: float, rate: float, periods: int, compounding_frequency: int = 1) float[source]

Calculate present value of a future amount.

Parameters:
  • future_value (float) – Future value amount.

  • rate (float) – Annual interest rate (as decimal).

  • periods (int) – Number of periods.

  • compounding_frequency (int, default 1) – Number of times interest is compounded per period.

Returns:

Present value.

Return type:

float

Examples

>>> present_value(1628.89, 0.05, 10)
1000.0
qfinbox.tvm.basic.interest_rate(present_value: float, future_value: float, periods: int, compounding_frequency: int = 1) float[source]

Calculate interest rate given present value, future value, and periods.

Parameters:
  • present_value (float) – Present value amount.

  • future_value (float) – Future value amount.

  • periods (int) – Number of periods.

  • compounding_frequency (int, default 1) – Number of times interest is compounded per period.

Returns:

Annual interest rate (as decimal).

Return type:

float

Raises:

ValidationError – If any parameter is invalid.

Examples

>>> interest_rate(1000, 1628.89, 10)
0.05
qfinbox.tvm.basic.number_of_periods(present_value: float, future_value: float, rate: float, compounding_frequency: int = 1) float[source]

Calculate number of periods required for present value to grow to future value.

Parameters:
  • present_value (float) – Present value amount.

  • future_value (float) – Future value amount.

  • rate (float) – Annual interest rate (as decimal).

  • compounding_frequency (int, default 1) – Number of times interest is compounded per period.

Returns:

Number of periods required.

Return type:

float

Raises:

ValidationError – If any parameter is invalid.

Examples

>>> number_of_periods(1000, 3000, 0.12)
9.69
qfinbox.tvm.basic.compound_interest(principal: float, rate: float, periods: int, compounding_frequency: int = 1) float[source]

Calculate compound interest earned.

Parameters:
  • principal (float) – Initial principal amount.

  • rate (float) – Annual interest rate (as decimal).

  • periods (int) – Number of periods.

  • compounding_frequency (int, default 1) – Number of times interest is compounded per period.

Returns:

Compound interest earned.

Return type:

float

Examples

>>> compound_interest(1000, 0.05, 10)
628.89
qfinbox.tvm.basic.effective_rate(nominal_rate: float, compounding_frequency: int) float[source]

Calculate effective annual rate from nominal rate.

Parameters:
  • nominal_rate (float) – Nominal annual interest rate (as decimal).

  • compounding_frequency (int) – Number of compounding periods per year.

Returns:

Effective annual rate.

Return type:

float

Examples

>>> effective_rate(0.12, 12)  # 12% compounded monthly
0.1268
qfinbox.tvm.basic.nominal_rate(effective_rate: float, compounding_frequency: int) float[source]

Calculate nominal rate from effective annual rate.

Parameters:
  • effective_rate (float) – Effective annual interest rate (as decimal).

  • compounding_frequency (int) – Number of compounding periods per year.

Returns:

Nominal annual rate.

Return type:

float

Examples

>>> nominal_rate(0.1268, 12)  # Effective 12.68% compounded monthly
0.12
qfinbox.tvm.basic.continuous_compounding_fv(present_value: float, rate: float, time: float) float[source]

Calculate future value with continuous compounding.

Parameters:
  • present_value (float) – Present value amount.

  • rate (float) – Annual interest rate (as decimal).

  • time (float) – Time period in years.

Returns:

Future value with continuous compounding.

Return type:

float

Examples

>>> continuous_compounding_fv(1000, 0.05, 10)
1648.72
qfinbox.tvm.basic.continuous_compounding_pv(future_value: float, rate: float, time: float) float[source]

Calculate present value with continuous compounding.

Parameters:
  • future_value (float) – Future value amount.

  • rate (float) – Annual interest rate (as decimal).

  • time (float) – Time period in years.

Returns:

Present value with continuous compounding.

Return type:

float

Examples

>>> continuous_compounding_pv(1648.72, 0.05, 10)
1000.0

Key Functions:

  • present_value() - Calculate present value given future value, rate, and periods

  • future_value() - Calculate future value given present value, rate, and periods

  • interest_rate() - Calculate interest rate given present/future values and periods

  • number_of_periods() - Calculate number of periods given present/future values and rate

  • effective_rate() - Convert nominal rate to effective annual rate

  • nominal_rate() - Convert effective rate to nominal rate with compounding

Annuities (qfinbox.tvm.annuities)

Calculations for ordinary annuities, annuities due, perpetuities, and growing annuities.

Annuity calculations.

qfinbox.tvm.annuities.ordinary_annuity_pv(payment: float, rate: float, periods: int) float[source]

Calculate present value of ordinary annuity.

Parameters:
  • payment (float) – Periodic payment amount.

  • rate (float) – Interest rate per period (as decimal).

  • periods (int) – Number of periods.

Returns:

Present value of ordinary annuity.

Return type:

float

Examples

>>> ordinary_annuity_pv(1000, 0.05, 10)
7721.73
qfinbox.tvm.annuities.ordinary_annuity_fv(payment: float, rate: float, periods: int) float[source]

Calculate future value of ordinary annuity.

Parameters:
  • payment (float) – Periodic payment amount.

  • rate (float) – Interest rate per period (as decimal).

  • periods (int) – Number of periods.

Returns:

Future value of ordinary annuity.

Return type:

float

Examples

>>> ordinary_annuity_fv(1000, 0.05, 10)
12577.89
qfinbox.tvm.annuities.annuity_due_pv(payment: float, rate: float, periods: int) float[source]

Calculate present value of annuity due.

Parameters:
  • payment (float) – Periodic payment amount.

  • rate (float) – Interest rate per period (as decimal).

  • periods (int) – Number of periods.

Returns:

Present value of annuity due.

Return type:

float

Examples

>>> annuity_due_pv(1000, 0.05, 10)
8107.82
qfinbox.tvm.annuities.annuity_due_fv(payment: float, rate: float, periods: int) float[source]

Calculate future value of annuity due.

Parameters:
  • payment (float) – Periodic payment amount.

  • rate (float) – Interest rate per period (as decimal).

  • periods (int) – Number of periods.

Returns:

Future value of annuity due.

Return type:

float

Examples

>>> annuity_due_fv(1000, 0.05, 10)
13206.79
qfinbox.tvm.annuities.annuity_pv(payment: float, rate: float, periods: int, due: bool = False) float[source]

Calculate present value of annuity (ordinary or due).

Parameters:
  • payment (float) – Periodic payment amount.

  • rate (float) – Interest rate per period (as decimal).

  • periods (int) – Number of periods.

  • due (bool, default False) – If True, calculate annuity due. If False, ordinary annuity.

Returns:

Present value of annuity.

Return type:

float

qfinbox.tvm.annuities.annuity_fv(payment: float, rate: float, periods: int, due: bool = False) float[source]

Calculate future value of annuity (ordinary or due).

Parameters:
  • payment (float) – Periodic payment amount.

  • rate (float) – Interest rate per period (as decimal).

  • periods (int) – Number of periods.

  • due (bool, default False) – If True, calculate annuity due. If False, ordinary annuity.

Returns:

Future value of annuity.

Return type:

float

qfinbox.tvm.annuities.perpetuity_value(payment: float, rate: float) float[source]

Calculate present value of a perpetuity.

A perpetuity is a stream of equal payments that continues forever.

Parameters:
  • payment (float) – Periodic payment amount.

  • rate (float) – Interest rate per period (as decimal).

Returns:

Present value of perpetuity.

Return type:

float

Raises:

ValidationError – If any parameter is invalid.

Examples

>>> perpetuity_value(50000, 0.04)
1250000.0

Notes

The formula for a perpetuity is simply: PV = Payment / Rate

qfinbox.tvm.annuities.growing_annuity_pv(payment: float, rate: float, growth_rate: float, periods: int) float[source]

Calculate present value of a growing annuity.

A growing annuity has payments that grow at a constant rate each period.

Parameters:
  • payment (float) – Initial payment amount.

  • rate (float) – Interest rate per period (as decimal).

  • growth_rate (float) – Growth rate of payments per period (as decimal).

  • periods (int) – Number of periods.

Returns:

Present value of growing annuity.

Return type:

float

Raises:

ValidationError – If any parameter is invalid.

Examples

>>> growing_annuity_pv(2, 0.09, 0.05, 20)
24.36

Notes

If rate equals growth_rate, the formula becomes: PV = PMT * n / (1 + r) Otherwise: PV = PMT * [(1 - ((1 + g) / (1 + r))^n) / (r - g)]

Key Functions:

  • pv_ordinary_annuity() - Present value of ordinary annuity

  • fv_ordinary_annuity() - Future value of ordinary annuity

  • pv_annuity_due() - Present value of annuity due

  • fv_annuity_due() - Future value of annuity due

  • perpetuity_value() - Value of perpetual annuity

  • growing_annuity_pv() - Present value of growing annuity

  • growing_perpetuity_value() - Value of growing perpetuity

Bond Valuation (qfinbox.tvm.bonds)

Comprehensive bond pricing, yield calculations, and risk measures.

Bond valuation and analysis.

qfinbox.tvm.bonds.bond_price(face_value: float, coupon_rate: float, years_to_maturity: float, yield_to_maturity: float, payments_per_year: int = 2) float[source]

Calculate bond price given yield to maturity.

Parameters:
  • face_value (float) – Face value of the bond.

  • coupon_rate (float) – Annual coupon rate (as decimal).

  • years_to_maturity (float) – Years until maturity.

  • yield_to_maturity (float) – Yield to maturity (as decimal).

  • payments_per_year (int, default 2) – Number of coupon payments per year.

Returns:

Bond price.

Return type:

float

Examples

>>> bond_price(1000, 0.06, 10, 0.08)
864.10
qfinbox.tvm.bonds.bond_yield_to_maturity(price: float, face_value: float, coupon_rate: float, years_to_maturity: float, payments_per_year: int = 2) float[source]

Calculate bond yield to maturity given price.

Parameters:
  • price (float) – Current bond price.

  • face_value (float) – Face value of the bond.

  • coupon_rate (float) – Annual coupon rate (as decimal).

  • years_to_maturity (float) – Years until maturity.

  • payments_per_year (int, default 2) – Number of coupon payments per year.

Returns:

Yield to maturity (as decimal).

Return type:

float

Examples

>>> bond_yield_to_maturity(864.10, 1000, 0.06, 10)
0.08
qfinbox.tvm.bonds.bond_duration(face_value: float, coupon_rate: float, years_to_maturity: float, yield_to_maturity: float, payments_per_year: int = 2) float[source]

Calculate Macaulay duration of a bond.

Parameters:
  • face_value (float) – Face value of the bond.

  • coupon_rate (float) – Annual coupon rate (as decimal).

  • years_to_maturity (float) – Years until maturity.

  • yield_to_maturity (float) – Yield to maturity (as decimal).

  • payments_per_year (int, default 2) – Number of coupon payments per year.

Returns:

Macaulay duration in years.

Return type:

float

Examples

>>> bond_duration(1000, 0.06, 10, 0.08)
7.25
qfinbox.tvm.bonds.bond_modified_duration(face_value: float, coupon_rate: float, years_to_maturity: float, yield_to_maturity: float, payments_per_year: int = 2) float[source]

Calculate modified duration of a bond.

Parameters:
  • face_value (float) – Face value of the bond.

  • coupon_rate (float) – Annual coupon rate (as decimal).

  • years_to_maturity (float) – Years until maturity.

  • yield_to_maturity (float) – Yield to maturity (as decimal).

  • payments_per_year (int, default 2) – Number of coupon payments per year.

Returns:

Modified duration.

Return type:

float

Examples

>>> bond_modified_duration(1000, 0.06, 10, 0.08)
6.71
qfinbox.tvm.bonds.bond_convexity(face_value: float, coupon_rate: float, years_to_maturity: float, yield_to_maturity: float, payments_per_year: int = 2) float[source]

Calculate convexity of a bond.

Parameters:
  • face_value (float) – Face value of the bond.

  • coupon_rate (float) – Annual coupon rate (as decimal).

  • years_to_maturity (float) – Years until maturity.

  • yield_to_maturity (float) – Yield to maturity (as decimal).

  • payments_per_year (int, default 2) – Number of coupon payments per year.

Returns:

Convexity.

Return type:

float

Examples

>>> bond_convexity(1000, 0.06, 10, 0.08)
64.93

Key Functions:

  • bond_price() - Calculate bond price given coupon rate and market yield

  • bond_yield() - Calculate yield to maturity given bond price

  • bond_duration() - Calculate modified duration for interest rate sensitivity

  • bond_convexity() - Calculate convexity for advanced interest rate risk

  • zero_coupon_bond_price() - Price zero-coupon bonds

  • zero_coupon_bond_yield() - Calculate yield for zero-coupon bonds

Loan Analysis (qfinbox.tvm.loans)

Comprehensive loan calculations including payments, balances, and amortization schedules.

Loan calculations and amortization.

qfinbox.tvm.loans.loan_payment(principal: float, annual_rate: float, years: float, payments_per_year: int = 12) float[source]

Calculate periodic loan payment.

Parameters:
  • principal (float) – Loan principal amount.

  • annual_rate (float) – Annual interest rate (as decimal).

  • years (float) – Loan term in years.

  • payments_per_year (int, default 12) – Number of payments per year.

Returns:

Periodic payment amount.

Return type:

float

Examples

>>> loan_payment(300000, 0.05, 30)
1610.46
qfinbox.tvm.loans.loan_balance(principal: float, annual_rate: float, years: float, payments_made: int, payments_per_year: int = 12) float[source]

Calculate remaining loan balance after specified payments.

Parameters:
  • principal (float) – Original loan principal amount.

  • annual_rate (float) – Annual interest rate (as decimal).

  • years (float) – Loan term in years.

  • payments_made (int) – Number of payments already made.

  • payments_per_year (int, default 12) – Number of payments per year.

Returns:

Remaining loan balance.

Return type:

float

Examples

>>> loan_balance(300000, 0.05, 30, 120)
260108.58
qfinbox.tvm.loans.total_interest_paid(principal: float, annual_rate: float, years: float, payments_per_year: int = 12) float[source]

Calculate total interest paid over the life of the loan.

Parameters:
  • principal (float) – Loan principal amount.

  • annual_rate (float) – Annual interest rate (as decimal).

  • years (float) – Loan term in years.

  • payments_per_year (int, default 12) – Number of payments per year.

Returns:

Total interest paid.

Return type:

float

Examples

>>> total_interest_paid(300000, 0.05, 30)
279767.35
qfinbox.tvm.loans.amortization_schedule(principal: float, annual_rate: float, years: float, payments_per_year: int = 12) DataFrame[source]

Generate loan amortization schedule.

Parameters:
  • principal (float) – Loan principal amount.

  • annual_rate (float) – Annual interest rate (as decimal).

  • years (float) – Loan term in years.

  • payments_per_year (int, default 12) – Number of payments per year.

Returns:

Amortization schedule with columns: Payment, Interest, Principal, Balance.

Return type:

pd.DataFrame

Examples

>>> schedule = amortization_schedule(300000, 0.05, 30)
>>> schedule.head()
   Payment  Interest   Principal      Balance
0  1610.46   1250.00     360.46   299639.54
1  1610.46   1248.50     361.96   299277.58

Key Functions:

  • loan_payment() - Calculate periodic loan payment

  • loan_balance() - Calculate remaining loan balance

  • amortization_schedule() - Generate detailed amortization schedule

  • total_interest_paid() - Calculate total interest over loan life

  • loan_affordability() - Determine maximum affordable loan amount

Cash Flow Analysis (qfinbox.tvm.cashflow)

Investment analysis tools including NPV, IRR, payback period, and profitability metrics.

Cash flow analysis and investment evaluation.

qfinbox.tvm.cashflow.net_present_value(cash_flows: List[float] | ndarray, discount_rate: float) float[source]

Calculate net present value of cash flows.

Parameters:
  • cash_flows (array-like) – Series of cash flows, with initial investment as negative value.

  • discount_rate (float) – Discount rate (as decimal).

Returns:

Net present value.

Return type:

float

Examples

>>> cash_flows = [-100000, 30000, 40000, 50000]
>>> net_present_value(cash_flows, 0.10)
4349.34
qfinbox.tvm.cashflow.internal_rate_of_return(cash_flows: List[float] | ndarray, initial_guess: float = 0.1) float[source]

Calculate internal rate of return for cash flows.

Parameters:
  • cash_flows (array-like) – Series of cash flows, with initial investment as negative value.

  • initial_guess (float, default 0.1) – Initial guess for IRR calculation.

Returns:

Internal rate of return (as decimal).

Return type:

float

Examples

>>> cash_flows = [-100000, 30000, 40000, 50000]
>>> internal_rate_of_return(cash_flows)
0.1627
qfinbox.tvm.cashflow.payback_period(cash_flows: List[float] | ndarray) float[source]

Calculate payback period for cash flows.

Parameters:

cash_flows (array-like) – Series of cash flows, with initial investment as negative value.

Returns:

Payback period in years.

Return type:

float

Examples

>>> cash_flows = [-100000, 30000, 40000, 50000]
>>> payback_period(cash_flows)
2.6
qfinbox.tvm.cashflow.discounted_payback_period(cash_flows: List[float] | ndarray, discount_rate: float) float[source]

Calculate discounted payback period for cash flows.

Parameters:
  • cash_flows (array-like) – Series of cash flows, with initial investment as negative value.

  • discount_rate (float) – Discount rate (as decimal).

Returns:

Discounted payback period in years.

Return type:

float

Examples

>>> cash_flows = [-100000, 30000, 40000, 50000]
>>> discounted_payback_period(cash_flows, 0.10)
2.8
qfinbox.tvm.cashflow.profitability_index(cash_flows: List[float] | ndarray, discount_rate: float) float[source]

Calculate profitability index for cash flows.

Parameters:
  • cash_flows (array-like) – Series of cash flows, with initial investment as negative value.

  • discount_rate (float) – Discount rate (as decimal).

Returns:

Profitability index.

Return type:

float

Examples

>>> cash_flows = [-100000, 30000, 40000, 50000]
>>> profitability_index(cash_flows, 0.10)
1.043

Key Functions:

  • npv() - Net Present Value calculation

  • irr() - Internal Rate of Return calculation

  • mirr() - Modified Internal Rate of Return

  • payback_period() - Simple payback period calculation

  • discounted_payback_period() - Discounted payback period

  • profitability_index() - Profitability index for investment ranking

Mathematical Foundations

All TVM calculations in qfinbox are based on fundamental financial mathematics:

Present Value Formula:

\[\begin{split}PV = \\frac{FV}{(1 + r)^n}\end{split}\]

Future Value Formula:

\[\begin{split}FV = PV \\times (1 + r)^n\end{split}\]

Annuity Present Value:

\[\begin{split}PV = PMT \\times \\frac{1 - (1 + r)^{-n}}{r}\end{split}\]

Bond Pricing:

\[\begin{split}P = \\sum_{t=1}^{n} \\frac{C}{(1 + r)^t} + \\frac{F}{(1 + r)^n}\end{split}\]

Where: - PV = Present Value - FV = Future Value - PMT = Payment - r = Interest Rate per period - n = Number of periods - C = Coupon payment - F = Face value - P = Bond price

Performance and Accuracy

The qfinbox TVM module is optimized for both performance and accuracy:

  • NumPy Integration: Uses NumPy arrays for vectorized calculations

  • SciPy Optimization: Leverages SciPy for complex root-finding (IRR, yield calculations)

  • Input Validation: Comprehensive validation prevents calculation errors

  • Error Handling: Graceful handling of edge cases and invalid inputs

  • Type Safety: Full type hints for IDE support and runtime checking

Usage Patterns

Single Value Calculations:

from qfinbox.tvm import basic

pv = basic.present_value(fv=1000, rate=0.05, periods=10)

Array-based Calculations:

import numpy as np
from qfinbox.tvm import basic

# Calculate PV for multiple scenarios
fv_values = np.array([1000, 2000, 3000])
rates = np.array([0.05, 0.06, 0.07])
periods = np.array([5, 10, 15])

pv_results = basic.present_value(fv=fv_values, rate=rates, periods=periods)

Complex Financial Modeling:

from qfinbox.tvm import cashflow, loans

# Combine multiple TVM functions for complex analysis
principal = 100000
rate = 0.05/12
periods = 30*12

payment = loans.loan_payment(principal, rate, periods)

# Create cash flow stream for NPV analysis
cash_flows = [-principal] + [payment] * periods
npv = cashflow.npv(rate=0.06/12, cash_flows=cash_flows)