| 
						
						
							
								
							
						
						
					 | 
					@ -2,6 +2,17 @@ import { Currency } from '@prisma/client'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { CurrentRateService } from '@ghostfolio/api/app/core/current-rate.service'; | 
					 | 
					 | 
					import { CurrentRateService } from '@ghostfolio/api/app/core/current-rate.service'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { OrderType } from '@ghostfolio/api/models/order-type'; | 
					 | 
					 | 
					import { OrderType } from '@ghostfolio/api/models/order-type'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import Big from 'big.js'; | 
					 | 
					 | 
					import Big from 'big.js'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					import { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  addDays, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  addMonths, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  addYears, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  format, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  isAfter, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  isBefore, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  parse | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					} from 'date-fns'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					const DATE_FORMAT = 'yyyy-MM-dd'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					export class PortfolioCalculator { | 
					 | 
					 | 
					export class PortfolioCalculator { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  private transactionPoints: TransactionPoint[]; | 
					 | 
					 | 
					  private transactionPoints: TransactionPoint[]; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -11,10 +22,6 @@ export class PortfolioCalculator { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    private currency: Currency | 
					 | 
					 | 
					    private currency: Currency | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  ) {} | 
					 | 
					 | 
					  ) {} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  addOrder(order: PortfolioOrder): void {} | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  deleteOrder(order: PortfolioOrder): void {} | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  computeTransactionPoints(orders: PortfolioOrder[]) { | 
					 | 
					 | 
					  computeTransactionPoints(orders: PortfolioOrder[]) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    orders.sort((a, b) => a.date.localeCompare(b.date)); | 
					 | 
					 | 
					    orders.sort((a, b) => a.date.localeCompare(b.date)); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -121,9 +128,38 @@ export class PortfolioCalculator { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  calculateTimeline( | 
					 | 
					 | 
					  calculateTimeline( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    timelineSpecification: TimelineSpecification[], | 
					 | 
					 | 
					    timelineSpecification: TimelineSpecification[], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    endDate: Date | 
					 | 
					 | 
					    endDate: string | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					  ): TimelinePeriod[] { | 
					 | 
					 | 
					  ): TimelinePeriod[] { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    return null; | 
					 | 
					 | 
					    if (timelineSpecification.length === 0) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      return []; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const startDate = timelineSpecification[0].start; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const start = parse(startDate, DATE_FORMAT, new Date()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const end = parse(endDate, DATE_FORMAT, new Date()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const timelinePeriod: TimelinePeriod[] = []; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    let i = 0; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    for ( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      let currentDate = start; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      !isAfter(currentDate, end); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      currentDate = this.addToDate( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        currentDate, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        timelineSpecification[i].accuracy | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      ) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    ) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      if (this.isNextItemActive(timelineSpecification, currentDate, i)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        i++; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      timelinePeriod.push({ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        date: format(currentDate, DATE_FORMAT), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        grossPerformance: 0, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        investment: 0, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        value: 0 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    return timelinePeriod; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  private getFactor(type: OrderType) { | 
					 | 
					 | 
					  private getFactor(type: OrderType) { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -141,6 +177,31 @@ export class PortfolioCalculator { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    return factor; | 
					 | 
					 | 
					    return factor; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  private addToDate(date: Date, accurany: Accuracy): Date { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    switch (accurany) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      case 'day': | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return addDays(date, 1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      case 'month': | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return addMonths(date, 1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      case 'year': | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return addYears(date, 1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  private isNextItemActive( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    timelineSpecification: TimelineSpecification[], | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    currentDate: Date, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    i: number | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  ) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    return ( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      i + 1 < timelineSpecification.length && | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      !isBefore( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        currentDate, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        parse(timelineSpecification[i + 1].start, DATE_FORMAT, new Date()) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      ) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					interface TransactionPoint { | 
					 | 
					 | 
					interface TransactionPoint { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -169,13 +230,13 @@ interface TimelinePosition { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					type Accuracy = 'year' | 'month' | 'day'; | 
					 | 
					 | 
					type Accuracy = 'year' | 'month' | 'day'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					interface TimelineSpecification { | 
					 | 
					 | 
					export interface TimelineSpecification { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					  start: Date; | 
					 | 
					 | 
					  start: string; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					  accuracy: Accuracy; | 
					 | 
					 | 
					  accuracy: Accuracy; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					interface TimelinePeriod { | 
					 | 
					 | 
					export interface TimelinePeriod { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					  date: Date; | 
					 | 
					 | 
					  date: string; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					  grossPerformance: number; | 
					 | 
					 | 
					  grossPerformance: number; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  investment: number; | 
					 | 
					 | 
					  investment: number; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  value: number; | 
					 | 
					 | 
					  value: number; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					
  |