Skip to content
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
c4aa47c
Added PV an NPV computation
thsubaku9 Jan 28, 2021
c2a226e
testing for pv and npv functions
thsubaku9 Jan 29, 2021
5c4df0b
missing examples added
thsubaku9 Jan 30, 2021
ae9c788
comment line violation
thsubaku9 Jan 30, 2021
ad35b8a
gofumpt linting
thsubaku9 Jan 30, 2021
b850524
indentation oopsie
thsubaku9 Feb 1, 2021
90ef39c
new play.golang links
thsubaku9 Feb 1, 2021
089af1e
variable naming
thsubaku9 Feb 2, 2021
ac619a2
better example
thsubaku9 Feb 3, 2021
16fc02d
pull merge
thsubaku9 Feb 6, 2021
fffc0ae
Merge branch 'master' of https://github.com/razorpay/go-financial
thsubaku9 Mar 5, 2021
04c9309
Rate calculation
thsubaku9 Mar 20, 2021
b4a4d77
readme fix
thsubaku9 Mar 20, 2021
bb23dc8
modified as per decimal values
thsubaku9 Mar 22, 2021
3448076
minor modifications
thsubaku9 Mar 28, 2021
0e7e689
required modifications
thsubaku9 Apr 11, 2021
ddc5f1a
required modifications 2
thsubaku9 Apr 11, 2021
4878997
required fixes and comment modifications
thsubaku9 Apr 19, 2021
4134c54
gofumpt
thsubaku9 Apr 19, 2021
97b52a1
README changes
thsubaku9 Apr 19, 2021
60d3d66
error printing
thsubaku9 Apr 25, 2021
6cb9b88
Merge branch 'master' of https://github.com/razorpay/go-financial
thsubaku9 Jun 6, 2021
8c47073
Merge branch 'master' of https://github.com/razorpay/go-financial
thsubaku9 Jul 25, 2021
4edb2b7
IRR function added
thsubaku9 Jul 26, 2021
d86b2f4
test for irr
thsubaku9 Jul 26, 2021
3f66ca5
readme.md updated
thsubaku9 Jul 26, 2021
ef14104
mirr added
thsubaku9 Jul 27, 2021
49062ef
Readme.md updated
thsubaku9 Jul 27, 2021
f1363f9
lint check
thsubaku9 Jul 27, 2021
305673f
naming convention
thsubaku9 Aug 27, 2021
8ddf09f
naming convention
thsubaku9 Aug 27, 2021
9606bf7
math var renaming
thsubaku9 Sep 1, 2021
b713fbb
Merge pull request #5 from thsubaku9/irr-feature
thsubaku9 Aug 29, 2023
153b7af
Merge branch 'master' into mirr-feature
thsubaku9 Aug 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ which are as follows:
| rate | ✅ | Computes the rate of interest per period|
| irr | | Computes the internal rate of return|
| npv | ✅ | Computes the net present value of a series of cash flow|
| mirr | | Computes the modified internal rate of return|
| mirr | | Computes the modified internal rate of return|

# Index
While the numpy-financial package contains a set of elementary financial functions, this pkg also contains some helper functions on top of it. Their usage and description can be found below:
Expand All @@ -49,6 +49,8 @@ While the numpy-financial package contains a set of elementary financial functio
+ [Example(Nper-Loan)](#examplenper-loan)
* [Rate(Interest Rate)](#rate)
+ [Example(Rate-Investment)](#examplerate-investment)
* [Mirr(Modified irr)](#mirr)
+ [Example(Mirr)](#examplemirr)

Detailed documentation is available at [godoc](https://godoc.org/github.com/razorpay/go-financial).
## Amortisation(Generate Table)
Expand Down Expand Up @@ -638,3 +640,48 @@ func main() {
}
```
[Run on go-playground](https://play.golang.org/p/H2uybe1dbRj)

## Mirr

```go
func Mirr(cashflows []decimal.Decimal, financeRate, reinvestRate decimal.Decimal) decimal.Decimal
```

Params:
```text
cashflows: periodic chasflow statement
financeRate: interest rate for inflows
reinvestRate: interst received for reinvesting outflows
```

Returns:
```text
mirr : a value for the corresponding mirr
```

Mirr calculates the Modified internal rate of return for a given cashflow and finance and reinvestment rates

### Example(Mirr)

```go
package main

import (
"fmt"
gofinancial "github.com/razorpay/go-financial"
"github.com/shopspring/decimal"
)

func main() {
cashflow := []decimal.Decimal{decimal.NewFromInt(-1000), decimal.NewFromInt(-4000), decimal.NewFromInt(5000), decimal.NewFromInt(2000)}
financeRate := decimal.NewFromFloat(0.1)
reinvestRate := decimal.NewFromFloat(0.12)

mirr := gofinancial.Mirr(cashflow,financeRate,reinvestRate)

fmt.Printf("mirr: %v",mirr)
// Output:
// mirr: 0.1790856860348926
}
```
[Run on go-playground](https://play.golang.org/p/ci6pBUkX4jy)
37 changes: 37 additions & 0 deletions reducing_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,3 +371,40 @@ func Rate(pv, fv, pmt decimal.Decimal, nper int64, when paymentperiod.Type, maxI
}
return nextIterRate, nil
}

/*
Mirr calculates the Modified internal rate of return for a given cashflow and finance and reinvestment rates

Params:
cashflows : periodic chasflow statement
financeRate : interest rate for inflows
reinvestRate : interst received for reinvesting outflows
*/
func Mirr(cashflows []decimal.Decimal, financeRate, reinvestRate decimal.Decimal) decimal.Decimal {
var inflow, outflow []decimal.Decimal

for _, v := range cashflows {
if v.IsNegative() {
inflow = append(inflow, v)
outflow = append(outflow, decimal.Zero)
}
if v.IsPositive() {
outflow = append(outflow, v)
inflow = append(inflow, decimal.Zero)
}
}

one := decimal.NewFromFloat(1)
n_1 := decimal.NewFromInt(int64(len(cashflows) - 1))
Comment thread
thsubaku9 marked this conversation as resolved.
Outdated
_pv := Npv(financeRate, inflow)
_fv := Npv(reinvestRate, outflow).Mul(one.Add(reinvestRate).Pow(n_1))

// ! shopspring decimal struct based underroot is imprecise (hence math library)
_x1 := _fv.Div(_pv.Neg())
_go_x1, _ := _x1.Float64()
_go_x2, _ := one.Div(n_1).Float64()
_x3 := math.Pow(_go_x1, _go_x2)

_mirr := decimal.NewFromFloat(_x3).Sub(one)
return _mirr
}
38 changes: 38 additions & 0 deletions reducing_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,3 +422,41 @@ func Test_Rate(t *testing.T) {
})
}
}

func Test_Mirr(t *testing.T) {
type args struct {
cashflow []decimal.Decimal
financeRate decimal.Decimal
reinvestRate decimal.Decimal
}
tests := []struct {
name string
args args
want decimal.Decimal
}{
{
name: "success", args: args{
cashflow: []decimal.Decimal{decimal.NewFromInt(-1000), decimal.NewFromInt(-4000), decimal.NewFromInt(5000), decimal.NewFromInt(2000)},
financeRate: decimal.NewFromFloat(0.1),
reinvestRate: decimal.NewFromFloat(0.12),
},
want: decimal.NewFromFloat(0.1790856860),
},
{
name: "success", args: args{
cashflow: []decimal.Decimal{decimal.NewFromInt(-2000), decimal.NewFromInt(2000), decimal.NewFromInt(2000)},
financeRate: decimal.NewFromFloat(0.3),
reinvestRate: decimal.NewFromFloat(0.1),
},
want: decimal.NewFromFloat(0.4491376746),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if res := Mirr(tt.args.cashflow, tt.args.financeRate, tt.args.reinvestRate); isAlmostEqual(res, tt.want, decimal.NewFromFloat(precision)) != nil {
t.Errorf("Mirr returned (%v), wanted (%v)", res, tt.want)
}
})
}
}