Finex ๐ฐ
Professional financial calculations for Elixir applications with fee transparency and decimal precision.
Finex provides accurate, battle-tested financial calculations with decimal precision and comprehensive coverage of real-world financial scenarios. Built for production fintech applications that demand reliability and transparency.
Features
-
๐ฏ Decimal Precision: Uses
Decimalfor all calculations to avoid floating-point errors - ๐ฐ Fee Transparency: Separate yield and fees parameters for accurate net return calculations
- ๐ Inflation-Adjusted Planning: Calculate timelines for goals that grow with inflation (NEW in v0.1.1!)
- ๐ Production Ready: Optimized for fintech applications with comprehensive error handling
- ๐งช Battle Tested: Extensive test coverage with real-world scenarios
- ๐ Comprehensive: Covers investment outcomes, timelines, feasibility analysis, and inflation impact
- โจ Clean API: Consistent parameter ordering with optional fees as the last parameter
Installation
Add finex to your list of dependencies in mix.exs:
def deps do
[
{:finex, "~> 0.1.1"}
]
endQuick Start
# Simple calculation without fees - fees default to 0.0
iex> Finex.investment_outcome(1000, 500, 5, 0.07)
{:ok, %{
final_amount: #Decimal<37214.07>,
total_contributions: #Decimal<31000.00>,
total_interest: #Decimal<6214.07>
}}
# Include fees when needed
iex> Finex.investment_outcome(1000, 500, 5, 0.07, 0.01)
{:ok, %{
final_amount: #Decimal<36228.25>,
total_contributions: #Decimal<31000.00>,
total_interest: #Decimal<5228.25>
}}
# How long to save $10k at $500/month with 5% yield?
iex> Finex.savings_timeline(10_000, 500, 0.05)
{:ok, %{years: 1.6, months: 19.25}}
# What's $1M worth in 25 years with 3% inflation?
iex> Finex.inflation_impact(1_000_000, 25, 0.03)
{:ok, %{
purchasing_power: #Decimal<467744.00>,
purchasing_power_percentage: 46.77
}}
# NEW: How long to save for house down payment with price inflation?
iex> Finex.inflation_adjusted_timeline(80_000, 1500, 0.035, 0.07, 0.01)
{:ok, %{years: 4.34, months: 52.05}}Core Functions
Investment Calculations
# Calculate final portfolio value
Finex.investment_outcome(initial, monthly, years, annual_yield, annual_fees \\ 0.0)
# Timeline for monthly savings goal
Finex.savings_timeline(target, monthly, annual_yield, annual_fees \\ 0.0)
# Timeline for lump sum to grow
Finex.lump_sum_timeline(target, initial, annual_yield, annual_fees \\ 0.0)
# Required monthly contribution
Finex.monthly_needed(target, initial, years, annual_yield, annual_fees \\ 0.0)Analysis & Planning
# Goal feasibility analysis
Finex.goal_feasibility(monthly_income, target, initial, years, annual_yield, annual_fees \\ 0.0)
# Track progress toward goal
Finex.goal_progress(current_amount, target_amount)
# Inflation impact analysis
Finex.inflation_impact(amount_today, years, inflation_rate)
# Investment doubling time (Rule of 72)
Finex.doubling_time(annual_yield, annual_fees)
# NEW: Inflation-adjusted goal planning
Finex.inflation_adjusted_timeline(present_goal, monthly_contribution, inflation_rate, annual_yield, annual_fees \\ 0.0)Real-World Examples
Emergency Fund Planning
# Build 6-month emergency fund
monthly_expenses = 3_500
target_fund = monthly_expenses * 6 # $21,000
monthly_savings = 600
# How long will it take?
{:ok, timeline} = Finex.savings_timeline(target_fund, monthly_savings, 0.025, 0.0)
# => %{years: 2.9, months: 35}
# Is this feasible on $5k income?
{:ok, feasibility} = Finex.goal_feasibility(5000, target_fund, 0, 3, 0.025, 0.0)
# => %{difficulty: :moderate, income_percentage: 12.0}House Down Payment
# Save for 20% down payment on $400k house
house_price = 400_000
down_payment = house_price * 0.20 # $80,000
timeline_years = 5
# How much to save monthly (assuming fixed price)?
{:ok, monthly_needed} = Finex.monthly_needed(down_payment, 10_000, timeline_years, 0.04, 0.005)
# => #Decimal<1285.67>
# NEW: Account for house price inflation (3.5% annually)
{:ok, inflation_timeline} = Finex.inflation_adjusted_timeline(down_payment, 1500, 0.035, 0.07, 0.01)
# => %{years: 4.73, months: 56.76}
# Check feasibility
{:ok, analysis} = Finex.goal_feasibility(7000, down_payment, 10_000, timeline_years, 0.04, 0.005)
# => %{difficulty: :moderate, income_percentage: 18.37}Retirement Planning
# 401k contribution analysis
annual_contribution = 23_000 # 2024 limit
monthly_contribution = annual_contribution / 12
years_to_retirement = 30
# Portfolio value at retirement
{:ok, outcome} = Finex.investment_outcome(50_000, monthly_contribution, years_to_retirement, 0.08, 0.005)
# => %{final_amount: #Decimal<2156789.45>}
# Account for inflation impact
{:ok, inflation_impact} = Finex.inflation_impact(outcome.final_amount, 25, 0.025)
# => %{purchasing_power_percentage: 53.94}Investment Analysis
# Compare investment options
option_a = Finex.doubling_time(0.08, 0.005) # Index fund: 8% yield, 0.5% fees
option_b = Finex.doubling_time(0.06, 0.02) # Managed fund: 6% yield, 2% fees
# => Option A: {:ok, 9.31} years
# => Option B: {:ok, 17.67} yearsClean API Design
Finex follows a consistent, intuitive parameter pattern across all functions:
# Pattern: function(core_params..., years, annual_yield, annual_fees \\ 0.0)
# Simple usage - fees default to 0.0
Finex.investment_outcome(1000, 500, 5, 0.07)
Finex.monthly_needed(60_000, 5_000, 5, 0.06)
Finex.goal_feasibility(5000, 50_000, 0, 5, 0.07)
# Include fees when needed (always last parameter)
Finex.investment_outcome(1000, 500, 5, 0.07, 0.01)
Finex.monthly_needed(60_000, 5_000, 5, 0.06, 0.005)
Finex.goal_feasibility(5000, 50_000, 0, 5, 0.07, 0.01)Fee Transparency
Finex requires separate annual_yield and annual_fees parameters for transparent calculations:
# Clear fee structure
annual_yield = 0.07 # 7% expected return
annual_fees = 0.015 # 1.5% total fees (management + expense ratio)
# Finex calculates net return using: (1 + yield/12) * (1 - fees/12) - 1
{:ok, outcome} = Finex.investment_outcome(10_000, 1000, 10, annual_yield, annual_fees)
# Compare with no-fee alternative
{:ok, no_fee_outcome} = Finex.investment_outcome(10_000, 1000, 10, 0.07)Precision & Accuracy
Finex uses Decimal arithmetic for all financial calculations:
# No floating-point errors
{:ok, result} = Finex.investment_outcome(1000, 500.33, 7.5, 0.0725, 0.0125)
# All monetary values are precise Decimal structs
result.final_amount # => #Decimal<52847.39>
result.total_interest # => #Decimal<6847.39>Error Handling
Consistent error tuples with descriptive messages:
# Validation errors
{:error, :negative_amount} = Finex.investment_outcome(-1000, 500, 5, 0.07, 0.01)
{:error, :invalid_rate} = Finex.investment_outcome(1000, 500, 5, -0.05, 0.01)
{:error, :invalid_period} = Finex.investment_outcome(1000, 500, -5, 0.07, 0.01)
# Get user-friendly error messages
Finex.Utils.format_error(:negative_amount) # => "Amount must be non-negative"Phoenix Integration
Works seamlessly with Phoenix and LiveView:
defmodule MyAppWeb.InvestmentLive do
use MyAppWeb, :live_view
def handle_event("calculate", params, socket) do
%{"initial" => initial, "monthly" => monthly, "yield" => yield, "fees" => fees, "years" => years} = params
case Finex.investment_outcome(initial, monthly, years, yield, fees) do
{:ok, result} ->
{:noreply, assign(socket, :result, result)}
{:error, reason} ->
error_message = Finex.Utils.format_error(reason)
{:noreply, put_flash(socket, :error, error_message)}
end
end
endTesting
Comprehensive test coverage with real-world scenarios:
mix test
mix test --coverDocumentation
Generate documentation:
mix docsRoadmap
v0.2.0 - Enhanced Analysis
- Portfolio optimization and rebalancing
- Risk assessment metrics
- Monte Carlo simulations
- Tax-advantaged account calculations
v0.3.0 - Loan & Debt
- Mortgage amortization schedules
- Debt payoff strategies
- Refinancing analysis
- Student loan optimization
v0.4.0 - Advanced Features
- Multi-currency support
- Tax calculations and optimization
- Estate planning calculations
- Business valuation tools
v1.0.0 - Enterprise Ready
- API rate limiting
- Advanced caching strategies
- Audit logging
- Enterprise security features
Contributing
We welcome contributions! Please see CONTRIBUTING.md for details.
- Fork the repository
-
Create your feature branch (
git checkout -b feature/amazing-feature) - Add tests for your changes
-
Ensure all tests pass (
mix test) -
Run code quality checks (
mix credo && mix dialyzer) -
Commit your changes (
git commit -am 'Add amazing feature') -
Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Performance
Finex is optimized for production use:
- Memory Efficient: Minimal memory allocation with Decimal precision
- Fast Calculations: Optimized mathematical formulas
- Scalable: Handles high-volume financial calculations
- Fault Tolerant: Comprehensive error handling and validation
Comparison with Other Libraries
| Feature | Finex | Other Libraries |
|---|---|---|
| Decimal Precision | โ | โ (most use floats) |
| Fee Transparency | โ | โ |
| Comprehensive Testing | โ | โ ๏ธ |
| Production Ready | โ | โ ๏ธ |
| Phoenix Integration | โ | โ |
| Real-world Scenarios | โ | โ |
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built with โค๏ธ for the Elixir community
- Inspired by real-world fintech challenges
- Thanks to all contributors and early adopters
Ready to build the next generation of fintech apps with Elixir? Start with Finex! ๐