|  |  | @ -3,6 +3,8 @@ import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfac | 
			
		
	
		
			
				
					|  |  |  | import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; | 
			
		
	
		
			
				
					|  |  |  | import { | 
			
		
	
		
			
				
					|  |  |  |   DataProviderInfo, | 
			
		
	
		
			
				
					|  |  |  |   HistoricalDataItem, | 
			
		
	
		
			
				
					|  |  |  |   InvestmentItem, | 
			
		
	
		
			
				
					|  |  |  |   ResponseError, | 
			
		
	
		
			
				
					|  |  |  |   SymbolMetrics, | 
			
		
	
		
			
				
					|  |  |  |   TimelinePosition | 
			
		
	
	
		
			
				
					|  |  | @ -14,16 +16,11 @@ import Big from 'big.js'; | 
			
		
	
		
			
				
					|  |  |  | import { | 
			
		
	
		
			
				
					|  |  |  |   addDays, | 
			
		
	
		
			
				
					|  |  |  |   addMilliseconds, | 
			
		
	
		
			
				
					|  |  |  |   addMonths, | 
			
		
	
		
			
				
					|  |  |  |   addYears, | 
			
		
	
		
			
				
					|  |  |  |   differenceInDays, | 
			
		
	
		
			
				
					|  |  |  |   endOfDay, | 
			
		
	
		
			
				
					|  |  |  |   format, | 
			
		
	
		
			
				
					|  |  |  |   isBefore, | 
			
		
	
		
			
				
					|  |  |  |   isSameDay, | 
			
		
	
		
			
				
					|  |  |  |   isSameMonth, | 
			
		
	
		
			
				
					|  |  |  |   isSameYear, | 
			
		
	
		
			
				
					|  |  |  |   set, | 
			
		
	
		
			
				
					|  |  |  |   subDays | 
			
		
	
		
			
				
					|  |  |  | } from 'date-fns'; | 
			
		
	
		
			
				
					|  |  |  | import { cloneDeep, first, isNumber, last, sortBy, uniq } from 'lodash'; | 
			
		
	
	
		
			
				
					|  |  | @ -32,10 +29,6 @@ import { CurrentRateService } from './current-rate.service'; | 
			
		
	
		
			
				
					|  |  |  | import { CurrentPositions } from './interfaces/current-positions.interface'; | 
			
		
	
		
			
				
					|  |  |  | import { PortfolioOrderItem } from './interfaces/portfolio-calculator.interface'; | 
			
		
	
		
			
				
					|  |  |  | import { PortfolioOrder } from './interfaces/portfolio-order.interface'; | 
			
		
	
		
			
				
					|  |  |  | import { | 
			
		
	
		
			
				
					|  |  |  |   Accuracy, | 
			
		
	
		
			
				
					|  |  |  |   TimelineSpecification | 
			
		
	
		
			
				
					|  |  |  | } from './interfaces/timeline-specification.interface'; | 
			
		
	
		
			
				
					|  |  |  | import { TransactionPointSymbol } from './interfaces/transaction-point-symbol.interface'; | 
			
		
	
		
			
				
					|  |  |  | import { TransactionPoint } from './interfaces/transaction-point.interface'; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -179,7 +172,15 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |     this.transactionPoints = transactionPoints; | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   public async getChartData(start: Date, end = new Date(Date.now()), step = 1) { | 
			
		
	
		
			
				
					|  |  |  |   public async getChartData({ | 
			
		
	
		
			
				
					|  |  |  |     end = new Date(Date.now()), | 
			
		
	
		
			
				
					|  |  |  |     start, | 
			
		
	
		
			
				
					|  |  |  |     step = 1 | 
			
		
	
		
			
				
					|  |  |  |   }: { | 
			
		
	
		
			
				
					|  |  |  |     end?: Date; | 
			
		
	
		
			
				
					|  |  |  |     start: Date; | 
			
		
	
		
			
				
					|  |  |  |     step?: number; | 
			
		
	
		
			
				
					|  |  |  |   }): Promise<HistoricalDataItem[]> { | 
			
		
	
		
			
				
					|  |  |  |     const symbols: { [symbol: string]: boolean } = {}; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const transactionPointsBeforeEndDate = | 
			
		
	
	
		
			
				
					|  |  | @ -203,6 +204,7 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |       dates.push(resetHours(end)); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     if (transactionPointsBeforeEndDate.length > 0) { | 
			
		
	
		
			
				
					|  |  |  |       for (const item of transactionPointsBeforeEndDate[firstIndex - 1].items) { | 
			
		
	
		
			
				
					|  |  |  |         dataGatheringItems.push({ | 
			
		
	
		
			
				
					|  |  |  |           dataSource: item.dataSource, | 
			
		
	
	
		
			
				
					|  |  | @ -211,6 +213,7 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |         currencies[item.symbol] = item.currency; | 
			
		
	
		
			
				
					|  |  |  |         symbols[item.symbol] = true; | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const { dataProviderInfos, values: marketSymbols } = | 
			
		
	
		
			
				
					|  |  |  |       await this.currentRateService.getValues({ | 
			
		
	
	
		
			
				
					|  |  | @ -248,6 +251,7 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const accumulatedValuesByDate: { | 
			
		
	
		
			
				
					|  |  |  |       [date: string]: { | 
			
		
	
		
			
				
					|  |  |  |         investmentValueWithCurrencyEffect: Big; | 
			
		
	
		
			
				
					|  |  |  |         totalCurrentValue: Big; | 
			
		
	
		
			
				
					|  |  |  |         totalCurrentValueWithCurrencyEffect: Big; | 
			
		
	
		
			
				
					|  |  |  |         totalInvestmentValue: Big; | 
			
		
	
	
		
			
				
					|  |  | @ -263,7 +267,8 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |       [symbol: string]: { | 
			
		
	
		
			
				
					|  |  |  |         currentValues: { [date: string]: Big }; | 
			
		
	
		
			
				
					|  |  |  |         currentValuesWithCurrencyEffect: { [date: string]: Big }; | 
			
		
	
		
			
				
					|  |  |  |         investmentValues: { [date: string]: Big }; | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesAccumulated: { [date: string]: Big }; | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesAccumulatedWithCurrencyEffect: { [date: string]: Big }; | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesWithCurrencyEffect: { [date: string]: Big }; | 
			
		
	
		
			
				
					|  |  |  |         netPerformanceValues: { [date: string]: Big }; | 
			
		
	
		
			
				
					|  |  |  |         netPerformanceValuesWithCurrencyEffect: { [date: string]: Big }; | 
			
		
	
	
		
			
				
					|  |  | @ -276,7 +281,8 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |       const { | 
			
		
	
		
			
				
					|  |  |  |         currentValues, | 
			
		
	
		
			
				
					|  |  |  |         currentValuesWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |         investmentValues, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesAccumulated, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesAccumulatedWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |         netPerformanceValues, | 
			
		
	
		
			
				
					|  |  |  |         netPerformanceValuesWithCurrencyEffect, | 
			
		
	
	
		
			
				
					|  |  | @ -296,7 +302,8 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |       valuesBySymbol[symbol] = { | 
			
		
	
		
			
				
					|  |  |  |         currentValues, | 
			
		
	
		
			
				
					|  |  |  |         currentValuesWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |         investmentValues, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesAccumulated, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesAccumulatedWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |         netPerformanceValues, | 
			
		
	
		
			
				
					|  |  |  |         netPerformanceValuesWithCurrencyEffect, | 
			
		
	
	
		
			
				
					|  |  | @ -318,8 +325,13 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |           symbolValues.currentValuesWithCurrencyEffect?.[dateString] ?? | 
			
		
	
		
			
				
					|  |  |  |           new Big(0); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         const investmentValue = | 
			
		
	
		
			
				
					|  |  |  |           symbolValues.investmentValues?.[dateString] ?? new Big(0); | 
			
		
	
		
			
				
					|  |  |  |         const investmentValueAccumulated = | 
			
		
	
		
			
				
					|  |  |  |           symbolValues.investmentValuesAccumulated?.[dateString] ?? new Big(0); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         const investmentValueAccumulatedWithCurrencyEffect = | 
			
		
	
		
			
				
					|  |  |  |           symbolValues.investmentValuesAccumulatedWithCurrencyEffect?.[ | 
			
		
	
		
			
				
					|  |  |  |             dateString | 
			
		
	
		
			
				
					|  |  |  |           ] ?? new Big(0); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         const investmentValueWithCurrencyEffect = | 
			
		
	
		
			
				
					|  |  |  |           symbolValues.investmentValuesWithCurrencyEffect?.[dateString] ?? | 
			
		
	
	
		
			
				
					|  |  | @ -341,6 +353,10 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |           ] ?? new Big(0); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         accumulatedValuesByDate[dateString] = { | 
			
		
	
		
			
				
					|  |  |  |           investmentValueWithCurrencyEffect: ( | 
			
		
	
		
			
				
					|  |  |  |             accumulatedValuesByDate[dateString] | 
			
		
	
		
			
				
					|  |  |  |               ?.investmentValueWithCurrencyEffect ?? new Big(0) | 
			
		
	
		
			
				
					|  |  |  |           ).add(investmentValueWithCurrencyEffect), | 
			
		
	
		
			
				
					|  |  |  |           totalCurrentValue: ( | 
			
		
	
		
			
				
					|  |  |  |             accumulatedValuesByDate[dateString]?.totalCurrentValue ?? new Big(0) | 
			
		
	
		
			
				
					|  |  |  |           ).add(currentValue), | 
			
		
	
	
		
			
				
					|  |  | @ -351,11 +367,11 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |           totalInvestmentValue: ( | 
			
		
	
		
			
				
					|  |  |  |             accumulatedValuesByDate[dateString]?.totalInvestmentValue ?? | 
			
		
	
		
			
				
					|  |  |  |             new Big(0) | 
			
		
	
		
			
				
					|  |  |  |           ).add(investmentValue), | 
			
		
	
		
			
				
					|  |  |  |           ).add(investmentValueAccumulated), | 
			
		
	
		
			
				
					|  |  |  |           totalInvestmentValueWithCurrencyEffect: ( | 
			
		
	
		
			
				
					|  |  |  |             accumulatedValuesByDate[dateString] | 
			
		
	
		
			
				
					|  |  |  |               ?.totalInvestmentValueWithCurrencyEffect ?? new Big(0) | 
			
		
	
		
			
				
					|  |  |  |           ).add(investmentValueWithCurrencyEffect), | 
			
		
	
		
			
				
					|  |  |  |           ).add(investmentValueAccumulatedWithCurrencyEffect), | 
			
		
	
		
			
				
					|  |  |  |           totalNetPerformanceValue: ( | 
			
		
	
		
			
				
					|  |  |  |             accumulatedValuesByDate[dateString]?.totalNetPerformanceValue ?? | 
			
		
	
		
			
				
					|  |  |  |             new Big(0) | 
			
		
	
	
		
			
				
					|  |  | @ -378,6 +394,7 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     return Object.entries(accumulatedValuesByDate).map(([date, values]) => { | 
			
		
	
		
			
				
					|  |  |  |       const { | 
			
		
	
		
			
				
					|  |  |  |         investmentValueWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |         totalCurrentValue, | 
			
		
	
		
			
				
					|  |  |  |         totalCurrentValueWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |         totalInvestmentValue, | 
			
		
	
	
		
			
				
					|  |  | @ -407,6 +424,8 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |         date, | 
			
		
	
		
			
				
					|  |  |  |         netPerformanceInPercentage, | 
			
		
	
		
			
				
					|  |  |  |         netPerformanceInPercentageWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |         investmentValueWithCurrencyEffect: | 
			
		
	
		
			
				
					|  |  |  |           investmentValueWithCurrencyEffect.toNumber(), | 
			
		
	
		
			
				
					|  |  |  |         netPerformance: totalNetPerformanceValue.toNumber(), | 
			
		
	
		
			
				
					|  |  |  |         netPerformanceWithCurrencyEffect: | 
			
		
	
		
			
				
					|  |  |  |           totalNetPerformanceValueWithCurrencyEffect.toNumber(), | 
			
		
	
	
		
			
				
					|  |  | @ -671,95 +690,27 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   public getInvestmentsByGroup( | 
			
		
	
		
			
				
					|  |  |  |     groupBy: GroupBy | 
			
		
	
		
			
				
					|  |  |  |   ): { date: string; investment: Big }[] { | 
			
		
	
		
			
				
					|  |  |  |     if (this.orders.length === 0) { | 
			
		
	
		
			
				
					|  |  |  |       return []; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const investments: { date: string; investment: Big }[] = []; | 
			
		
	
		
			
				
					|  |  |  |     let currentDate: Date; | 
			
		
	
		
			
				
					|  |  |  |     let investmentByGroup = new Big(0); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     for (const [index, order] of this.orders.entries()) { | 
			
		
	
		
			
				
					|  |  |  |       if ( | 
			
		
	
		
			
				
					|  |  |  |         isSameYear(parseDate(order.date), currentDate) && | 
			
		
	
		
			
				
					|  |  |  |         (groupBy === 'year' || isSameMonth(parseDate(order.date), currentDate)) | 
			
		
	
		
			
				
					|  |  |  |       ) { | 
			
		
	
		
			
				
					|  |  |  |         // Same group: Add up investments
 | 
			
		
	
		
			
				
					|  |  |  |         investmentByGroup = investmentByGroup.plus( | 
			
		
	
		
			
				
					|  |  |  |           order.quantity.mul(order.unitPrice).mul(this.getFactor(order.type)) | 
			
		
	
		
			
				
					|  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |       } else { | 
			
		
	
		
			
				
					|  |  |  |         // New group: Store previous group and reset
 | 
			
		
	
		
			
				
					|  |  |  |         if (currentDate) { | 
			
		
	
		
			
				
					|  |  |  |           investments.push({ | 
			
		
	
		
			
				
					|  |  |  |             date: format( | 
			
		
	
		
			
				
					|  |  |  |               set(currentDate, { | 
			
		
	
		
			
				
					|  |  |  |                 date: 1, | 
			
		
	
		
			
				
					|  |  |  |                 month: groupBy === 'year' ? 0 : currentDate.getMonth() | 
			
		
	
		
			
				
					|  |  |  |               }), | 
			
		
	
		
			
				
					|  |  |  |               DATE_FORMAT | 
			
		
	
		
			
				
					|  |  |  |             ), | 
			
		
	
		
			
				
					|  |  |  |             investment: investmentByGroup | 
			
		
	
		
			
				
					|  |  |  |           }); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         currentDate = parseDate(order.date); | 
			
		
	
		
			
				
					|  |  |  |         investmentByGroup = order.quantity | 
			
		
	
		
			
				
					|  |  |  |           .mul(order.unitPrice) | 
			
		
	
		
			
				
					|  |  |  |           .mul(this.getFactor(order.type)); | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       if (index === this.orders.length - 1) { | 
			
		
	
		
			
				
					|  |  |  |         // Store current group (latest order)
 | 
			
		
	
		
			
				
					|  |  |  |         investments.push({ | 
			
		
	
		
			
				
					|  |  |  |           date: format( | 
			
		
	
		
			
				
					|  |  |  |             set(currentDate, { | 
			
		
	
		
			
				
					|  |  |  |               date: 1, | 
			
		
	
		
			
				
					|  |  |  |               month: groupBy === 'year' ? 0 : currentDate.getMonth() | 
			
		
	
		
			
				
					|  |  |  |             }), | 
			
		
	
		
			
				
					|  |  |  |             DATE_FORMAT | 
			
		
	
		
			
				
					|  |  |  |           ), | 
			
		
	
		
			
				
					|  |  |  |           investment: investmentByGroup | 
			
		
	
		
			
				
					|  |  |  |         }); | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     // Fill in the missing dates with investment = 0
 | 
			
		
	
		
			
				
					|  |  |  |     const startDate = parseDate(first(this.orders).date); | 
			
		
	
		
			
				
					|  |  |  |     const endDate = parseDate(last(this.orders).date); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const allDates: string[] = []; | 
			
		
	
		
			
				
					|  |  |  |     currentDate = startDate; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     while (currentDate <= endDate) { | 
			
		
	
		
			
				
					|  |  |  |       allDates.push( | 
			
		
	
		
			
				
					|  |  |  |         format( | 
			
		
	
		
			
				
					|  |  |  |           set(currentDate, { | 
			
		
	
		
			
				
					|  |  |  |             date: 1, | 
			
		
	
		
			
				
					|  |  |  |             month: groupBy === 'year' ? 0 : currentDate.getMonth() | 
			
		
	
		
			
				
					|  |  |  |           }), | 
			
		
	
		
			
				
					|  |  |  |           DATE_FORMAT | 
			
		
	
		
			
				
					|  |  |  |         ) | 
			
		
	
		
			
				
					|  |  |  |   public getInvestmentsByGroup({ | 
			
		
	
		
			
				
					|  |  |  |     data, | 
			
		
	
		
			
				
					|  |  |  |     groupBy | 
			
		
	
		
			
				
					|  |  |  |   }: { | 
			
		
	
		
			
				
					|  |  |  |     data: HistoricalDataItem[]; | 
			
		
	
		
			
				
					|  |  |  |     groupBy: GroupBy; | 
			
		
	
		
			
				
					|  |  |  |   }): InvestmentItem[] { | 
			
		
	
		
			
				
					|  |  |  |     const groupedData: { [dateGroup: string]: Big } = {}; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     for (const { date, investmentValueWithCurrencyEffect } of data) { | 
			
		
	
		
			
				
					|  |  |  |       const dateGroup = | 
			
		
	
		
			
				
					|  |  |  |         groupBy === 'month' ? date.substring(0, 7) : date.substring(0, 4); | 
			
		
	
		
			
				
					|  |  |  |       groupedData[dateGroup] = (groupedData[dateGroup] ?? new Big(0)).plus( | 
			
		
	
		
			
				
					|  |  |  |         investmentValueWithCurrencyEffect | 
			
		
	
		
			
				
					|  |  |  |       ); | 
			
		
	
		
			
				
					|  |  |  |       currentDate.setMonth(currentDate.getMonth() + 1); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     for (const date of allDates) { | 
			
		
	
		
			
				
					|  |  |  |       const existingInvestment = investments.find((investment) => { | 
			
		
	
		
			
				
					|  |  |  |         return investment.date === date; | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       if (!existingInvestment) { | 
			
		
	
		
			
				
					|  |  |  |         investments.push({ date, investment: new Big(0) }); | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     return sortBy(investments, ({ date }) => { | 
			
		
	
		
			
				
					|  |  |  |       return date; | 
			
		
	
		
			
				
					|  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  |     return Object.keys(groupedData).map((dateGroup) => ({ | 
			
		
	
		
			
				
					|  |  |  |       date: groupBy === 'month' ? `${dateGroup}-01` : `${dateGroup}-01-01`, | 
			
		
	
		
			
				
					|  |  |  |       investment: groupedData[dateGroup].toNumber() | 
			
		
	
		
			
				
					|  |  |  |     })); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   private calculateOverallPerformance(positions: TimelinePosition[]) { | 
			
		
	
	
		
			
				
					|  |  | @ -886,17 +837,6 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |     return factor; | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   private addToDate(date: Date, accuracy: Accuracy): Date { | 
			
		
	
		
			
				
					|  |  |  |     switch (accuracy) { | 
			
		
	
		
			
				
					|  |  |  |       case 'day': | 
			
		
	
		
			
				
					|  |  |  |         return addDays(date, 1); | 
			
		
	
		
			
				
					|  |  |  |       case 'month': | 
			
		
	
		
			
				
					|  |  |  |         return addMonths(date, 1); | 
			
		
	
		
			
				
					|  |  |  |       case 'year': | 
			
		
	
		
			
				
					|  |  |  |         return addYears(date, 1); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   private getSymbolMetrics({ | 
			
		
	
		
			
				
					|  |  |  |     end, | 
			
		
	
		
			
				
					|  |  |  |     exchangeRates, | 
			
		
	
	
		
			
				
					|  |  | @ -933,7 +873,10 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |     let initialValueWithCurrencyEffect: Big; | 
			
		
	
		
			
				
					|  |  |  |     let investmentAtStartDate: Big; | 
			
		
	
		
			
				
					|  |  |  |     let investmentAtStartDateWithCurrencyEffect: Big; | 
			
		
	
		
			
				
					|  |  |  |     const investmentValues: { [date: string]: Big } = {}; | 
			
		
	
		
			
				
					|  |  |  |     const investmentValuesAccumulated: { [date: string]: Big } = {}; | 
			
		
	
		
			
				
					|  |  |  |     const investmentValuesAccumulatedWithCurrencyEffect: { | 
			
		
	
		
			
				
					|  |  |  |       [date: string]: Big; | 
			
		
	
		
			
				
					|  |  |  |     } = {}; | 
			
		
	
		
			
				
					|  |  |  |     const investmentValuesWithCurrencyEffect: { [date: string]: Big } = {}; | 
			
		
	
		
			
				
					|  |  |  |     let lastAveragePrice = new Big(0); | 
			
		
	
		
			
				
					|  |  |  |     let lastAveragePriceWithCurrencyEffect = new Big(0); | 
			
		
	
	
		
			
				
					|  |  | @ -975,7 +918,8 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |         hasErrors: false, | 
			
		
	
		
			
				
					|  |  |  |         initialValue: new Big(0), | 
			
		
	
		
			
				
					|  |  |  |         initialValueWithCurrencyEffect: new Big(0), | 
			
		
	
		
			
				
					|  |  |  |         investmentValues: {}, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesAccumulated: {}, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesAccumulatedWithCurrencyEffect: {}, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesWithCurrencyEffect: {}, | 
			
		
	
		
			
				
					|  |  |  |         netPerformance: new Big(0), | 
			
		
	
		
			
				
					|  |  |  |         netPerformancePercentage: new Big(0), | 
			
		
	
	
		
			
				
					|  |  | @ -1014,7 +958,8 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |         hasErrors: true, | 
			
		
	
		
			
				
					|  |  |  |         initialValue: new Big(0), | 
			
		
	
		
			
				
					|  |  |  |         initialValueWithCurrencyEffect: new Big(0), | 
			
		
	
		
			
				
					|  |  |  |         investmentValues: {}, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesAccumulated: {}, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesAccumulatedWithCurrencyEffect: {}, | 
			
		
	
		
			
				
					|  |  |  |         investmentValuesWithCurrencyEffect: {}, | 
			
		
	
		
			
				
					|  |  |  |         netPerformance: new Big(0), | 
			
		
	
		
			
				
					|  |  |  |         netPerformancePercentage: new Big(0), | 
			
		
	
	
		
			
				
					|  |  | @ -1407,11 +1352,15 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |                 feesWithCurrencyEffect.minus(feesAtStartDateWithCurrencyEffect) | 
			
		
	
		
			
				
					|  |  |  |               ); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |           investmentValues[order.date] = totalInvestment; | 
			
		
	
		
			
				
					|  |  |  |           investmentValuesAccumulated[order.date] = totalInvestment; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |           investmentValuesWithCurrencyEffect[order.date] = | 
			
		
	
		
			
				
					|  |  |  |           investmentValuesAccumulatedWithCurrencyEffect[order.date] = | 
			
		
	
		
			
				
					|  |  |  |             totalInvestmentWithCurrencyEffect; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |           investmentValuesWithCurrencyEffect[order.date] = ( | 
			
		
	
		
			
				
					|  |  |  |             investmentValuesWithCurrencyEffect[order.date] ?? new Big(0) | 
			
		
	
		
			
				
					|  |  |  |           ).add(transactionInvestmentWithCurrencyEffect); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |           timeWeightedInvestmentValues[order.date] = | 
			
		
	
		
			
				
					|  |  |  |             totalInvestmentDays > 0 | 
			
		
	
		
			
				
					|  |  |  |               ? sumOfTimeWeightedInvestments.div(totalInvestmentDays) | 
			
		
	
	
		
			
				
					|  |  | @ -1569,7 +1518,8 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |       grossPerformancePercentageWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |       initialValue, | 
			
		
	
		
			
				
					|  |  |  |       initialValueWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |       investmentValues, | 
			
		
	
		
			
				
					|  |  |  |       investmentValuesAccumulated, | 
			
		
	
		
			
				
					|  |  |  |       investmentValuesAccumulatedWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |       investmentValuesWithCurrencyEffect, | 
			
		
	
		
			
				
					|  |  |  |       netPerformancePercentage, | 
			
		
	
		
			
				
					|  |  |  |       netPerformancePercentageWithCurrencyEffect, | 
			
		
	
	
		
			
				
					|  |  | @ -1591,15 +1541,4 @@ export class PortfolioCalculator { | 
			
		
	
		
			
				
					|  |  |  |         timeWeightedAverageInvestmentBetweenStartAndEndDateWithCurrencyEffect | 
			
		
	
		
			
				
					|  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   private isNextItemActive( | 
			
		
	
		
			
				
					|  |  |  |     timelineSpecification: TimelineSpecification[], | 
			
		
	
		
			
				
					|  |  |  |     currentDate: Date, | 
			
		
	
		
			
				
					|  |  |  |     i: number | 
			
		
	
		
			
				
					|  |  |  |   ) { | 
			
		
	
		
			
				
					|  |  |  |     return ( | 
			
		
	
		
			
				
					|  |  |  |       i + 1 < timelineSpecification.length && | 
			
		
	
		
			
				
					|  |  |  |       !isBefore(currentDate, parseDate(timelineSpecification[i + 1].start)) | 
			
		
	
		
			
				
					|  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
	
		
			
				
					|  |  | 
 |