Skip to content

Commit

Permalink
fix: holding total change amount and percent mixed currencies with co…
Browse files Browse the repository at this point in the history
…st basis conversion disabled
  • Loading branch information
achannarasappa committed Feb 18, 2023
1 parent 6f139d9 commit d746e19
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 29 deletions.
18 changes: 9 additions & 9 deletions internal/asset/asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ func GetAssets(ctx c.Context, assetGroupQuote c.AssetGroupQuote) ([]c.Asset, Hol

currencyRateByUse := currency.GetCurrencyRateFromContext(ctx, assetQuote.Currency.FromCurrencyCode)

holding := getHoldingFromAssetQuote(assetQuote, holdingsBySymbol)
holding = convertAssetHoldingCurrency(currencyRateByUse, holding)
holding := getHoldingFromAssetQuote(assetQuote, holdingsBySymbol, currencyRateByUse)
holdingSummary = addHoldingToHoldingSummary(holdingSummary, holding, currencyRateByUse)

assets = append(assets, c.Asset{
Expand Down Expand Up @@ -102,21 +101,22 @@ func updateHoldingWeights(assets []c.Asset, holdingSummary HoldingSummary) []c.A

}

func getHoldingFromAssetQuote(assetQuote c.AssetQuote, lotsBySymbol map[string]AggregatedLot) c.Holding {
func getHoldingFromAssetQuote(assetQuote c.AssetQuote, lotsBySymbol map[string]AggregatedLot, currencyRateByUse currency.CurrencyRateByUse) c.Holding {

if aggregatedLot, ok := lotsBySymbol[assetQuote.Symbol]; ok {
value := aggregatedLot.Quantity * assetQuote.QuotePrice.Price
totalChangeAmount := value - aggregatedLot.Cost
totalChangePercent := (totalChangeAmount / aggregatedLot.Cost) * 100
value := aggregatedLot.Quantity * assetQuote.QuotePrice.Price * currencyRateByUse.QuotePrice
cost := aggregatedLot.Cost * currencyRateByUse.PositionCost
totalChangeAmount := value - cost
totalChangePercent := (totalChangeAmount / cost) * 100

return c.Holding{
Value: value,
Cost: aggregatedLot.Cost,
Cost: cost,
Quantity: aggregatedLot.Quantity,
UnitValue: value / aggregatedLot.Quantity,
UnitCost: aggregatedLot.Cost / aggregatedLot.Quantity,
UnitCost: cost / aggregatedLot.Quantity,
DayChange: c.HoldingChange{
Amount: assetQuote.QuotePrice.Change * aggregatedLot.Quantity,
Amount: assetQuote.QuotePrice.Change * aggregatedLot.Quantity * currencyRateByUse.QuotePrice,
Percent: assetQuote.QuotePrice.ChangePercent,
},
TotalChange: c.HoldingChange{
Expand Down
26 changes: 25 additions & 1 deletion internal/asset/asset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ var _ = Describe("Asset", func() {
Expect(outputHoldingSummary.DayChange.Amount).To(Equal(190.0))
})

When("and only the summary conversion only option is set", func() {
When("and the summary conversion only option is set", func() {

inputContextSummaryConversion := inputContext
inputContextSummaryConversion.Config = c.Config{
Expand All @@ -183,6 +183,30 @@ var _ = Describe("Asset", func() {

})

When("and the disable unit cost conversion option is set", func() {

inputContextDisableUnitCostConversion := inputContext
inputContextDisableUnitCostConversion.Config = c.Config{
Currency: "EUR",
CurrencyDisableUnitCostConversion: true,
}

outputAssets, outputHoldingSummary := GetAssets(inputContextDisableUnitCostConversion, inputAssetGroupQuote)

It("should not convert holding costs", func() {
Expect(outputAssets[0].Holding.Cost).To(Equal(1000.0)) // 1000 EUR unconverted since option is set
Expect(outputAssets[0].Holding.UnitCost).To(Equal(100.0))
Expect(outputAssets[0].Holding.Value).To(Equal(1650.0)) // Conversion 10 shares @ 110 USD/share to EUR
Expect(outputAssets[0].Holding.TotalChange.Amount).To(Equal(650.0))
Expect(outputAssets[0].Holding.TotalChange.Percent).To(Equal(65.0))
Expect(outputHoldingSummary.Cost).To(Equal(1100.0)) // Sum of 1000 EUR + 100 EUR
Expect(outputHoldingSummary.DayChange.Percent).To(Equal(9.090909090909092))
Expect(outputHoldingSummary.TotalChange.Amount).To(Equal(990.0))
Expect(outputHoldingSummary.TotalChange.Percent).To(Equal(90.0))
})

})

})

When("there is no explicit currency conversion", func() {
Expand Down
19 changes: 0 additions & 19 deletions internal/asset/currency.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,3 @@ func convertAssetQuoteExtendedCurrency(currencyRateByUse currency.CurrencyRateBy
Volume: quoteExtended.Volume,
}
}

func convertAssetHoldingCurrency(currencyRateByUse currency.CurrencyRateByUse, holding c.Holding) c.Holding {
return c.Holding{
Value: holding.Value * currencyRateByUse.QuotePrice,
Cost: holding.Cost * currencyRateByUse.PositionCost,
Quantity: holding.Quantity,
UnitValue: holding.UnitValue * currencyRateByUse.QuotePrice,
UnitCost: holding.UnitCost * currencyRateByUse.PositionCost,
DayChange: c.HoldingChange{
Amount: holding.DayChange.Amount * currencyRateByUse.QuotePrice,
Percent: holding.DayChange.Percent,
},
TotalChange: c.HoldingChange{
Amount: holding.TotalChange.Amount * currencyRateByUse.QuotePrice,
Percent: holding.TotalChange.Percent,
},
Weight: holding.Weight,
}
}
1 change: 1 addition & 0 deletions internal/currency/currency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ var _ = Describe("Currency", func() {
}
outputCurrencyRateByUse := GetCurrencyRateFromContext(inputCtx, "USD")
Expect(outputCurrencyRateByUse.SummaryCost).To(Equal(1.0))
Expect(outputCurrencyRateByUse.PositionCost).To(Equal(1.0))
})
})
})

0 comments on commit d746e19

Please sign in to comment.