Browse Source

Merge 0c4ca8f3ac into a0424147d4

pull/6468/merge
Attila Cseh 2 weeks ago
committed by GitHub
parent
commit
01778c6f8c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 128
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  2. 15
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-buy.spec.ts
  3. 15
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts
  4. 15
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell.spec.ts
  5. 15
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy.spec.ts
  6. 22
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur.spec.ts
  7. 39
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts
  8. 22
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd.spec.ts
  9. 15
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts
  10. 15
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-jnug-buy-and-sell-and-buy-and-sell.spec.ts
  11. 7
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-no-orders.spec.ts
  12. 15
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell-partially.spec.ts
  13. 2
      apps/api/src/app/portfolio/portfolio.controller.ts
  14. 28
      apps/api/src/app/portfolio/portfolio.service.ts

128
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_HIGH,
PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE_PRIORITY_LOW PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE_PRIORITY_LOW
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { import { DATE_FORMAT, getSum, parseDate } from '@ghostfolio/common/helper';
DATE_FORMAT,
getSum,
parseDate,
resetHours
} from '@ghostfolio/common/helper';
import { import {
Activity, Activity,
AssetProfileIdentifier, AssetProfileIdentifier,
@ -57,7 +52,7 @@ import {
startOfYear, startOfYear,
subDays subDays
} from 'date-fns'; } from 'date-fns';
import { isNumber, sortBy, sum, uniqBy } from 'lodash'; import { groupBy as ldGroupBy, isNumber, sortBy, sum, uniqBy } from 'lodash';
export abstract class PortfolioCalculator { export abstract class PortfolioCalculator {
protected static readonly ENABLE_LOGGING = false; protected static readonly ENABLE_LOGGING = false;
@ -716,68 +711,89 @@ export abstract class PortfolioCalculator {
return this.snapshot.totalLiabilitiesWithCurrencyEffect; return this.snapshot.totalLiabilitiesWithCurrencyEffect;
} }
public async getPerformance({ end, start }) { public getPerformance({ data }: { data: HistoricalDataItem[] }) {
await this.snapshotPromise;
const { historicalData } = this.snapshot;
const chart: HistoricalDataItem[] = []; const chart: HistoricalDataItem[] = [];
let netPerformanceAtStartDate: number; let netPerformanceAtStartDate: number;
let netPerformanceWithCurrencyEffectAtStartDate: number; let netPerformanceWithCurrencyEffectAtStartDate: number;
const totalInvestmentValuesWithCurrencyEffect: number[] = []; const totalInvestmentValuesWithCurrencyEffect: number[] = [];
for (const historicalDataItem of historicalData) { for (const historicalDataItem of data) {
const date = resetHours(parseDate(historicalDataItem.date)); if (!isNumber(netPerformanceAtStartDate)) {
netPerformanceAtStartDate = historicalDataItem.netPerformance;
if (!isBefore(date, start) && !isAfter(date, end)) { netPerformanceWithCurrencyEffectAtStartDate =
if (!isNumber(netPerformanceAtStartDate)) { historicalDataItem.netPerformanceWithCurrencyEffect;
netPerformanceAtStartDate = historicalDataItem.netPerformance; }
netPerformanceWithCurrencyEffectAtStartDate = const netPerformanceSinceStartDate =
historicalDataItem.netPerformanceWithCurrencyEffect; historicalDataItem.netPerformance - netPerformanceAtStartDate;
}
const netPerformanceWithCurrencyEffectSinceStartDate =
historicalDataItem.netPerformanceWithCurrencyEffect -
netPerformanceWithCurrencyEffectAtStartDate;
const netPerformanceSinceStartDate = if (historicalDataItem.totalInvestmentValueWithCurrencyEffect > 0) {
historicalDataItem.netPerformance - netPerformanceAtStartDate; totalInvestmentValuesWithCurrencyEffect.push(
historicalDataItem.totalInvestmentValueWithCurrencyEffect
);
}
const netPerformanceWithCurrencyEffectSinceStartDate = const timeWeightedInvestmentValue =
historicalDataItem.netPerformanceWithCurrencyEffect - totalInvestmentValuesWithCurrencyEffect.length > 0
netPerformanceWithCurrencyEffectAtStartDate; ? sum(totalInvestmentValuesWithCurrencyEffect) /
totalInvestmentValuesWithCurrencyEffect.length
: 0;
if (historicalDataItem.totalInvestmentValueWithCurrencyEffect > 0) { chart.push({
totalInvestmentValuesWithCurrencyEffect.push( ...historicalDataItem,
historicalDataItem.totalInvestmentValueWithCurrencyEffect 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
});
}
const timeWeightedInvestmentValue = return { chart };
totalInvestmentValuesWithCurrencyEffect.length > 0 }
? sum(totalInvestmentValuesWithCurrencyEffect) /
totalInvestmentValuesWithCurrencyEffect.length public getPerformanceByGroup({
: 0; data,
groupBy
chart.push({ }: {
...historicalDataItem, data: HistoricalDataItem[];
netPerformance: groupBy: Extract<GroupBy, 'year'>;
historicalDataItem.netPerformance - netPerformanceAtStartDate, }) {
netPerformanceWithCurrencyEffect: const chart: HistoricalDataItem[] = [];
netPerformanceWithCurrencyEffectSinceStartDate,
netPerformanceInPercentage: if (groupBy === 'year') {
timeWeightedInvestmentValue === 0 const dataByYear = ldGroupBy(data, (item) => item.date.slice(0, 4));
? 0
: netPerformanceSinceStartDate / timeWeightedInvestmentValue, for (const year of Object.keys(dataByYear)) {
netPerformanceInPercentageWithCurrencyEffect: const { chart: yearChart } = this.getPerformance({
timeWeightedInvestmentValue === 0 data: Object.values(dataByYear[year])
? 0
: netPerformanceWithCurrencyEffectSinceStartDate /
timeWeightedInvestmentValue
// TODO: Add net worth
// netWorth: totalCurrentValueWithCurrencyEffect
// .plus(totalAccountBalanceWithCurrencyEffect)
// .toNumber()
// netWorth: 0
}); });
const yearPerformanceItem = {
...(yearChart.at(-1) ?? ({} as HistoricalDataItem)),
date: format(startOfYear(year), DATE_FORMAT)
};
chart.push(yearPerformanceItem);
} }
} }

15
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-buy.spec.ts

@ -138,6 +138,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot).toMatchObject({ expect(portfolioSnapshot).toMatchObject({
currentValueInBaseCurrency: new Big('595.6'), currentValueInBaseCurrency: new Big('595.6'),
errors: [], errors: [],
@ -212,6 +217,16 @@ describe('PortfolioCalculator', () => {
expect(investmentsByYear).toEqual([ expect(investmentsByYear).toEqual([
{ date: '2021-01-01', investment: 559 } { 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
})
]);
}); });
}); });
}); });

15
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts

@ -154,6 +154,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot).toMatchObject({ expect(portfolioSnapshot).toMatchObject({
currentValueInBaseCurrency: new Big('0'), currentValueInBaseCurrency: new Big('0'),
errors: [], errors: [],
@ -226,6 +231,16 @@ describe('PortfolioCalculator', () => {
expect(investmentsByYear).toEqual([ expect(investmentsByYear).toEqual([
{ date: '2021-01-01', investment: 0 } { 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
})
]);
}); });
}); });
}); });

15
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell.spec.ts

@ -138,6 +138,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot).toMatchObject({ expect(portfolioSnapshot).toMatchObject({
currentValueInBaseCurrency: new Big('0'), currentValueInBaseCurrency: new Big('0'),
errors: [], errors: [],
@ -210,6 +215,16 @@ describe('PortfolioCalculator', () => {
expect(investmentsByYear).toEqual([ expect(investmentsByYear).toEqual([
{ date: '2021-01-01', investment: 0 } { 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
})
]);
}); });
}); });
}); });

15
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy.spec.ts

@ -128,6 +128,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot).toMatchObject({ expect(portfolioSnapshot).toMatchObject({
currentValueInBaseCurrency: new Big('297.8'), currentValueInBaseCurrency: new Big('297.8'),
errors: [], errors: [],
@ -209,6 +214,16 @@ describe('PortfolioCalculator', () => {
expect(investmentsByYear).toEqual([ expect(investmentsByYear).toEqual([
{ date: '2021-01-01', investment: 273.2 } { 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 () => { it.only('with BALN.SW buy (with unit price lower than closing price)', async () => {

22
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur.spec.ts

@ -137,6 +137,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot.historicalData[0]).toEqual({ expect(portfolioSnapshot.historicalData[0]).toEqual({
date: '2021-12-11', date: '2021-12-11',
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
@ -255,6 +260,23 @@ describe('PortfolioCalculator', () => {
{ date: '2021-01-01', investment: 44558.42 }, { date: '2021-01-01', investment: 44558.42 },
{ date: '2022-01-01', investment: 0 } { 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
})
]);
}); });
}); });
}); });

39
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts

@ -151,6 +151,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot).toMatchObject({ expect(portfolioSnapshot).toMatchObject({
currentValueInBaseCurrency: new Big('13298.425356'), currentValueInBaseCurrency: new Big('13298.425356'),
errors: [], errors: [],
@ -266,6 +271,40 @@ describe('PortfolioCalculator', () => {
{ date: '2017-01-01', investment: -318.54266729999995 }, { date: '2017-01-01', investment: -318.54266729999995 },
{ date: '2018-01-01', investment: 0 } { 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'
})
]);
}); });
}); });
}); });

22
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd.spec.ts

@ -137,6 +137,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot.historicalData[0]).toEqual({ expect(portfolioSnapshot.historicalData[0]).toEqual({
date: '2021-12-11', date: '2021-12-11',
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
@ -255,6 +260,23 @@ describe('PortfolioCalculator', () => {
{ date: '2021-01-01', investment: 44558.42 }, { date: '2021-01-01', investment: 44558.42 },
{ date: '2022-01-01', investment: 0 } { 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
})
]);
}); });
}); });
}); });

15
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts

@ -134,6 +134,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot).toMatchObject({ expect(portfolioSnapshot).toMatchObject({
currentValueInBaseCurrency: new Big('103.10483'), currentValueInBaseCurrency: new Big('103.10483'),
errors: [], errors: [],
@ -228,6 +233,16 @@ describe('PortfolioCalculator', () => {
expect(investmentsByYear).toEqual([ expect(investmentsByYear).toEqual([
{ date: '2023-01-01', investment: 82.329056 } { 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
})
]);
}); });
}); });
}); });

15
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-jnug-buy-and-sell-and-buy-and-sell.spec.ts

@ -134,6 +134,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot).toMatchObject({ expect(portfolioSnapshot).toMatchObject({
currentValueInBaseCurrency: new Big('0'), currentValueInBaseCurrency: new Big('0'),
errors: [], errors: [],
@ -185,6 +190,16 @@ describe('PortfolioCalculator', () => {
expect(investmentsByYear).toEqual([ expect(investmentsByYear).toEqual([
{ date: '2025-01-01', investment: 0 } { 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
})
]);
}); });
}); });
}); });

7
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-no-orders.spec.ts

@ -98,6 +98,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot).toMatchObject({ expect(portfolioSnapshot).toMatchObject({
currentValueInBaseCurrency: new Big(0), currentValueInBaseCurrency: new Big(0),
hasErrors: false, hasErrors: false,
@ -115,6 +120,8 @@ describe('PortfolioCalculator', () => {
expect(investmentsByMonth).toEqual([]); expect(investmentsByMonth).toEqual([]);
expect(investmentsByYear).toEqual([]); expect(investmentsByYear).toEqual([]);
expect(performanceByYear.chart).toEqual([]);
}); });
}); });
}); });

15
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell-partially.spec.ts

@ -134,6 +134,11 @@ describe('PortfolioCalculator', () => {
groupBy: 'year' groupBy: 'year'
}); });
const performanceByYear = portfolioCalculator.getPerformanceByGroup({
data: portfolioSnapshot.historicalData,
groupBy: 'year'
});
expect(portfolioSnapshot).toMatchObject({ expect(portfolioSnapshot).toMatchObject({
currentValueInBaseCurrency: new Big('87.8'), currentValueInBaseCurrency: new Big('87.8'),
errors: [], errors: [],
@ -208,6 +213,16 @@ describe('PortfolioCalculator', () => {
expect(investmentsByYear).toEqual([ expect(investmentsByYear).toEqual([
{ date: '2022-01-01', investment: 75.8 } { 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
})
]);
}); });
}); });
}); });

2
apps/api/src/app/portfolio/portfolio.controller.ts

@ -510,6 +510,7 @@ export class PortfolioController {
@Query('accounts') filterByAccounts?: string, @Query('accounts') filterByAccounts?: string,
@Query('assetClasses') filterByAssetClasses?: string, @Query('assetClasses') filterByAssetClasses?: string,
@Query('dataSource') filterByDataSource?: string, @Query('dataSource') filterByDataSource?: string,
@Query('groupBy') groupBy?: Extract<GroupBy, 'year'>,
@Query('range') dateRange: DateRange = 'max', @Query('range') dateRange: DateRange = 'max',
@Query('symbol') filterBySymbol?: string, @Query('symbol') filterBySymbol?: string,
@Query('tags') filterByTags?: string, @Query('tags') filterByTags?: string,
@ -528,6 +529,7 @@ export class PortfolioController {
const performanceInformation = await this.portfolioService.getPerformance({ const performanceInformation = await this.portfolioService.getPerformance({
dateRange, dateRange,
filters, filters,
groupBy,
impersonationId, impersonationId,
withExcludedAccounts, withExcludedAccounts,
userId: this.request.user.id userId: this.request.user.id

28
apps/api/src/app/portfolio/portfolio.service.ts

@ -991,11 +991,13 @@ export class PortfolioService {
public async getPerformance({ public async getPerformance({
dateRange = 'max', dateRange = 'max',
filters, filters,
groupBy,
impersonationId, impersonationId,
userId userId
}: { }: {
dateRange?: DateRange; dateRange?: DateRange;
filters?: Filter[]; filters?: Filter[];
groupBy?: Extract<GroupBy, 'year'>;
impersonationId: string; impersonationId: string;
userId: string; userId: string;
withExcludedAccounts?: boolean; withExcludedAccounts?: boolean;
@ -1004,6 +1006,8 @@ export class PortfolioService {
const user = await this.userService.user({ id: userId }); const user = await this.userService.user({ id: userId });
const userCurrency = this.getUserCurrency(user); const userCurrency = this.getUserCurrency(user);
const { endDate, startDate } = getIntervalFromDateRange(dateRange);
const [accountBalanceItems, { activities }] = await Promise.all([ const [accountBalanceItems, { activities }] = await Promise.all([
this.accountBalanceService.getAccountBalanceItems({ this.accountBalanceService.getAccountBalanceItems({
filters, filters,
@ -1047,13 +1051,27 @@ export class PortfolioService {
const { errors, hasErrors, historicalData } = const { errors, hasErrors, historicalData } =
await portfolioCalculator.getSnapshot(); await portfolioCalculator.getSnapshot();
const { endDate, startDate } = getIntervalFromDateRange(dateRange); const items = historicalData.filter(({ date }) => {
return !isBefore(date, startDate) && !isAfter(date, endDate);
});
const { chart } = await portfolioCalculator.getPerformance({ const { chart: intervalChart } = portfolioCalculator.getPerformance({
end: endDate, data: items
start: startDate
}); });
let chart = intervalChart;
if (groupBy) {
const { chart: groupedChart } = portfolioCalculator.getPerformanceByGroup(
{
data: items,
groupBy
}
);
chart = groupedChart;
}
const { const {
netPerformance, netPerformance,
netPerformanceInPercentage, netPerformanceInPercentage,
@ -1063,7 +1081,7 @@ export class PortfolioService {
totalInvestment, totalInvestment,
totalInvestmentValueWithCurrencyEffect, totalInvestmentValueWithCurrencyEffect,
valueWithCurrencyEffect valueWithCurrencyEffect
} = chart?.at(-1) ?? { } = intervalChart?.at(-1) ?? {
netPerformance: 0, netPerformance: 0,
netPerformanceInPercentage: 0, netPerformanceInPercentage: 0,
netPerformanceInPercentageWithCurrencyEffect: 0, netPerformanceInPercentageWithCurrencyEffect: 0,

Loading…
Cancel
Save