Browse Source

Bugfix/improve portfolio calculation for activity with no market data (#5130)

* Improve portfolio calculation for activity with no market data

* Update changelog
pull/5153/head
Kenrick Tandrian 2 weeks ago
committed by GitHub
parent
commit
92d3079f2d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 44
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-valuable.spec.ts
  3. 20
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts

1
CHANGELOG.md

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Improved the portfolio calculations for activities without historical market data
- Improved the asset profile dialog’s data gathering checkbox of the admin control panel to reflect the global settings
- Improved the language localization for Catalan (`ca`)
- Improved the language localization for Portuguese (`pt`)

44
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-valuable.spec.ts

@ -114,14 +114,8 @@ describe('PortfolioCalculator', () => {
expect(portfolioSnapshot).toMatchObject({
currentValueInBaseCurrency: new Big('500000'),
// TODO: []
errors: [
{
dataSource: 'MANUAL',
symbol: 'dac95060-d4f2-4653-a253-2c45e6fb5cde'
}
],
hasErrors: true, // TODO: false
errors: [],
hasErrors: false,
positions: [
{
averagePrice: new Big('500000'),
@ -132,31 +126,35 @@ describe('PortfolioCalculator', () => {
fee: new Big('0'),
feeInBaseCurrency: new Big('0'),
firstBuyDate: '2022-01-01',
grossPerformance: null,
grossPerformancePercentage: null,
grossPerformancePercentageWithCurrencyEffect: null,
grossPerformanceWithCurrencyEffect: null,
investment: new Big('0'), // TODO: new Big('500000')
investmentWithCurrencyEffect: new Big('0'), // TODO: new Big('500000')
grossPerformance: new Big('0'),
grossPerformancePercentage: new Big('0'),
grossPerformancePercentageWithCurrencyEffect: new Big('0'),
grossPerformanceWithCurrencyEffect: new Big('0'),
investment: new Big('500000'),
investmentWithCurrencyEffect: new Big('500000'),
marketPrice: null,
marketPriceInBaseCurrency: 500000,
netPerformance: null,
netPerformancePercentage: null,
netPerformancePercentageWithCurrencyEffectMap: null,
netPerformanceWithCurrencyEffectMap: null,
netPerformance: new Big('0'),
netPerformancePercentage: new Big('0'),
netPerformancePercentageWithCurrencyEffectMap: {
max: new Big('0')
},
netPerformanceWithCurrencyEffectMap: {
max: new Big('0')
},
quantity: new Big('1'),
symbol: 'dac95060-d4f2-4653-a253-2c45e6fb5cde',
tags: [],
timeWeightedInvestment: new Big('0'),
timeWeightedInvestmentWithCurrencyEffect: new Big('0'),
timeWeightedInvestment: new Big('500000'),
timeWeightedInvestmentWithCurrencyEffect: new Big('500000'),
transactionCount: 1,
valueInBaseCurrency: new Big('500000')
}
],
totalFeesWithCurrencyEffect: new Big('0'),
totalInterestWithCurrencyEffect: new Big('0'),
totalInvestment: new Big('0'), // TODO: new Big('500000')
totalInvestmentWithCurrencyEffect: new Big('0'), // TODO: new Big('500000')
totalInvestment: new Big('500000'),
totalInvestmentWithCurrencyEffect: new Big('500000'),
totalLiabilitiesWithCurrencyEffect: new Big('0')
});
@ -166,7 +164,7 @@ describe('PortfolioCalculator', () => {
netPerformanceInPercentage: 0,
netPerformanceInPercentageWithCurrencyEffect: 0,
netPerformanceWithCurrencyEffect: 0,
totalInvestmentValueWithCurrencyEffect: 0 // TODO: 500000
totalInvestmentValueWithCurrencyEffect: 500000
})
);
});

20
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts

@ -231,7 +231,20 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
const startDateString = format(start, DATE_FORMAT);
const unitPriceAtStartDate = marketSymbolMap[startDateString]?.[symbol];
const unitPriceAtEndDate = marketSymbolMap[endDateString]?.[symbol];
let unitPriceAtEndDate = marketSymbolMap[endDateString]?.[symbol];
let latestActivity = orders.at(-1);
if (
dataSource === 'MANUAL' &&
['BUY', 'SELL'].includes(latestActivity?.type) &&
latestActivity?.unitPrice &&
!unitPriceAtEndDate
) {
// For BUY / SELL activities with a MANUAL data source where no historical market price is available,
// the calculation should fall back to using the activity’s unit price.
unitPriceAtEndDate = latestActivity.unitPrice;
}
if (
!unitPriceAtEndDate ||
@ -344,9 +357,10 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
});
}
const lastOrder = orders.at(-1);
latestActivity = orders.at(-1);
lastUnitPrice = lastOrder.unitPriceFromMarketData ?? lastOrder.unitPrice;
lastUnitPrice =
latestActivity.unitPriceFromMarketData ?? latestActivity.unitPrice;
}
// Sort orders so that the start and end placeholder order are at the correct

Loading…
Cancel
Save