Financial Calculations with NumberF
View SourceThis guide explains how to use NumberF for financial calculations in your Elixir applications. From basic interest calculations to complex loan amortization, NumberF provides the tools you need for finance-related software.
Basic Interest Calculations
Simple Interest
Simple interest is calculated on the principal amount only:
# Calculate simple interest (principal, rate, time in years)
NumberF.simple_interest(1000, 0.05, 2) # => 100.0
# $1000 at 5% for 2 years = $100 interest
# For larger amounts
NumberF.simple_interest(50000, 0.03, 5) # => 7500.0
# $50,000 at 3% for 5 years = $7,500 interest
Compound Interest
Compound interest is calculated on both the principal and the accumulated interest:
# Annual compounding (default)
NumberF.compound_interest(1000, 0.05, 2) # => 102.5
# $1000 at 5% for 2 years with annual compounding = $102.50 interest
# Monthly compounding (frequency = 12)
NumberF.compound_interest(1000, 0.05, 2, 12) # => 104.94
# $1000 at 5% for 2 years with monthly compounding = $104.94 interest
# Quarterly compounding (frequency = 4)
NumberF.compound_interest(10000, 0.04, 10, 4) # => 4889.32
# $10,000 at 4% for 10 years with quarterly compounding = $4,889.32 interest
Loan Calculations
Monthly Installment (EMI)
Calculate the Equated Monthly Installment for a loan:
# Calculate EMI (principal, annual rate, term in months)
NumberF.calculate_emi(100000, 0.10, 12) # => 8791.59
# $100,000 loan at 10% annual interest for 12 months = $8,791.59 monthly payment
# Home loan example
NumberF.calculate_emi(250000, 0.045, 360) # => 1266.71
# $250,000 mortgage at 4.5% for 30 years (360 months) = $1,266.71 monthly payment
Tax Calculations
Value Added Tax (VAT)
# Calculate VAT (amount, rate)
NumberF.calculate_vat(100, 0.2)
# => %{net: 100.0, vat: 20.0, gross: 120.0}
# Calculate VAT from inclusive amount
NumberF.calculate_vat(120, 0.2, true)
# => %{net: 100.0, vat: 20.0, gross: 120.0}
Sales Tax
# Calculate sales tax (amount, rate)
NumberF.calculate_sales_tax(100, 0.06)
# => %{subtotal: 100.0, tax: 6.0, total: 106.0}
# With custom rounding
NumberF.calculate_sales_tax(100, 0.0625, round_to: 0.05)
# => %{subtotal: 100.0, tax: 6.25, total: 106.25}
Income Tax
# UK tax brackets example
brackets = [{0, 0.0}, {12570, 0.2}, {50270, 0.4}, {150000, 0.45}]
# Calculate income tax
NumberF.Tax.calculate_income_tax(30000, brackets)
# => %{tax: 3486.0, effective_rate: 0.1162}
# £30,000 salary results in £3,486 tax (11.62% effective rate)
Currency Conversion
Convert amounts between currencies:
# Basic conversion (amount, from_rate, to_rate)
NumberF.convert_currency(100, 1, 0.85) # => 85.0
# $100 USD converted to EUR at 0.85 EUR/USD rate
# Multi-currency calculation
amount_usd = 1000
usd_to_eur_rate = 0.92
usd_to_gbp_rate = 0.79
amount_eur = NumberF.convert_currency(amount_usd, 1, usd_to_eur_rate) # => 920.0
amount_gbp = NumberF.convert_currency(amount_usd, 1, usd_to_gbp_rate) # => 790.0
Investment Analysis
Combining various functions for investment analysis:
# Investment growth projection
initial_investment = 10000
annual_rate = 0.07
years = 30
compounding_frequency = 12
final_value = initial_investment + NumberF.compound_interest(
initial_investment,
annual_rate,
years,
compounding_frequency
)
formatted_result = NumberF.currency(final_value, "$")
# => "$ 76,122.51" after 30 years
# Calculate effective annual rate with monthly compounding
effective_rate = (1 + annual_rate/12) ** 12 - 1
annual_percentage = NumberF.percentage(effective_rate, 1, 2)
# => 7.23%
Loan Amortization Table
Example of creating a loan amortization schedule using NumberF:
defmodule LoanCalculator do
def generate_amortization_schedule(principal, annual_rate, term_months) do
# Calculate monthly payment
monthly_payment = NumberF.calculate_emi(principal, annual_rate, term_months)
# Generate schedule
monthly_rate = annual_rate / 12
Enum.reduce(1..term_months, {principal, []}, fn month, {remaining_principal, acc} ->
# Calculate interest for this period
interest_payment = remaining_principal * monthly_rate
# Calculate principal for this period
principal_payment = monthly_payment - interest_payment
# Calculate new remaining principal
new_remaining = remaining_principal - principal_payment
# Create payment record
payment = %{
month: month,
payment: NumberF.round_with_precision(monthly_payment, 2),
principal: NumberF.round_with_precision(principal_payment, 2),
interest: NumberF.round_with_precision(interest_payment, 2),
remaining: max(0, NumberF.round_with_precision(new_remaining, 2))
}
# Add to accumulator and continue
{new_remaining, [payment | acc]}
end)
|> elem(1)
|> Enum.reverse()
end
def print_amortization_schedule(schedule) do
IO.puts "Month | Payment | Principal | Interest | Remaining"
IO.puts "------|---------|-----------|----------|----------"
Enum.each(schedule, fn %{month: month, payment: payment, principal: principal,
interest: interest, remaining: remaining} ->
IO.puts "#{String.pad_leading("#{month}", 5)} | #{NumberF.currency(payment, "$", 2)} | " <>
"#{NumberF.currency(principal, "$", 2)} | " <>
"#{NumberF.currency(interest, "$", 2)} | " <>
"#{NumberF.currency(remaining, "$", 2)}"
end)
end
end
# Example usage:
schedule = LoanCalculator.generate_amortization_schedule(10000, 0.06, 12)
LoanCalculator.print_amortization_schedule(schedule)
Real Estate Financial Analysis
Example of real estate investment analysis:
defmodule RealEstateAnalysis do
def calculate_roi(purchase_price, closing_costs, repair_costs, annual_rental_income,
annual_expenses, years_held, estimated_sale_price) do
# Total investment
total_investment = purchase_price + closing_costs + repair_costs
# Annual cash flow
annual_cash_flow = annual_rental_income - annual_expenses
# Total cash flow over holding period
total_cash_flow = annual_cash_flow * years_held
# Profit from sale (simplified, not accounting for taxes)
sale_profit = estimated_sale_price - purchase_price
# Total profit
total_profit = total_cash_flow + sale_profit
# Calculate ROI
roi = NumberF.percentage(total_profit, total_investment, 2)
# Calculate annual ROI
annual_roi = NumberF.percentage(total_profit / years_held, total_investment, 2)
# Return analysis
%{
total_investment: NumberF.currency(total_investment, "$"),
total_cash_flow: NumberF.currency(total_cash_flow, "$"),
sale_profit: NumberF.currency(sale_profit, "$"),
total_profit: NumberF.currency(total_profit, "$"),
roi: "#{roi}%",
annual_roi: "#{annual_roi}%"
}
end
end
# Example usage:
analysis = RealEstateAnalysis.calculate_roi(
200000, # Purchase price
5000, # Closing costs
15000, # Repair costs
24000, # Annual rental income
10000, # Annual expenses
5, # Years held
250000 # Estimated sale price
)
# Result would show total ROI and annualized ROI for the investment
Best Practices for Financial Calculations
- Use appropriate precision - Financial calculations often require specific rounding rules
- Be careful with floating point - Use
NumberF.round_with_precision/2
to handle precision issues - Document your assumptions - Financial formulas often make assumptions about compounding periods, etc.
- Validate input data - Financial calculations are sensitive to incorrect inputs
- Use explicit parameter names - Makes your code more readable and less error-prone
NumberF provides a solid foundation for financial calculations in Elixir applications, from simple interest to complex investment analysis. By combining these tools with Elixir's excellent pattern matching and functional programming features, you can build robust financial software with clear, maintainable code.