money

package module
v0.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2018 License: BSD-3-Clause Imports: 6 Imported by: 0

README

Money

Godoc Go Report Card

import "github.com/mpwalkerdine/money"

Package money is a convenience wrapper for github.com/ericlagergren/decimal.

It makes decimal values returned from this package immutable, at the expense of reduced memory efficiency. See https://golang.org/pkg/math/big/ for why the API is designed in the way it is. We forego that benefit in calling code, but where possible this package will attempt to minimise allocations during calculations. In the majority of cases however, monetary values fit inside the compact uint64 value used by the underlying decimal package.

Documentation

Overview

Package money is a convenience wrapper for "github.com/ericlagergren/decimal".

It makes decimal values returned from this package immutable, at the expense of reduced memory efficiency. See https://golang.org/pkg/math/big/ for why the API is designed in the way it is. We forego that benefit in calling code, but where possible this package will attempt to minimise allocations during calculations. In the majority of cases however, monetary values fit inside the compact uint64 value used by the underlying decimal package.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Decimal

type Decimal struct {
	// contains filtered or unexported fields
}

Decimal is an immutable, arbitrary precision decimal number.

func Bp

func Bp(v int64) Decimal

Bp creates a new "Basis Point" / permyriad decimal i.e. 4‱ = Bp(4) = 0.0004.

Example
fmt.Print(Bp(10))
Output:

0.001

func Deflate added in v0.2.4

func Deflate(amount, inflation Decimal, periods int) Decimal

Deflate calculates amount / (1 + inflation)^periods.

This expresses a future value (after the given number of periods) in today's money. The inflation rate must be per unit of period i.e. if periods is 5 years, inflation must be per annum e.g. 0.05 for 5% pa.

Example
amount := New(1000) // £1000
years := 20         // in 20 years
inflation := Pm(25) // with 2.5% inflation p.a.
fmt.Printf("%.2f", Deflate(amount, inflation, years))
Output:

610.27

func EffectiveToNominalRate added in v0.2.0

func EffectiveToNominalRate(rate Decimal, periods int) Decimal

EffectiveToNominalRate calculates ((1+rate)^(1/periods) - 1) * periods.

This is the inverse of NominalToEffectiveRate.

Example
effective := Bp(617) // 6.17%
nominal := EffectiveToNominalRate(effective, 12)
fmt.Print(nominal.Round(3, ToNearestAway))
Output:

0.0600

func EffectiveToPeriodicRate added in v0.2.0

func EffectiveToPeriodicRate(rate Decimal, periods int) Decimal

EffectiveToPeriodicRate calculates (1+rate)^(1/periods) - 1.

Given an effective rate, e.g. the amount of interest paid in a year, this calculates the rate used for periodic payments to achieve the same rate overall.

Example
annual := Pc(10)
daily := EffectiveToPeriodicRate(annual, 365)
fmt.Print(daily.Round(6, ToNearestAway))
Output:

0.000261158

func FutureValue added in v0.2.0

func FutureValue(amount, rate Decimal, duration, periods int) Decimal

FutureValue calculates amount * (1+rate/periods)^(duration*periods).

In other words, given an amount, interest rate and compounding frequency, this calculates what the future value will be at the end of the term.

Example
amount := New(1500) // £1,500
rate := Pm(43)      // 4.3%
periods := 4        // Compounded quarterly
duration := 6       // 6 years

final := FutureValue(amount, rate, duration, periods)
fmt.Print(final.RoundDP(2, ToNearestEven))
Output:

1938.84

func FutureValueAnnuityDue added in v0.2.0

func FutureValueAnnuityDue(amountPerPeriod, rate Decimal, periods int) Decimal

FutureValueAnnuityDue calculates amountPerPeriod * [ ((1+rate)^periods - 1) / rate ] * (1+rate).

This is the accumulated value when payments are made at the beginning of each period. Note that rate should be per period.

Example
amountPerPeriod := New(1000) // £1000 at the start of each year
rate := Pc(5)                // 5% PA
periods := 5                 // 5 years
result := FutureValueAnnuityDue(amountPerPeriod, rate, periods)
fmt.Printf("%.2f", result)
Output:

5801.91

func FutureValueOrdinaryAnnuity added in v0.2.0

func FutureValueOrdinaryAnnuity(amountPerPeriod, rate Decimal, periods int) Decimal

FutureValueOrdinaryAnnuity calculates amountPerPeriod * [ ((1+rate)^periods - 1) / rate ].

This is the accumulated value when payments are made at the end of each period. Note that rate should be per period.

Example
amountPerPeriod := New(1000) // £1000 at the end of each year
rate := Pc(5)                // 5% PA
periods := 5                 // 5 years
result := FutureValueOrdinaryAnnuity(amountPerPeriod, rate, periods)
fmt.Printf("%.2f", result)
Output:

5525.63

func GoalSeek added in v0.2.3

func GoalSeek(initial, target Decimal, precision int, f func(Decimal) Decimal) (Decimal, bool)

GoalSeek attempts to find a value x (to the specified precision), such that f(x) = target, using initial as a starting point.

Example
initial := New(1)

// Find x s.t. x^2+2 = 11 (i.e. √9 = 3)
fmt.Println(GoalSeek(initial, New(11), 2, func(x Decimal) Decimal { return x.PowInt(2).AddInt(2) }))

// Find x s.t. 0.01x^2+0.8 = 1 (i.e. 10√0.2 ≅ 4.472)
fmt.Println(GoalSeek(initial, New(1), 4, func(x Decimal) Decimal { return x.PowInt(2).Mul(Pc(1)).Add(Pc(80)) }))

// Find x s.t. x^2 = -1 (i.e. √-1, no real solution)
fmt.Println(GoalSeek(initial, New(-1), 3, func(x Decimal) Decimal { return x.PowInt(2) }))
Output:

3.0 true
4.472 true
1.00 false

func Max added in v0.2.2

func Max(first Decimal, others ...Decimal) Decimal

Max returns the value closest to positive infinity.

Example
fmt.Print(Max(New(1), NewCents(200), NewInt(1)))
Output:

2.00

func New

func New(units int64) Decimal

New creates a monetary decimal for a given unit number.

Example
fmt.Print(New(50))
Output:

50.00

func NewCents

func NewCents(cents int64) Decimal

NewCents creates a monetary decimal for a given cent value.

Example
fmt.Print(NewCents(1234))
Output:

12.34

func NewInt

func NewInt(i int) Decimal

NewInt creates an integer decimal with zero scale.

func NewScalar

func NewScalar(value int64, scale int) Decimal

NewScalar creates an arbitrary scalar value.

Example
fmt.Print(NewScalar(42, 0))
Output:

42

func NominalToEffectiveRate added in v0.2.0

func NominalToEffectiveRate(rate Decimal, periods int) Decimal

NominalToEffectiveRate calculates (1+rate/periods)^periods - 1.

A nominal rate in this context is just the periodic rate multiplied by the number of periods, which will be less than the effective rate due to the nature of compounding.

For example, 6% compounded monthly means 0.5% is applied each month, which gives an effective rate of 6.17%.

Example
nominal := Pc(6)
effective := NominalToEffectiveRate(nominal, 12)
fmt.Print(effective.Round(3, ToNearestAway))
Output:

0.0617

func NominalToRealRate added in v0.2.0

func NominalToRealRate(rate, inflation Decimal) Decimal

NominalToRealRate calculates (1+rate)/(1+inflation) - 1 (Fisher equation).

A nominal rate in this context is the "before inflation rate".

Example
nominal := Bp(521)  // 5.21%
inflation := Pm(25) // 2.50%
real := NominalToRealRate(nominal, inflation)
fmt.Print(real.Round(3, ToNearestAway))
Output:

0.0264

func Pc

func Pc(v int64) Decimal

Pc creates a decimal percent i.e. 2% = Pc(2) = 0.02.

Example
fmt.Print(Pc(50))
Output:

0.5

func Pm

func Pm(v int64) Decimal

Pm creates a decimal permille i.e. 3‰ = Pm(3) = 0.003.

Example
fmt.Print(Pm(20))
Output:

0.02

func RealToNominalRate added in v0.2.2

func RealToNominalRate(rate, inflation Decimal) Decimal

RealToNominalRate calculates (rate + 1)(1+inflation) - 1 (Fisher equation).

A nominal rate in this context is the "before inflation rate".

Example
real := Bp(264)     // 2.64%
inflation := Pm(25) // 2.50%
nominal := RealToNominalRate(real, inflation)
fmt.Print(nominal.Round(3, ToNearestAway))
Output:

0.0521

func RecompoundRate added in v0.2.0

func RecompoundRate(rate Decimal, current, new int) Decimal

RecompoundRate converts a rate from one compounding basis to another.

For example, 4% compounded quarterly is a 3.98% compounded daily.

Example
annualQuarterly := Pc(4)
annualDaily := RecompoundRate(annualQuarterly, 4, 365)
fmt.Print(annualDaily.Round(3, ToNearestAway))
Output:

0.0398

func (Decimal) Add

func (a Decimal) Add(b Decimal) Decimal

Add calculates a + b.

Example
a := New(5)
b := New(10)
fmt.Print(a.Add(b))
Output:

15.00

func (Decimal) AddInt

func (a Decimal) AddInt(b int) Decimal

AddInt calculates a + b.

Example
fmt.Println(NewCents(99).AddInt(1))
Output:

1.99

func (Decimal) Div

func (a Decimal) Div(b Decimal) Decimal

Div calculates a / b.

Example
a := New(1)
b := New(3)
fmt.Printf("%.5f", a.Div(b))
Output:

0.33333

func (Decimal) Equals

func (d Decimal) Equals(other Decimal) bool

Equals returns true if the two numbers represent the same value.

Example
a := New(1)
b := NewCents(100)
fmt.Print(a.Equals(b))
Output:

true

func (Decimal) Format added in v0.2.0

func (d Decimal) Format(s fmt.State, c rune)

Format implements the fmt.Formatter interface. Verbs are the same as for the underlying decimal.Big, except %v and %d are the same as %f. %c will multiply by 100, use %f and append '%'. If a precision is requested for negative scale decimals, these are appended.

Example
print := func(format string, d Decimal) {
	fmt.Printf(format+"\n", d)
}

print("%s", NewCents(123))
print("%s", NewScalar(2345, -6))
print("%v", NewScalar(2345, -6))
print("%.2f", New(5678))
print("`%5.2f`", New(7).Div(New(3)))
print("'%-10.f'", NewCents(-80808))
print("%.2c", Pm(25))
Output:

1.23
2.345e+9
2345000000
5678.00
` 2.33`
'-808      '
2.50%

func (Decimal) LessThan added in v0.2.2

func (d Decimal) LessThan(other Decimal) bool

LessThan than returns true if the receiver is less than the argument.

Example
fmt.Print(New(1).LessThan(NewCents(100)))
Output:

false

func (Decimal) Mul

func (a Decimal) Mul(b Decimal) Decimal

Mul calculates a * b.

Example
a := New(50)
b := Pc(50)
fmt.Print(a.Mul(b))
Output:

25.000

func (Decimal) Pow

func (d Decimal) Pow(n Decimal) Decimal

Pow calculates d^n.

Example
fmt.Print(New(16).Pow(Pc(50)).RoundDP(2, ToNearestAway))
Output:

4.00

func (Decimal) PowFrac

func (d Decimal) PowFrac(num, denom int) Decimal

PowFrac calculates d^(num/denom).

Example
fmt.Print(New(27).PowFrac(1, 3).RoundDP(2, ToNearestEven))
Output:

3.00

func (Decimal) PowInt

func (d Decimal) PowInt(i int) Decimal

PowInt calculates d^i.

Example
fmt.Print(New(3).PowInt(3))
Output:

27.000000

func (Decimal) Round

func (d Decimal) Round(sigfigs int, mode RoundingMode) Decimal

Round rounds the decimal to the specified number of significant figures.

Example
fmt.Print(NewCents(123999999).Round(3, ToNegativeInf))
Output:

1230000

func (Decimal) RoundDP

func (d Decimal) RoundDP(dp int, mode RoundingMode) Decimal

RoundDP rounds the decimal to the specified number of decimal places.

Example
fmt.Print(Bp(1234).RoundDP(1, ToPositiveInf))
Output:

0.2

func (Decimal) Sub

func (a Decimal) Sub(b Decimal) Decimal

Sub calculates a - b.

Example
a := New(5)
b := New(10)
fmt.Print(a.Sub(b))
Output:

-5.00

func (Decimal) SubInt

func (a Decimal) SubInt(b int) Decimal

SubInt calculates a - b.

Example
fmt.Print(NewCents(499).SubInt(4))
Output:

0.99

type RoundingMode

type RoundingMode = eld.RoundingMode

RoundingMode determines how rounding is performed.

const (
	ToNearestEven RoundingMode = eld.ToNearestEven
	ToNearestAway RoundingMode = eld.ToNearestAway
	ToZero        RoundingMode = eld.ToZero
	AwayFromZero  RoundingMode = eld.AwayFromZero
	ToNegativeInf RoundingMode = eld.ToNegativeInf
	ToPositiveInf RoundingMode = eld.ToPositiveInf
)

Rounding constants.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL