Packages
ex_money
0.0.5
6.1.1
6.1.0
6.0.0
6.0.0-rc.0
5.24.2
5.24.1
5.24.0
retired
5.23.0
5.22.0
5.21.0
5.20.0
5.19.2
5.19.1
5.19.0
5.18.0
5.17.2
5.17.1
5.17.0
5.16.1
5.16.0
5.15.4
5.15.3
5.15.2
5.15.1
5.15.0
5.14.1
5.13.0
5.12.4
5.12.3
5.12.2
5.12.1
5.12.0
5.11.0
5.10.0
5.9.0
5.8.0
5.7.4
5.7.3
5.7.2
5.7.1
5.7.0
5.6.0
5.5.5
5.5.4
5.5.3
5.5.2
5.5.1
5.5.0
5.4.1
5.4.0
5.4.0-rc.0
5.3.2
5.3.1
5.3.0
5.2.1
5.2.0
5.1.0
5.0.2
5.0.1
5.0.0
retired
4.4.3
4.4.2
retired
4.4.1
4.4.0
4.3.0
4.2.2
4.2.1
4.2.0
4.1.0
4.0.0
3.4.4
3.4.3
3.4.2
3.4.1
3.4.0
3.3.1
3.3.0
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.0
3.0.0
2.12.2
2.12.1
retired
2.12.0
retired
2.11.0
2.10.0
2.9.1
2.9.0
2.8.0
2.7.3
2.7.2
2.7.1
2.7.0
2.6.1
2.6.0
2.5.0
2.4.0
2.3.0
2.2.2
2.2.1
2.2.0
2.1.0
2.1.0-rc.1
retired
2.1.0-rc.0
retired
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.1.3
1.1.2
1.1.1
retired
1.1.0
1.0.0
1.0.0-rc.0
retired
0.9.0
retired
0.8.5
retired
0.8.4
retired
0.8.3
retired
0.8.2
retired
0.8.1
retired
0.8.0
retired
0.7.0
retired
0.6.2
retired
0.6.1
retired
0.6.0
retired
0.5.3
retired
0.5.2
retired
0.5.1
retired
0.5.0
retired
0.4.3
retired
0.4.2
retired
0.4.1
retired
0.4.0
retired
0.3.0
retired
0.2.0
retired
0.1.7
retired
0.1.6
retired
0.1.5
retired
0.1.4
retired
0.1.3
retired
0.1.2
retired
0.1.1
retired
0.1.0
retired
0.0.16
retired
0.0.15
retired
0.0.14
retired
0.0.13
retired
0.0.12
retired
0.0.11
retired
0.0.10
retired
0.0.9
retired
0.0.7
retired
0.0.6
retired
0.0.5
retired
0.0.4
retired
0.0.3
retired
0.0.2
retired
Money functions for operations on and localization of a money data type with support for ISO 4217 currencies and ISO 24165 digial tokens (crypto currencies).
Retired package: Deprecated
Current section
Files
Jump to
Current section
Files
lib/money/financial.ex
defmodule Money.Financial do
@moduledoc false
# Some algorithms from http://www.financeformulas.net
alias Cldr.Number.Math
defmacro __using__(_opts) do
quote do
@doc """
Calculates the future value for a %Money{} present value, an interest rate
and a number of periods.
* `present_value` is a %Money{} representation of the present value
* `interest_rate` is a float representation of an interest rate. For
example, 12% would be represented as `0.12`
* `periods` in an integer number of periods
## Examples
iex> Money.future_value Money.new(:USD, 10000), 0.08, 1
#Money<:USD, 10800.00>
iex> Money.future_value Money.new(:USD, 10000), 0.04, 2
#Money<:USD, 10816.0000>
iex> Money.future_value Money.new(:USD, 10000), 0.02, 4
#Money<:USD, 10824.32160000>
"""
@one Decimal.new(1)
def future_value(%Money{currency: currency, amount: amount} = present_value, interest_rate, periods)
when is_number(interest_rate) and is_number(periods) do
fv = interest_rate
|> Decimal.new
|> Decimal.add(@one)
|> Math.power(periods)
|> Decimal.mult(amount)
Money.new(currency, fv)
end
@doc """
Calculates the present value for %Money{} future value, an interest rate
and a number of periods
* `future_value` is a %Money{} representation of the future value
* `interest_rate` is a float representation of an interest rate. For
example, 12% would be represented as `0.12`
* `periods` in an integer number of periods
## Examples
iex> Money.present_value Money.new(:USD, 100), 0.08, 2
#Money<:USD, 85.73388203017832647462277092>
iex> Money.present_value Money.new(:USD, 1000), 0.10, 20
#Money<:USD, 148.6436280241436864020760472>
"""
def present_value(%Money{currency: currency, amount: amount} = future_value, interest_rate, periods)
when is_number(interest_rate) and interest_rate > 0 and is_number(periods) and periods > 0 do
pv_1 = interest_rate
|> Decimal.new
|> Decimal.add(@one)
|> Math.power(periods)
pv = Decimal.div(@one, pv_1)
|> Decimal.mult(amount)
Money.new(currency, pv)
end
@doc """
Calculates the effective interest rate for a given %Money{} present value,
a %Money{} future value and a number of periods.
* `present_value` is a %Money{} representation of the present value
* `future_value` is a %Money{} representation of the future value
* `periods` is an integer number of periods
## Examples
iex> Money.interest_rate Money.new(:USD, 10000), Money.new(:USD, 10816), 2
#Decimal<0.04>
iex> Money.interest_rate Money.new(:USD, 10000), Money.new(:USD, 10824.3216), 4
#Decimal<0.02>
"""
def interest_rate(%Money{currency: pv_currency, amount: pv_amount} = present_value,
%Money{currency: fv_currency, amount: fv_amount} = future_value,
periods)
when pv_currency == fv_currency and is_number(periods) and periods > 0 do
Decimal.div(fv_amount, pv_amount)
|> Math.root(periods)
|> Decimal.sub(@one)
end
@doc """
Calculates the number of periods between a %Money{} present value and
a %Money{} future value with a given interest rate.
* `present_value` is a %Money{} representation of the present value
* `future_value` is a %Money{} representation of the future value
* `interest_rate` is a float representation of an interest rate. For
example, 12% would be represented as `0.12`
## Example
iex> Money.periods Money.new(:USD, 1500), Money.new(:USD, 2000), 0.005
#Decimal<57.68013595323872502502238648>
"""
def periods(%Money{currency: pv_currency, amount: pv_amount} = present_value,
%Money{currency: fv_currency, amount: fv_amount} = future_value,
interest_rate)
when pv_currency == fv_currency and is_number(interest_rate) and interest_rate > 0 do
Decimal.div(Math.log(Decimal.div(fv_amount, pv_amount)),
Math.log(Decimal.add(@one, Decimal.new(interest_rate))))
end
@doc """
Calculates the payment for a given loan or annuity given a %Money{}
present value, an interest rate and a number of periods.
* `present_value` is a %Money{} representation of the present value
* `interest_rate` is a float representation of an interest rate. For
example, 12% would be represented as `0.12`
* `periods` is an integer number of periods
## Example
iex> Money.payment Money.new(:USD, 100), 0.12, 20
#Money<:USD, 13.38787800396606622792492299>
"""
def payment(%Money{currency: pv_currency, amount: pv_amount} = present_value,
interest_rate, periods)
when is_number(interest_rate) and interest_rate > 0 and is_number(periods) and periods > 0 do
interest_rate = Decimal.new(interest_rate)
p1 = Decimal.mult(pv_amount, interest_rate)
p2 = Decimal.sub(@one, Decimal.add(@one, interest_rate) |> Math.power(-periods))
Money.new(pv_currency, Decimal.div(p1, p2))
end
end
end
end