diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index ba35a7670..b165ed5c6 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -16,7 +16,6 @@ import { addMilliseconds, addMonths, addYears, - differenceInDays, endOfDay, format, isAfter, @@ -45,7 +44,7 @@ import { TransactionPointSymbol } from './interfaces/transaction-point-symbol.in import { TransactionPoint } from './interfaces/transaction-point.interface'; export class PortfolioCalculator { - private static readonly CALCULATE_PERCENTAGE_PERFORMANCE_WITH_TIME_WEIGHTED_INVESTMENT = + private static readonly CALCULATE_PERCENTAGE_PERFORMANCE_WITH_MAX_INVESTMENT = true; private static readonly ENABLE_LOGGING = false; @@ -622,6 +621,7 @@ export class PortfolioCalculator { if (firstIndex > 0) { firstIndex--; } + const initialValues: { [symbol: string]: Big } = {}; const positions: TimelinePosition[] = []; let hasAnySymbolMetricsErrors = false; @@ -635,9 +635,9 @@ export class PortfolioCalculator { grossPerformance, grossPerformancePercentage, hasErrors, + initialValue, netPerformance, - netPerformancePercentage, - timeWeightedInvestment + netPerformancePercentage } = this.getSymbolMetrics({ end, marketSymbolMap, @@ -646,9 +646,9 @@ export class PortfolioCalculator { }); hasAnySymbolMetricsErrors = hasAnySymbolMetricsErrors || hasErrors; + initialValues[item.symbol] = initialValue; positions.push({ - timeWeightedInvestment, averagePrice: item.quantity.eq(0) ? new Big(0) : item.investment.div(item.quantity), @@ -683,7 +683,7 @@ export class PortfolioCalculator { } } - const overall = this.calculateOverallPerformance(positions); + const overall = this.calculateOverallPerformance(positions, initialValues); return { ...overall, @@ -906,13 +906,18 @@ export class PortfolioCalculator { }; } - private calculateOverallPerformance(positions: TimelinePosition[]) { + private calculateOverallPerformance( + positions: TimelinePosition[], + initialValues: { [symbol: string]: Big } + ) { let currentValue = new Big(0); let grossPerformance = new Big(0); + let grossPerformancePercentage = new Big(0); let hasErrors = false; let netPerformance = new Big(0); + let netPerformancePercentage = new Big(0); + let sumOfWeights = new Big(0); let totalInvestment = new Big(0); - let totalTimeWeightedInvestment = new Big(0); for (const currentPosition of positions) { if (currentPosition.marketPrice) { @@ -960,18 +965,22 @@ export class PortfolioCalculator { } } + if (sumOfWeights.gt(0)) { + grossPerformancePercentage = grossPerformancePercentage.div(sumOfWeights); + netPerformancePercentage = netPerformancePercentage.div(sumOfWeights); + } else { + grossPerformancePercentage = new Big(0); + netPerformancePercentage = new Big(0); + } + return { currentValue, grossPerformance, + grossPerformancePercentage, hasErrors, netPerformance, - totalInvestment, - netPerformancePercentage: totalTimeWeightedInvestment.eq(0) - ? new Big(0) - : netPerformance.div(totalTimeWeightedInvestment), - grossPerformancePercentage: totalTimeWeightedInvestment.eq(0) - ? new Big(0) - : grossPerformance.div(totalTimeWeightedInvestment) + netPerformancePercentage, + totalInvestment }; } @@ -1185,7 +1194,6 @@ export class PortfolioCalculator { let averagePriceAtEndDate = new Big(0); let averagePriceAtStartDate = new Big(0); - const currentValues: { [date: string]: Big } = {}; let feesAtStartDate = new Big(0); let fees = new Big(0); let grossPerformance = new Big(0); @@ -1193,6 +1201,7 @@ export class PortfolioCalculator { let grossPerformanceFromSells = new Big(0); let initialValue: Big; let investmentAtStartDate: Big; + const currentValues: { [date: string]: Big } = {}; const investmentValues: { [date: string]: Big } = {}; const maxInvestmentValues: { [date: string]: Big } = {}; let lastAveragePrice = new Big(0); @@ -1240,9 +1249,6 @@ export class PortfolioCalculator { return order.itemType === 'end'; }); - let totalInvestmentDays = 0; - let sumOfTimeWeightedInvestments = new Big(0); - return this.calculatePerformanceOfSymbol( orders, indexOfStartOrder, @@ -1974,9 +1980,6 @@ export class PortfolioCalculator { 2 )} -> ${averagePriceAtEndDate.toFixed(2)} Total investment: ${totalInvestment.toFixed(2)} - Time weighted investment: ${timeWeightedAverageInvestmentBetweenStartAndEndDate.toFixed( - 2 - )} Max. total investment: ${maxTotalInvestment.toFixed(2)} Gross performance: ${totalGrossPerformance.toFixed( 2 diff --git a/libs/common/src/lib/interfaces/timeline-position.interface.ts b/libs/common/src/lib/interfaces/timeline-position.interface.ts index 1b27de8dc..de4c3ff19 100644 --- a/libs/common/src/lib/interfaces/timeline-position.interface.ts +++ b/libs/common/src/lib/interfaces/timeline-position.interface.ts @@ -16,6 +16,5 @@ export interface TimelinePosition { quantity: Big; symbol: string; tags?: Tag[]; - timeWeightedInvestment: Big; transactionCount: number; }