Skip to content

Commit

Permalink
add allocation target
Browse files Browse the repository at this point in the history
  • Loading branch information
ananthakumaran committed Jul 10, 2022
1 parent 41b0e1f commit 30200d5
Show file tree
Hide file tree
Showing 11 changed files with 377 additions and 79 deletions.
9 changes: 9 additions & 0 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ func generateConfigFile(cwd string) {
config := `
journal_path: "%s"
db_path: "%s"
allocation_targets:
- name: Debt
target: 40
accounts:
- Asset:Debt:*
- name: Equity
target: 60
accounts:
- Asset:Equity:*
commodities:
- name: NIFTY
type: mutualfund
Expand Down
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
# Reference Guide

- [Accounts](accounts.md)
- [Allocation Targets](allocation-targets.md)
19 changes: 19 additions & 0 deletions docs/src/allocation-targets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Allocation Targets

Paisa allows you to set a allocation target for a group of
accounts. The allocation page shows how far your current allocation is
from the allocation target. For example, to keep a 40:60 split between
debt and equity, add the following configuration to the `paisa.yaml`
file. The account name can have `*` which matches any characters

```yaml
allocation_targets:
- name: Debt
target: 40
accounts:
- Asset:Debt:*
- name: Equity
target: 60
accounts:
- Asset:Equity:*
```
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/google/btree v1.0.1
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/manifoldco/promptui v0.9.0
github.com/samber/lo v1.11.0
github.com/samber/lo v1.25.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.10.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/samber/lo v1.11.0 h1:JfeYozXL1xfkhRUFOfH13ociyeiLSC/GRJjGKI668xM=
github.com/samber/lo v1.11.0/go.mod h1:2I7tgIv8Q1SG2xEIkRq0F2i2zgxVpnyPOP0d3Gj2r+A=
github.com/samber/lo v1.25.0 h1:H8F6cB0RotRdgcRCivTByAQePaYhGMdOTJIj2QFS2I0=
github.com/samber/lo v1.25.0/go.mod h1:2I7tgIv8Q1SG2xEIkRq0F2i2zgxVpnyPOP0d3Gj2r+A=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
Expand Down
49 changes: 48 additions & 1 deletion internal/server/allocation.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package server

import (
"path/filepath"
"strings"
"time"

Expand All @@ -10,6 +11,7 @@ import (
"github.com/ananthakumaran/paisa/internal/model/posting"
"github.com/ananthakumaran/paisa/internal/service"
"github.com/gin-gonic/gin"
"github.com/spf13/viper"
"gorm.io/gorm"
)

Expand All @@ -20,6 +22,19 @@ type Aggregate struct {
MarketAmount float64 `json:"market_amount"`
}

type AllocationTargetConfig struct {
Name string
Target float64
Accounts []string
}

type AllocationTarget struct {
Name string `json:"name"`
Target float64 `json:"target"`
Current float64 `json:"current"`
Aggregates map[string]Aggregate `json:"aggregates"`
}

func GetAllocation(db *gorm.DB) gin.H {
var postings []posting.Posting
result := db.Where("account like ?", "Asset:%").Order("date ASC").Find(&postings)
Expand All @@ -34,7 +49,8 @@ func GetAllocation(db *gorm.DB) gin.H {
})
aggregates := computeAggregate(postings, now)
aggregates_timeline := computeAggregateTimeline(postings)
return gin.H{"aggregates": aggregates, "aggregates_timeline": aggregates_timeline}
allocation_targets := computeAllocationTargets(postings)
return gin.H{"aggregates": aggregates, "aggregates_timeline": aggregates_timeline, "allocation_targets": allocation_targets}
}

func computeAggregateTimeline(postings []posting.Posting) []map[string]Aggregate {
Expand All @@ -55,6 +71,37 @@ func computeAggregateTimeline(postings []posting.Posting) []map[string]Aggregate
return timeline
}

func computeAllocationTargets(postings []posting.Posting) []AllocationTarget {
var targetAllocations []AllocationTarget
var configs []AllocationTargetConfig
viper.UnmarshalKey("allocation_targets", &configs)

totalMarketAmount := lo.Reduce(postings, func(acc float64, p posting.Posting, _ int) float64 { return acc + p.MarketAmount }, 0.0)

for _, config := range configs {
targetAllocations = append(targetAllocations, computeAllocationTarget(postings, config, totalMarketAmount))
}

return targetAllocations
}

func computeAllocationTarget(postings []posting.Posting, config AllocationTargetConfig, total float64) AllocationTarget {
date := time.Now()
postings = lo.Filter(postings, func(p posting.Posting, _ int) bool {
return lo.SomeBy(config.Accounts, func(accountGlob string) bool {
match, err := filepath.Match(accountGlob, p.Account)
if err != nil {
log.Fatal("Invalid account value used in target_allocations", accountGlob, err)
}
return match
})
})

aggregates := computeAggregate(postings, date)
currentTotal := lo.Reduce(postings, func(acc float64, p posting.Posting, _ int) float64 { return acc + p.MarketAmount }, 0.0)
return AllocationTarget{Name: config.Name, Target: config.Target, Current: (currentTotal / total) * 100, Aggregates: aggregates}
}

func computeAggregate(postings []posting.Posting, date time.Time) map[string]Aggregate {
byAccount := lo.GroupBy(postings, func(p posting.Posting) string { return p.Account })
result := make(map[string]Aggregate)
Expand Down
Loading

0 comments on commit 30200d5

Please sign in to comment.