Finex (finex v0.1.1)

View Source

Professional financial calculations for Elixir applications.

Finex provides accurate, battle-tested financial calculations with decimal precision and comprehensive coverage of common financial scenarios, including advanced inflation-adjusted planning.

Features

  • ๐ŸŽฏ Precision: Uses Decimal for all calculations to avoid floating-point errors
  • ๐Ÿ“Š Comprehensive: Covers investments, savings, and inflation analysis
  • ๐Ÿ  Real-World Ready: Inflation-adjusted goal planning for moving targets
  • ๐Ÿš€ Performance: Optimized for production fintech applications
  • ๐Ÿงช Tested: Extensive test coverage with real-world scenarios
  • ๐Ÿ’ฐ Fee Transparency: Separate yield and fees for accurate calculations

Quick Start

# Calculate investment outcome with yield and fees
iex> Finex.investment_outcome(1000, 500, 5, 0.07, 0.01)
{:ok, %{final_amount: Decimal.new("36228.25"), total_contributions: Decimal.new("31000.00"), total_interest: Decimal.new("5228.25"), initial_growth: Decimal.new("1348.46"), monthly_growth: Decimal.new("34879.79")}}

# Calculate timeline for fixed savings goal
iex> Finex.savings_timeline(10_000, 500, 0.05, 0.0)
{:ok, %{years: 1.6, months: 19.25}}

# Calculate timeline for inflation-adjusted goal (NEW!)
iex> Finex.inflation_adjusted_timeline(60_000, 1200, 0.04, 0.07, 0.01)
{:ok, %{years: 4.34, months: 52.05}}

# Analyze inflation impact on purchasing power
iex> Finex.inflation_impact(1_000_000, 4, 0.03)
{:ok, %{future_nominal_value: Decimal.new("1000000.00"), purchasing_power: Decimal.new("888487.05"), purchasing_power_loss: Decimal.new("111512.95"), purchasing_power_percentage: 88.85}}

Core Module

Summary

Functions

Calculate the time required to double an investment (Rule of 72 refined).

Analyze investment goal feasibility given income constraints.

Calculate progress percentage toward investment goal.

Calculate future purchasing power accounting for inflation.

Calculate final investment outcome with initial and monthly contributions.

Calculate timeline for lump sum investment to grow to target.

Calculate required monthly contribution to reach investment goal.

Calculate timeline to reach savings goal using monthly contributions.

Types

amount()

@type amount() :: Decimal.t() | number()

period()

@type period() :: pos_integer()

rate()

@type rate() :: float()

Functions

doubling_time(annual_yield, annual_fees \\ 0.0)

@spec doubling_time(rate(), rate()) :: {:ok, float()} | {:error, atom()}

Calculate the time required to double an investment (Rule of 72 refined).

Uses the net return rate after accounting for fees to provide accurate doubling time.

Parameters

  • annual_yield - Annual return rate before fees
  • annual_fees - Annual fees (default: 0)

Examples

iex> Finex.doubling_time(0.07, 0.01)
{:ok, 11.59}

iex> Finex.doubling_time(0.08, 0.0)
{:ok, 8.69}

goal_feasibility(monthly_income, target, initial, years, annual_yield, annual_fees \\ 0.0)

@spec goal_feasibility(amount(), amount(), amount(), number(), rate(), rate()) ::
  {:ok, map()} | {:error, atom()}

Analyze investment goal feasibility given income constraints.

Parameters

  • monthly_income - Monthly take-home income
  • target - Investment goal
  • initial - Initial investment
  • years - Timeline in years
  • annual_yield - Expected return
  • annual_fees - Annual fees (default: 0)

Examples

iex> Finex.goal_feasibility(5000, 50_000, 0, 5, 0.07, 0.01)
{:ok, %{difficulty: :moderate, income_percentage: 14.34, recommendation: "Reasonable goal with good budgeting", required_monthly: Decimal.new("716.75")}}

goal_progress(current, target)

@spec goal_progress(amount(), amount()) :: {:ok, float()} | {:error, atom()}

Calculate progress percentage toward investment goal.

Parameters

  • current - Current investment value
  • target - Target investment amount

Examples

iex> Finex.goal_progress(7_500, 10_000)
{:ok, 75.0}

inflation_adjusted_timeline(present_goal, monthly_contribution, inflation_rate, annual_yield, annual_fees \\ 0.0)

@spec inflation_adjusted_timeline(amount(), amount(), rate(), rate(), rate()) ::
  {:ok, %{years: float(), months: float()}} | {:error, atom()}

Calculate timeline to reach inflation-adjusted savings goal.

Determines how long it will take to save for a goal whose cost increases with inflation over time, accounting for the moving target effect.

Parameters

  • present_goal - Cost of the goal in today's purchasing power
  • monthly_contribution - Fixed monthly savings amount
  • inflation_rate - Annual inflation rate for the goal
  • annual_yield - Expected annual return before fees
  • annual_fees - Annual fees and expenses (default: 0)

Examples

# House down payment with real estate inflation
iex> Finex.inflation_adjusted_timeline(60_000, 1200, 0.04, 0.07, 0.01)
{:ok, %{years: 4.34, months: 52.05}}

# College costs with education inflation
iex> Finex.inflation_adjusted_timeline(50_000, 800, 0.06, 0.06, 0.005)
{:ok, %{years: 6.31, months: 75.72}}

inflation_impact(amount_today, years, inflation_rate)

@spec inflation_impact(amount(), number(), rate()) :: {:ok, map()} | {:error, atom()}

Calculate future purchasing power accounting for inflation.

Parameters

  • amount_today - Current amount
  • years - Number of years in the future
  • inflation_rate - Annual inflation rate

Examples

iex> Finex.inflation_impact(1_000_000, 4, 0.03)
{:ok, %{future_nominal_value: Decimal.new("1000000.00"), purchasing_power: Decimal.new("888487.05"), purchasing_power_loss: Decimal.new("111512.95"), purchasing_power_percentage: 88.85}}

investment_outcome(initial, monthly, years, annual_yield, annual_fees \\ 0.0)

@spec investment_outcome(amount(), amount(), number(), rate(), rate()) ::
  {:ok, map()} | {:error, atom()}

Calculate final investment outcome with initial and monthly contributions.

Parameters

  • initial - Initial lump sum investment
  • monthly - Monthly contribution amount
  • years - Investment period in years
  • annual_yield - Expected annual return before fees
  • annual_fees - Annual fees and expenses

Examples

iex> Finex.investment_outcome(1000, 500, 5, 0.07, 0.01)
{:ok, %{final_amount: Decimal.new("36228.25"), total_contributions: Decimal.new("31000.00"), total_interest: Decimal.new("5228.25"), initial_growth: Decimal.new("1348.46"), monthly_growth: Decimal.new("34879.79")}}

lump_sum_timeline(target, initial, annual_yield, annual_fees \\ 0.0)

@spec lump_sum_timeline(amount(), amount(), rate(), rate()) ::
  {:ok, %{years: float(), months: integer()}} | {:error, atom()}

Calculate timeline for lump sum investment to grow to target.

Parameters

  • target - Target investment amount
  • initial - Initial lump sum investment
  • annual_yield - Expected annual return
  • annual_fees - Annual fees (default: 0)

Examples

iex> Finex.lump_sum_timeline(10_000, 5_000, 0.07, 0.0)
{:ok, %{years: 10.0, months: 120}}

monthly_needed(target, initial, years, annual_yield, annual_fees \\ 0.0)

@spec monthly_needed(amount(), amount(), number(), rate(), rate()) ::
  {:ok, Decimal.t()} | {:error, atom()}

Calculate required monthly contribution to reach investment goal.

Parameters

  • target - Target investment amount
  • initial - Initial investment
  • years - Investment period in years
  • annual_yield - Expected annual return
  • annual_fees - Annual fees (default: 0)

Examples

iex> Finex.monthly_needed(60_000, 5_000, 5, 0.06, 0.01)
{:ok, Decimal.new("788.04")}

savings_timeline(target, monthly, annual_yield, annual_fees \\ 0.0)

@spec savings_timeline(amount(), amount(), rate(), rate()) ::
  {:ok, %{years: float(), months: integer()}} | {:error, atom()}

Calculate timeline to reach savings goal using monthly contributions.

Parameters

  • target - Target savings amount
  • monthly - Monthly contribution
  • annual_yield - Expected annual return
  • annual_fees - Annual fees (default: 0)

Examples

iex> Finex.savings_timeline(10_000, 500, 0.05, 0.0)
{:ok, %{years: 1.6, months: 19.25}}