Browse Source

feat(api): support group by year in portfolio performance endpoint

pull/6468/head
Attila Cseh 4 weeks ago
parent
commit
e24eb4a4b4
  1. 41
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  2. 2
      apps/api/src/app/portfolio/portfolio.controller.ts
  3. 19
      apps/api/src/app/portfolio/portfolio.service.ts

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

@ -51,6 +51,7 @@ import {
format, format,
isAfter, isAfter,
isBefore, isBefore,
isSameYear,
isWithinInterval, isWithinInterval,
min, min,
startOfDay, startOfDay,
@ -784,6 +785,46 @@ export abstract class PortfolioCalculator {
return { chart }; return { chart };
} }
public async getPerformanceByGroup({
endDate,
groupBy,
startDate
}: {
endDate: Date;
groupBy: GroupBy;
startDate: Date;
}) {
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 { chart: yearChart } = await this.getPerformance({
end: yearIntervalEndDate,
start: yearIntervalStartDate
});
const yearPerformanceItem = {
...(yearChart.at(-1) ?? ({} as HistoricalDataItem)),
date: format(yearStartDate, DATE_FORMAT)
};
chart.push(yearPerformanceItem);
}
}
return { chart };
}
public async getSnapshot() { public async getSnapshot() {
await this.snapshotPromise; await this.snapshotPromise;

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

19
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;
@ -1049,11 +1051,24 @@ export class PortfolioService {
const { endDate, startDate } = getIntervalFromDateRange(dateRange); const { endDate, startDate } = getIntervalFromDateRange(dateRange);
const { chart } = await portfolioCalculator.getPerformance({ const { chart: intervalChart } = await portfolioCalculator.getPerformance({
end: endDate, end: endDate,
start: startDate start: startDate
}); });
let chart = intervalChart;
if (groupBy) {
const { chart: groupedChart } =
await portfolioCalculator.getPerformanceByGroup({
startDate,
endDate,
groupBy
});
chart = groupedChart;
}
const { const {
netPerformance, netPerformance,
netPerformanceInPercentage, netPerformanceInPercentage,
@ -1063,7 +1078,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