Skip to content

Commit

Permalink
Add support for grouping by liquidity and fix max deviation reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
MicroFish91 committed Nov 14, 2024
1 parent 9a17ad2 commit 47a58d1
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 5 deletions.
12 changes: 12 additions & 0 deletions api/services/snapshot/handler_getsnapshotbyid.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ func (h *SnapshotHandlerImpl) handleGroupByResource(c fiber.Ctx, snapId, userId
"maturation_end": options.Maturation_end,
})

case BY_LIQUIDITY:

liquidTotal, err := h.snapshotStore.GroupByLiquidity(c.Context(), userId, snapId)
if err != nil {
return utils.SendError(c, utils.StatusCodeFromError(err), err)
}

return utils.SendJSON(c, fiber.StatusOK, fiber.Map{
"liquid_total": liquidTotal,
"field_type": GroupByCategory(options.Group_by),
})

default:
return utils.SendError(c, fiber.StatusBadRequest, errors.New("provided an unsupported group_by request category"))
}
Expand Down
10 changes: 6 additions & 4 deletions api/services/snapshot/handler_rebalancesnapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,15 @@ func (h *SnapshotHandlerImpl) computeRebalance(balloc []types.AssetAllocationPct
}

// Rebalance diff required
ch, rebThresh, err := h.computeRebalanceDiff(tar, cur)
ch, rebThresh, err := h.computeRebalanceDiff(tar, cur, total)
if err != nil {
return nil, nil, nil, 0, err
}

return &tar, &cur, ch, rebThresh, nil
}

func (h *SnapshotHandlerImpl) computeRebalanceDiff(target []types.AssetAllocation, current []types.AssetAllocation) (alloc *[]types.AssetAllocation, rebThreshPct int, e error) {
func (h *SnapshotHandlerImpl) computeRebalanceDiff(target []types.AssetAllocation, current []types.AssetAllocation, total float64) (alloc *[]types.AssetAllocation, rebThreshPct int, e error) {
var (
maxDeviation = 0
chmap = make(map[string]float64)
Expand All @@ -127,8 +127,10 @@ func (h *SnapshotHandlerImpl) computeRebalanceDiff(target []types.AssetAllocatio
diff := math.Round((t.Value-alloc.Value)*100) / 100
chmap[t.Category] = diff

deviation := int(math.Round(math.Abs(diff / t.Value * 100)))
if (deviation) > maxDeviation {
tarPct := math.Round(t.Value / total * 100)
curPct := math.Round(alloc.Value / total * 100)
deviation := int(math.Abs(tarPct - curPct))
if deviation > maxDeviation {
maxDeviation = deviation
}
}
Expand Down
3 changes: 3 additions & 0 deletions api/services/snapshot/schema_getsnapshotbyid.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const (
BY_TAX_SHELTER GroupByCategory = "TAX_SHELTER"
BY_ASSET_CATEGORY GroupByCategory = "ASSET_CATEGORY"
BY_MATURATION_DATE GroupByCategory = "MATURATION_DATE"
BY_LIQUIDITY GroupByCategory = "LIQUIDITY"
)

type GetSnapshotByIdQuery struct {
Expand Down Expand Up @@ -47,6 +48,8 @@ func (q GetSnapshotByIdQuery) Validate() error {
break
case GroupByCategory(q.Group_by) == BY_MATURATION_DATE:
break
case GroupByCategory(q.Group_by) == BY_LIQUIDITY:
break
default:
return errors.New("provide a valid group_by category in all caps")
}
Expand Down
46 changes: 46 additions & 0 deletions api/services/snapshot/store_groupbyliquidity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package snapshot

import (
"context"

"github.com/MicroFish91/portfolio-instruments-api/api/constants"
)

func (s *PostgresSnapshotStore) GroupByLiquidity(ctx context.Context, userId, snapId int) (float64, error) {
c, cancel := context.WithTimeout(ctx, constants.TIMEOUT_MEDIUM)
defer cancel()

row := s.db.QueryRow(
c,
`
select
SUM(snapshots_values.total) AS liquid_total
from
snapshots_values
inner join
accounts
on
snapshots_values.account_id = accounts.account_id
inner join
holdings
on
snapshots_values.holding_id = holdings.holding_id
where
snapshots_values.user_id = $1
and snapshots_values.snap_id = $2
and accounts.tax_shelter = 'TAXABLE'
and holdings.asset_category = 'CASH'
`,
userId, snapId,
)

var liquid_total float64
err := row.Scan(
&liquid_total,
)

if err != nil {
return 0, err
}
return liquid_total, nil
}
9 changes: 9 additions & 0 deletions api/types/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type SnapshotStore interface {
GroupByAccount(ctx context.Context, userId, snapId int, options *GetGroupByAccountStoreOptions) (ResourcesGrouped, error)
GroupByHolding(ctx context.Context, userId, snapId int, options *GetGroupByHoldingStoreOptions) (ResourcesGrouped, error)
GroupByMaturationDate(ctx context.Context, userId, snapId int, options *GetGroupByMaturationDateStoreOptions) ([]MaturationDateResource, error)
GroupByLiquidity(ctx context.Context, userId, snapId int) (total float64, err error)
}

type ResourcesGrouped struct {
Expand Down Expand Up @@ -159,6 +160,14 @@ type GetSnapshotMaturationDateResponse struct {
Error string `json:"error"`
}

type GetSnapshotLiquidityResponse struct {
Data struct {
Liquid_total string `json:"liquid_total"`
Field_type string `json:"field_type"`
} `json:"data"`
Error string `json:"error"`
}

type GetSnapshotRebalanceResponse struct {
Data struct {
Target_allocation *[]AssetAllocation `json:"target_allocation"`
Expand Down
2 changes: 1 addition & 1 deletion migrations/20240706215008_create-holding-table.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ CREATE TABLE IF NOT EXISTS holdings (
asset_category asset_type NOT NULL,
expense_ratio_pct numeric(3,2),
maturation_date varchar(10) CHECK (maturation_date ~ '^(\d{2}/\d{2}/\d{4})?$'), -- MM/DD/YYYY
interest_rate_pct numeric(3,3),
interest_rate_pct numeric(3,2),
is_deprecated boolean NOT NULL,
user_id integer NOT NULL,
created_at timestamp DEFAULT current_timestamp,
Expand Down

0 comments on commit 47a58d1

Please sign in to comment.