diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index c39eb8c9c..1576e13cb 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -44,7 +44,7 @@ import { min, subDays } from 'date-fns'; -import { first, last, uniq, uniqBy } from 'lodash'; +import { first, last, sum, uniq, uniqBy } from 'lodash'; export abstract class PortfolioCalculator { protected static readonly ENABLE_LOGGING = false; @@ -99,6 +99,8 @@ export abstract class PortfolioCalculator { this.dateRange = dateRange; this.exchangeRateDataService = exchangeRateDataService; + let dateOfFirstActivity = new Date(); + this.activities = activities .map( ({ @@ -110,6 +112,10 @@ export abstract class PortfolioCalculator { type, unitPrice }) => { + if (isBefore(date, dateOfFirstActivity)) { + dateOfFirstActivity = date; + } + if (isAfter(date, new Date(Date.now()))) { // Adapt date to today if activity is in future (e.g. liability) // to include it in the interval @@ -132,10 +138,13 @@ export abstract class PortfolioCalculator { }); this.redisCacheService = redisCacheService; - this.useCache = useCache; + this.useCache = false; // useCache; this.userId = userId; - const { endDate, startDate } = getInterval(dateRange); + const { endDate, startDate } = getInterval( + 'max', + subDays(dateOfFirstActivity, 1) + ); this.endDate = endDate; this.startDate = startDate; @@ -1082,6 +1091,57 @@ export abstract class PortfolioCalculator { return this.snapshot; } + public async getPerformance({ end, start }) { + await this.snapshotPromise; + + const { chartData } = this.snapshot; + + const newChartData = []; + + let netPerformanceAtStartDate; + let netPerformanceWithCurrencyEffectAtStartDate; + let netPerformanceInPercentageWithCurrencyEffectAtStartDate; + let investmentValuesWithCurrencyEffect = []; + + for (let historicalDataItem of chartData) { + if ( + !isBefore(parseDate(historicalDataItem.date), start) && + !isAfter(parseDate(historicalDataItem.date), end) + ) { + if (!netPerformanceAtStartDate) { + netPerformanceAtStartDate = historicalDataItem.netPerformance; + + netPerformanceWithCurrencyEffectAtStartDate = + historicalDataItem.netPerformanceWithCurrencyEffect; + + netPerformanceInPercentageWithCurrencyEffectAtStartDate = + historicalDataItem.netPerformanceInPercentageWithCurrencyEffect; + } + + investmentValuesWithCurrencyEffect.push( + historicalDataItem.investmentValueWithCurrencyEffect + ); + + // TODO: Normalize remaining metrics + newChartData.push({ + ...historicalDataItem, + netPerformance: + historicalDataItem.netPerformance - netPerformanceAtStartDate, + netPerformanceWithCurrencyEffect: + historicalDataItem.netPerformanceWithCurrencyEffect - + netPerformanceWithCurrencyEffectAtStartDate, + netPerformanceInPercentageWithCurrencyEffect: + historicalDataItem.netPerformanceWithCurrencyEffect / + // TODO: This is not correct yet + (sum(investmentValuesWithCurrencyEffect) / + investmentValuesWithCurrencyEffect.length) + }); + } + } + + return newChartData; + } + public getStartDate() { let firstAccountBalanceDate: Date; let firstActivityDate: Date; diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 0f64ccaed..63e1b20ed 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -340,10 +340,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { const ordersByDate: { [date: string]: PortfolioOrderItem[] } = {}; for (const order of orders) { - if (['BUY', 'SELL'].includes(order.type)) { - ordersByDate[order.date] = ordersByDate[order.date] ?? []; - ordersByDate[order.date].push(order); - } + ordersByDate[order.date] = ordersByDate[order.date] ?? []; + ordersByDate[order.date].push(order); } while (isBefore(day, end)) { diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 4d5a08b03..688ea9cf6 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1120,7 +1120,7 @@ export class PortfolioService { ) ); - const { endDate } = getInterval(dateRange); + const { endDate, startDate } = getInterval(dateRange); console.time('------- PortfolioService.getPerformance - 2'); @@ -1230,10 +1230,15 @@ export class PortfolioService { console.timeEnd('------ PortfolioService.getPerformance'); + const newChartData = await portfolioCalculator.getPerformance({ + end: endDate, + start: startDate + }); + return { errors, hasErrors, - chart: chartData, + chart: newChartData, firstOrderDate: parseDate(chartData[0]?.date), performance: { currentNetWorth,