Browse Source

Accumulate the values of each holding right away in computeSnapshot()

pull/8274/head
Andrea Bugeja 2 days ago
parent
commit
3165cd50ef
Failed to extract signature
  1. 6
      CHANGELOG.md
  2. 82
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

6
CHANGELOG.md

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Changed
- Reduced the memory usage of the portfolio calculator for portfolios with many holdings
## 3.90.0 - 2026-10-21 ## 3.90.0 - 2026-10-21
### Changed ### Changed

82
apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

@ -394,22 +394,6 @@ export abstract class PortfolioCalculator {
[date: string]: AccumulatedValues; [date: string]: AccumulatedValues;
} = {}; } = {};
const valuesByAssetProfileIdentifier: {
[assetProfileIdentifier: string]: {
averageInvestmentValues: { [date: string]: Big };
averageInvestmentValuesWithCurrencyEffect: { [date: string]: Big };
currentValues: { [date: string]: Big };
currentValuesWithCurrencyEffect: { [date: string]: Big };
dividendValuesWithCurrencyEffect: { [date: string]: Big };
investmentValuesAccumulated: { [date: string]: Big };
investmentValuesAccumulatedWithCurrencyEffect: { [date: string]: Big };
investmentValuesWithCurrencyEffect: { [date: string]: Big };
netPerformanceValues: { [date: string]: Big };
netPerformanceValuesWithCurrencyEffect: { [date: string]: Big };
netWorthValuesWithCurrencyEffect: { [date: string]: Big };
};
} = {};
for (const item of latestHoldingBalances.holdings) { for (const item of latestHoldingBalances.holdings) {
const assetProfileIdentifier = getAssetProfileIdentifier(item); const assetProfileIdentifier = getAssetProfileIdentifier(item);
@ -478,34 +462,33 @@ export abstract class PortfolioCalculator {
// contributes nothing but its balance to the performance calculation. It // contributes nothing but its balance to the performance calculation. It
// is therefore excluded from the value and the investment, while still // is therefore excluded from the value and the investment, while still
// contributing to the net worth. // contributing to the net worth.
valuesByAssetProfileIdentifier[assetProfileIdentifier] = const assetProfileValues = isCashInBaseCurrency
isCashInBaseCurrency ? {
? { averageInvestmentValues: {},
averageInvestmentValues: {}, averageInvestmentValuesWithCurrencyEffect: {},
averageInvestmentValuesWithCurrencyEffect: {}, currentValues: {},
currentValues: {}, currentValuesWithCurrencyEffect: {},
currentValuesWithCurrencyEffect: {}, dividendValuesWithCurrencyEffect: {},
dividendValuesWithCurrencyEffect: {}, investmentValuesAccumulated: {},
investmentValuesAccumulated: {}, investmentValuesAccumulatedWithCurrencyEffect: {},
investmentValuesAccumulatedWithCurrencyEffect: {}, investmentValuesWithCurrencyEffect: {},
investmentValuesWithCurrencyEffect: {}, netPerformanceValues: {},
netPerformanceValues: {}, netPerformanceValuesWithCurrencyEffect: {},
netPerformanceValuesWithCurrencyEffect: {}, netWorthValuesWithCurrencyEffect: currentValuesWithCurrencyEffect
netWorthValuesWithCurrencyEffect: currentValuesWithCurrencyEffect }
} : {
: { averageInvestmentValues,
averageInvestmentValues, averageInvestmentValuesWithCurrencyEffect,
averageInvestmentValuesWithCurrencyEffect, currentValues,
currentValues, currentValuesWithCurrencyEffect,
currentValuesWithCurrencyEffect, dividendValuesWithCurrencyEffect,
dividendValuesWithCurrencyEffect, investmentValuesAccumulated,
investmentValuesAccumulated, investmentValuesAccumulatedWithCurrencyEffect,
investmentValuesAccumulatedWithCurrencyEffect, investmentValuesWithCurrencyEffect,
investmentValuesWithCurrencyEffect, netPerformanceValues,
netPerformanceValues, netPerformanceValuesWithCurrencyEffect,
netPerformanceValuesWithCurrencyEffect, netWorthValuesWithCurrencyEffect: currentValuesWithCurrencyEffect
netWorthValuesWithCurrencyEffect: currentValuesWithCurrencyEffect };
};
positions.push({ positions.push({
averageInvestment, averageInvestment,
@ -580,15 +563,10 @@ export abstract class PortfolioCalculator {
) { ) {
errors.push({ dataSource: item.dataSource, symbol: item.symbol }); errors.push({ dataSource: item.dataSource, symbol: item.symbol });
} }
}
const assetProfileIdentifiers = Object.keys(valuesByAssetProfileIdentifier);
for (const dateString of chartDates) {
for (const assetProfileIdentifier of assetProfileIdentifiers) {
const assetProfileValues =
valuesByAssetProfileIdentifier[assetProfileIdentifier];
// Accumulate each holding right away, so that its values by date do not
// have to be kept for all holdings at once
for (const dateString of chartDates) {
const currentValue = const currentValue =
assetProfileValues.currentValues?.[dateString] ?? new Big(0); assetProfileValues.currentValues?.[dateString] ?? new Big(0);

Loading…
Cancel
Save