From 81a79ab4820c5ba8f0dfcd4b7ce65ecc2f80b321 Mon Sep 17 00:00:00 2001 From: Attila Cseh Date: Mon, 16 Mar 2026 04:13:31 +0100 Subject: [PATCH] unit tests extended --- .../calculator/portfolio-calculator.ts | 131 +++++++----------- ...tfolio-calculator-baln-buy-and-buy.spec.ts | 17 +++ ...aln-buy-and-sell-in-two-activities.spec.ts | 17 +++ ...folio-calculator-baln-buy-and-sell.spec.ts | 17 +++ .../portfolio-calculator-baln-buy.spec.ts | 17 +++ .../roai/portfolio-calculator-btceur.spec.ts | 24 ++++ ...ator-btcusd-buy-and-sell-partially.spec.ts | 41 ++++++ .../roai/portfolio-calculator-btcusd.spec.ts | 24 ++++ .../portfolio-calculator-googl-buy.spec.ts | 17 +++ ...jnug-buy-and-sell-and-buy-and-sell.spec.ts | 17 +++ .../portfolio-calculator-no-orders.spec.ts | 9 ++ ...ulator-novn-buy-and-sell-partially.spec.ts | 17 +++ .../src/app/portfolio/portfolio.service.ts | 12 +- 13 files changed, 277 insertions(+), 83 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 467449090..81095b511 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -18,12 +18,7 @@ import { PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE_PRIORITY_HIGH, PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE_PRIORITY_LOW } from '@ghostfolio/common/config'; -import { - DATE_FORMAT, - getSum, - parseDate, - resetHours -} from '@ghostfolio/common/helper'; +import { DATE_FORMAT, getSum, parseDate } from '@ghostfolio/common/helper'; import { Activity, AssetProfileIdentifier, @@ -51,14 +46,13 @@ import { format, isAfter, isBefore, - isSameYear, isWithinInterval, min, startOfDay, startOfYear, subDays } from 'date-fns'; -import { isNumber, sortBy, sum, uniqBy } from 'lodash'; +import { groupBy as ldGroupBy, isNumber, sortBy, sum, uniqBy } from 'lodash'; export abstract class PortfolioCalculator { protected static readonly ENABLE_LOGGING = false; @@ -717,105 +711,86 @@ export abstract class PortfolioCalculator { return this.snapshot.totalLiabilitiesWithCurrencyEffect; } - public async getPerformance({ end, start }) { - await this.snapshotPromise; - - const { historicalData } = this.snapshot; - + public async getPerformance({ data }: { data: HistoricalDataItem[] }) { const chart: HistoricalDataItem[] = []; let netPerformanceAtStartDate: number; let netPerformanceWithCurrencyEffectAtStartDate: number; const totalInvestmentValuesWithCurrencyEffect: number[] = []; - for (const historicalDataItem of historicalData) { - const date = resetHours(parseDate(historicalDataItem.date)); + for (const historicalDataItem of data) { + if (!isNumber(netPerformanceAtStartDate)) { + netPerformanceAtStartDate = historicalDataItem.netPerformance; - if (!isBefore(date, start) && !isAfter(date, end)) { - if (!isNumber(netPerformanceAtStartDate)) { - netPerformanceAtStartDate = historicalDataItem.netPerformance; + netPerformanceWithCurrencyEffectAtStartDate = + historicalDataItem.netPerformanceWithCurrencyEffect; + } - netPerformanceWithCurrencyEffectAtStartDate = - historicalDataItem.netPerformanceWithCurrencyEffect; - } + const netPerformanceSinceStartDate = + historicalDataItem.netPerformance - netPerformanceAtStartDate; - const netPerformanceSinceStartDate = - historicalDataItem.netPerformance - netPerformanceAtStartDate; + const netPerformanceWithCurrencyEffectSinceStartDate = + historicalDataItem.netPerformanceWithCurrencyEffect - + netPerformanceWithCurrencyEffectAtStartDate; - const netPerformanceWithCurrencyEffectSinceStartDate = - historicalDataItem.netPerformanceWithCurrencyEffect - - netPerformanceWithCurrencyEffectAtStartDate; + if (historicalDataItem.totalInvestmentValueWithCurrencyEffect > 0) { + totalInvestmentValuesWithCurrencyEffect.push( + historicalDataItem.totalInvestmentValueWithCurrencyEffect + ); + } - if (historicalDataItem.totalInvestmentValueWithCurrencyEffect > 0) { - totalInvestmentValuesWithCurrencyEffect.push( - historicalDataItem.totalInvestmentValueWithCurrencyEffect - ); - } + const timeWeightedInvestmentValue = + totalInvestmentValuesWithCurrencyEffect.length > 0 + ? sum(totalInvestmentValuesWithCurrencyEffect) / + totalInvestmentValuesWithCurrencyEffect.length + : 0; - const timeWeightedInvestmentValue = - totalInvestmentValuesWithCurrencyEffect.length > 0 - ? sum(totalInvestmentValuesWithCurrencyEffect) / - totalInvestmentValuesWithCurrencyEffect.length - : 0; - - chart.push({ - ...historicalDataItem, - netPerformance: - historicalDataItem.netPerformance - netPerformanceAtStartDate, - netPerformanceWithCurrencyEffect: - netPerformanceWithCurrencyEffectSinceStartDate, - netPerformanceInPercentage: - timeWeightedInvestmentValue === 0 - ? 0 - : netPerformanceSinceStartDate / timeWeightedInvestmentValue, - netPerformanceInPercentageWithCurrencyEffect: - timeWeightedInvestmentValue === 0 - ? 0 - : netPerformanceWithCurrencyEffectSinceStartDate / - timeWeightedInvestmentValue - // TODO: Add net worth - // netWorth: totalCurrentValueWithCurrencyEffect - // .plus(totalAccountBalanceWithCurrencyEffect) - // .toNumber() - // netWorth: 0 - }); - } + chart.push({ + ...historicalDataItem, + netPerformance: + historicalDataItem.netPerformance - netPerformanceAtStartDate, + netPerformanceWithCurrencyEffect: + netPerformanceWithCurrencyEffectSinceStartDate, + netPerformanceInPercentage: + timeWeightedInvestmentValue === 0 + ? 0 + : netPerformanceSinceStartDate / timeWeightedInvestmentValue, + netPerformanceInPercentageWithCurrencyEffect: + timeWeightedInvestmentValue === 0 + ? 0 + : netPerformanceWithCurrencyEffectSinceStartDate / + timeWeightedInvestmentValue + // TODO: Add net worth + // netWorth: totalCurrentValueWithCurrencyEffect + // .plus(totalAccountBalanceWithCurrencyEffect) + // .toNumber() + // netWorth: 0 + }); } return { chart }; } public async getPerformanceByGroup({ - endDate, - groupBy, - startDate + data, + groupBy }: { - endDate: Date; - groupBy: GroupBy; - startDate: Date; + data: HistoricalDataItem[]; + groupBy: Extract; }) { - const interval = { start: startDate, end: endDate }; const chart: HistoricalDataItem[] = []; if (groupBy === 'year') { - for (const year of eachYearOfInterval(interval)) { - const yearStartDate = startOfYear(year); - const yearEndDate = endOfYear(year); - const yearIntervalStartDate = isSameYear(startDate, yearStartDate) - ? startDate - : yearStartDate; - const yearIntervalEndDate = isSameYear(endDate, yearEndDate) - ? endDate - : yearEndDate; + const dataByYear = ldGroupBy(data, (item) => item.date.slice(0, 4)); + for (const year of Object.keys(dataByYear)) { const { chart: yearChart } = await this.getPerformance({ - end: yearIntervalEndDate, - start: yearIntervalStartDate + data: Object.values(dataByYear[year]) }); const yearPerformanceItem = { ...(yearChart.at(-1) ?? ({} as HistoricalDataItem)), - date: format(yearStartDate, DATE_FORMAT) + date: format(startOfYear(year), DATE_FORMAT) }; chart.push(yearPerformanceItem); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-buy.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-buy.spec.ts index 9a93d0419..71eda96f5 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-buy.spec.ts @@ -138,6 +138,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot).toMatchObject({ currentValueInBaseCurrency: new Big('595.6'), errors: [], @@ -212,6 +219,16 @@ describe('PortfolioCalculator', () => { expect(investmentsByYear).toEqual([ { date: '2021-01-01', investment: 559 } ]); + + expect(performanceByYear.chart).toEqual([ + expect.objectContaining({ + date: '2021-01-01', + netPerformance: 33.4, + netPerformanceInPercentage: 0.06986689805847808, + netPerformanceInPercentageWithCurrencyEffect: 0.06986689805847808, + netPerformanceWithCurrencyEffect: 33.4 + }) + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index c876d0db1..299aa639f 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -154,6 +154,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot).toMatchObject({ currentValueInBaseCurrency: new Big('0'), errors: [], @@ -226,6 +233,16 @@ describe('PortfolioCalculator', () => { expect(investmentsByYear).toEqual([ { date: '2021-01-01', investment: 0 } ]); + + expect(performanceByYear.chart).toEqual([ + expect.objectContaining({ + date: '2021-01-01', + netPerformance: -15.8, + netPerformanceInPercentage: -0.05528341497550735, + netPerformanceInPercentageWithCurrencyEffect: -0.05528341497550735, + netPerformanceWithCurrencyEffect: -15.8 + }) + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell.spec.ts index ae921d6d9..c42bcf05e 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -138,6 +138,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot).toMatchObject({ currentValueInBaseCurrency: new Big('0'), errors: [], @@ -210,6 +217,16 @@ describe('PortfolioCalculator', () => { expect(investmentsByYear).toEqual([ { date: '2021-01-01', investment: 0 } ]); + + expect(performanceByYear.chart).toEqual([ + expect.objectContaining({ + date: '2021-01-01', + netPerformance: -15.8, + netPerformanceInPercentage: -0.05528341497550735, + netPerformanceInPercentageWithCurrencyEffect: -0.05528341497550735, + netPerformanceWithCurrencyEffect: -15.8 + }) + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy.spec.ts index 6207f1417..5d5f2acc5 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy.spec.ts @@ -128,6 +128,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot).toMatchObject({ currentValueInBaseCurrency: new Big('297.8'), errors: [], @@ -209,6 +216,16 @@ describe('PortfolioCalculator', () => { expect(investmentsByYear).toEqual([ { date: '2021-01-01', investment: 273.2 } ]); + + expect(performanceByYear.chart).toEqual([ + expect.objectContaining({ + date: '2021-01-01', + netPerformance: 23.05, + netPerformanceInPercentage: 0.08437042459736459, + netPerformanceInPercentageWithCurrencyEffect: 0.08437042459736459, + netPerformanceWithCurrencyEffect: 23.05 + }) + ]); }); it.only('with BALN.SW buy (with unit price lower than closing price)', async () => { diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur.spec.ts index 055356325..64a65b75c 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur.spec.ts @@ -137,6 +137,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot.historicalData[0]).toEqual({ date: '2021-12-11', investmentValueWithCurrencyEffect: 0, @@ -255,6 +262,23 @@ describe('PortfolioCalculator', () => { { date: '2021-01-01', investment: 44558.42 }, { date: '2022-01-01', investment: 0 } ]); + + expect(performanceByYear.chart).toEqual([ + expect.objectContaining({ + date: '2021-01-01', + netPerformance: -1463.18, + netPerformanceInPercentage: -0.03283734028271199, + netPerformanceInPercentageWithCurrencyEffect: -0.03283734028271199, + netPerformanceWithCurrencyEffect: -1463.18 + }), + expect.objectContaining({ + date: '2022-01-01', + netPerformance: 0, + netPerformanceInPercentage: 0, + netPerformanceInPercentageWithCurrencyEffect: 0, + netPerformanceWithCurrencyEffect: 0 + }) + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index 11765fc49..bcbb60c57 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -151,6 +151,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot).toMatchObject({ currentValueInBaseCurrency: new Big('13298.425356'), errors: [], @@ -266,6 +273,40 @@ describe('PortfolioCalculator', () => { { date: '2017-01-01', investment: -318.54266729999995 }, { date: '2018-01-01', investment: 0 } ]); + + expect(performanceByYear.chart).toEqual([ + expect.objectContaining({ + date: '2014-01-01', + netPerformance: 0, + netPerformanceInPercentage: 0, + netPerformanceInPercentageWithCurrencyEffect: 0, + netPerformanceWithCurrencyEffect: 0 + }), + expect.objectContaining({ + date: '2015-01-01', + netPerformance: 25984.861407, + netPerformanceInPercentage: 40.787097105782344, + netPerformanceInPercentageWithCurrencyEffect: 41.893291864515064, + netPerformanceWithCurrencyEffect: 26689.601865 + }), + expect.objectContaining({ + date: '2016-01-01', + netPerformance: 0, + netPerformanceInPercentage: 0, + netPerformanceInPercentageWithCurrencyEffect: 0, + netPerformanceWithCurrencyEffect: 0 + }), + expect.objectContaining({ + date: '2017-01-01', + netPerformance: 972.1720319999986, + netPerformanceInPercentage: 1.5306926710921496, + netPerformanceInPercentageWithCurrencyEffect: 0.6224618479468005, + netPerformanceWithCurrencyEffect: 395.3373599999977 + }), + expect.objectContaining({ + date: '2018-01-01' + }) + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd.spec.ts index 64882061f..024f24e0e 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd.spec.ts @@ -137,6 +137,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot.historicalData[0]).toEqual({ date: '2021-12-11', investmentValueWithCurrencyEffect: 0, @@ -255,6 +262,23 @@ describe('PortfolioCalculator', () => { { date: '2021-01-01', investment: 44558.42 }, { date: '2022-01-01', investment: 0 } ]); + + expect(performanceByYear.chart).toEqual([ + expect.objectContaining({ + date: '2021-01-01', + netPerformance: -1463.18, + netPerformanceInPercentage: -0.03283734028271199, + netPerformanceInPercentageWithCurrencyEffect: -0.03283734028271199, + netPerformanceWithCurrencyEffect: -1463.18 + }), + expect.objectContaining({ + date: '2022-01-01', + netPerformance: 0, + netPerformanceInPercentage: 0, + netPerformanceInPercentageWithCurrencyEffect: 0, + netPerformanceWithCurrencyEffect: 0 + }) + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts index 122a9aaed..961d59d60 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts @@ -134,6 +134,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot).toMatchObject({ currentValueInBaseCurrency: new Big('103.10483'), errors: [], @@ -228,6 +235,16 @@ describe('PortfolioCalculator', () => { expect(investmentsByYear).toEqual([ { date: '2023-01-01', investment: 82.329056 } ]); + + expect(performanceByYear.chart).toEqual([ + expect.objectContaining({ + date: '2023-01-01', + netPerformance: 23.312582, + netPerformanceInPercentage: 0.2831634799747973, + netPerformanceInPercentageWithCurrencyEffect: 0.2411296201428566, + netPerformanceWithCurrencyEffect: 19.851974 + }) + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-jnug-buy-and-sell-and-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-jnug-buy-and-sell-and-buy-and-sell.spec.ts index d5b22e864..725b26339 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-jnug-buy-and-sell-and-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-jnug-buy-and-sell-and-buy-and-sell.spec.ts @@ -134,6 +134,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot).toMatchObject({ currentValueInBaseCurrency: new Big('0'), errors: [], @@ -185,6 +192,16 @@ describe('PortfolioCalculator', () => { expect(investmentsByYear).toEqual([ { date: '2025-01-01', investment: 0 } ]); + + expect(performanceByYear.chart).toEqual([ + expect.objectContaining({ + date: '2025-01-01', + netPerformance: 39.95, + netPerformanceInPercentage: 0.020208978362720148, + netPerformanceInPercentageWithCurrencyEffect: 0.020208978362720148, + netPerformanceWithCurrencyEffect: 39.95 + }) + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-no-orders.spec.ts index 6c47af7ca..42730cb6e 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-no-orders.spec.ts @@ -98,6 +98,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot).toMatchObject({ currentValueInBaseCurrency: new Big(0), hasErrors: false, @@ -115,6 +122,8 @@ describe('PortfolioCalculator', () => { expect(investmentsByMonth).toEqual([]); expect(investmentsByYear).toEqual([]); + + expect(performanceByYear.chart).toEqual([]); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index 3034e3a1f..ac2f7184a 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -134,6 +134,13 @@ describe('PortfolioCalculator', () => { groupBy: 'year' }); + const performanceByYear = await portfolioCalculator.getPerformanceByGroup( + { + data: portfolioSnapshot.historicalData, + groupBy: 'year' + } + ); + expect(portfolioSnapshot).toMatchObject({ currentValueInBaseCurrency: new Big('87.8'), errors: [], @@ -208,6 +215,16 @@ describe('PortfolioCalculator', () => { expect(investmentsByYear).toEqual([ { date: '2022-01-01', investment: 75.8 } ]); + + expect(performanceByYear.chart).toEqual([ + expect.objectContaining({ + date: '2022-01-01', + netPerformance: 17.68, + netPerformanceInPercentage: 0.12348284960422161, + netPerformanceInPercentageWithCurrencyEffect: 0.12348284960422161, + netPerformanceWithCurrencyEffect: 17.68 + }) + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index d59875575..5b22fa187 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1006,6 +1006,8 @@ export class PortfolioService { const user = await this.userService.user({ id: userId }); const userCurrency = this.getUserCurrency(user); + const { endDate, startDate } = getIntervalFromDateRange(dateRange); + const [accountBalanceItems, { activities }] = await Promise.all([ this.accountBalanceService.getAccountBalanceItems({ filters, @@ -1049,11 +1051,12 @@ export class PortfolioService { const { errors, hasErrors, historicalData } = await portfolioCalculator.getSnapshot(); - const { endDate, startDate } = getIntervalFromDateRange(dateRange); + const items = historicalData.filter(({ date }) => { + return !isBefore(date, startDate) && !isAfter(date, endDate); + }); const { chart: intervalChart } = await portfolioCalculator.getPerformance({ - end: endDate, - start: startDate + data: items }); let chart = intervalChart; @@ -1061,8 +1064,7 @@ export class PortfolioService { if (groupBy) { const { chart: groupedChart } = await portfolioCalculator.getPerformanceByGroup({ - startDate, - endDate, + data: items, groupBy });