| 
						
						
							
								
							
						
						
					 | 
					@ -7,7 +7,7 @@ import { TimelineSpecification } from '@ghostfolio/api/app/core/interfaces/timel | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { TransactionPoint } from '@ghostfolio/api/app/core/interfaces/transaction-point.interface'; | 
					 | 
					 | 
					import { TransactionPoint } from '@ghostfolio/api/app/core/interfaces/transaction-point.interface'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { PortfolioCalculator } from '@ghostfolio/api/app/core/portfolio-calculator'; | 
					 | 
					 | 
					import { PortfolioCalculator } from '@ghostfolio/api/app/core/portfolio-calculator'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { OrderType } from '@ghostfolio/api/models/order-type'; | 
					 | 
					 | 
					import { OrderType } from '@ghostfolio/api/models/order-type'; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; | 
					 | 
					 | 
					import { parseDate, resetHours } from '@ghostfolio/common/helper'; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					import { Currency } from '@prisma/client'; | 
					 | 
					 | 
					import { Currency } from '@prisma/client'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import Big from 'big.js'; | 
					 | 
					 | 
					import Big from 'big.js'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { | 
					 | 
					 | 
					import { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -15,8 +15,7 @@ import { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  differenceInCalendarDays, | 
					 | 
					 | 
					  differenceInCalendarDays, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  endOfDay, | 
					 | 
					 | 
					  endOfDay, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  isBefore, | 
					 | 
					 | 
					  isBefore, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  isSameDay, | 
					 | 
					 | 
					  isSameDay | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					  parse | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					} from 'date-fns'; | 
					 | 
					 | 
					} from 'date-fns'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					function mockGetValue(symbol: string, date: Date) { | 
					 | 
					 | 
					function mockGetValue(symbol: string, date: Date) { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -25,7 +24,7 @@ function mockGetValue(symbol: string, date: Date) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    if (isSameDay(today, date)) { | 
					 | 
					 | 
					    if (isSameDay(today, date)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      return { marketPrice: 213.32 }; | 
					 | 
					 | 
					      return { marketPrice: 213.32 }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } else { | 
					 | 
					 | 
					    } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      const startDate = parse('2019-02-01', DATE_FORMAT, new Date()); | 
					 | 
					 | 
					      const startDate = parseDate('2019-02-01'); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      const daysInBetween = differenceInCalendarDays(date, startDate); | 
					 | 
					 | 
					      const daysInBetween = differenceInCalendarDays(date, startDate); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      const marketPrice = new Big('144.38').plus( | 
					 | 
					 | 
					      const marketPrice = new Big('144.38').plus( | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -44,11 +43,23 @@ function mockGetValue(symbol: string, date: Date) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      return { marketPrice: 1.097884981 }; // 1192328 / 1086022.689344541
 | 
					 | 
					 | 
					      return { marketPrice: 1.097884981 }; // 1192328 / 1086022.689344541
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    return { marketPrice: 0 }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } else if (symbol === 'SPA') { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    if (isSameDay(parseDate('2013-12-31'), date)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      return { marketPrice: 1.025 }; // 205 / 200
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    return { marketPrice: 0 }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } else if (symbol === 'SPB') { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    if (isSameDay(parseDate('2013-12-31'), date)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      return { marketPrice: 1.04 }; // 312 / 300
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    return { marketPrice: 0 }; | 
					 | 
					 | 
					    return { marketPrice: 0 }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } else if (symbol === 'TSLA') { | 
					 | 
					 | 
					  } else if (symbol === 'TSLA') { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    if (isSameDay(parse('2021-07-26', DATE_FORMAT, new Date()), date)) { | 
					 | 
					 | 
					    if (isSameDay(parseDate('2021-07-26'), date)) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      return { marketPrice: 657.62 }; | 
					 | 
					 | 
					      return { marketPrice: 657.62 }; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    } else if (isSameDay(parse('2021-01-02', DATE_FORMAT, new Date()), date)) { | 
					 | 
					 | 
					    } else if (isSameDay(parseDate('2021-01-02'), date)) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      return { marketPrice: 666.66 }; | 
					 | 
					 | 
					      return { marketPrice: 666.66 }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -617,7 +628,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        .spyOn(Date, 'now') | 
					 | 
					 | 
					        .spyOn(Date, 'now') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        .mockImplementation(() => new Date(Date.UTC(2021, 6, 26)).getTime()); // 2021-07-26
 | 
					 | 
					 | 
					        .mockImplementation(() => new Date(Date.UTC(2021, 6, 26)).getTime()); // 2021-07-26
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        parse('2020-01-21', DATE_FORMAT, new Date()) | 
					 | 
					 | 
					        parseDate('2020-01-21') | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      ); | 
					 | 
					 | 
					      ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      spy.mockRestore(); | 
					 | 
					 | 
					      spy.mockRestore(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -625,7 +636,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        hasErrors: false, | 
					 | 
					 | 
					        hasErrors: false, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        currentValue: new Big('657.62'), | 
					 | 
					 | 
					        currentValue: new Big('657.62'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        grossPerformance: new Big('-61.84'), | 
					 | 
					 | 
					        grossPerformance: new Big('-61.84'), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        grossPerformancePercentage: new Big('-0.08456342256692519389'), | 
					 | 
					 | 
					        grossPerformancePercentage: new Big('-0.08595335390431712673'), | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        positions: [ | 
					 | 
					 | 
					        positions: [ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          { | 
					 | 
					 | 
					          { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            averagePrice: new Big('719.46'), | 
					 | 
					 | 
					            averagePrice: new Big('719.46'), | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -655,7 +666,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        .spyOn(Date, 'now') | 
					 | 
					 | 
					        .spyOn(Date, 'now') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        .mockImplementation(() => new Date(Date.UTC(2021, 6, 26)).getTime()); // 2021-07-26
 | 
					 | 
					 | 
					        .mockImplementation(() => new Date(Date.UTC(2021, 6, 26)).getTime()); // 2021-07-26
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        parse('2021-01-01', DATE_FORMAT, new Date()) | 
					 | 
					 | 
					        parseDate('2021-01-01') | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      ); | 
					 | 
					 | 
					      ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      spy.mockRestore(); | 
					 | 
					 | 
					      spy.mockRestore(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -663,7 +674,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        hasErrors: false, | 
					 | 
					 | 
					        hasErrors: false, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        currentValue: new Big('657.62'), | 
					 | 
					 | 
					        currentValue: new Big('657.62'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        grossPerformance: new Big('-61.84'), | 
					 | 
					 | 
					        grossPerformance: new Big('-61.84'), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        grossPerformancePercentage: new Big('-0.08456342256692519389'), | 
					 | 
					 | 
					        grossPerformancePercentage: new Big('-0.08595335390431712673'), | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        positions: [ | 
					 | 
					 | 
					        positions: [ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          { | 
					 | 
					 | 
					          { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            averagePrice: new Big('719.46'), | 
					 | 
					 | 
					            averagePrice: new Big('719.46'), | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -693,7 +704,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        .spyOn(Date, 'now') | 
					 | 
					 | 
					        .spyOn(Date, 'now') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        .mockImplementation(() => new Date(Date.UTC(2021, 6, 26)).getTime()); // 2021-07-26
 | 
					 | 
					 | 
					        .mockImplementation(() => new Date(Date.UTC(2021, 6, 26)).getTime()); // 2021-07-26
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        parse('2021-01-02', DATE_FORMAT, new Date()) | 
					 | 
					 | 
					        parseDate('2021-01-02') | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      ); | 
					 | 
					 | 
					      ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      spy.mockRestore(); | 
					 | 
					 | 
					      spy.mockRestore(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -701,7 +712,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        hasErrors: false, | 
					 | 
					 | 
					        hasErrors: false, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        currentValue: new Big('657.62'), | 
					 | 
					 | 
					        currentValue: new Big('657.62'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        grossPerformance: new Big('-9.04'), | 
					 | 
					 | 
					        grossPerformance: new Big('-9.04'), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        grossPerformancePercentage: new Big('-0.01206012060120601206'), | 
					 | 
					 | 
					        grossPerformancePercentage: new Big('-0.01356013560135601356'), | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        positions: [ | 
					 | 
					 | 
					        positions: [ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          { | 
					 | 
					 | 
					          { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            averagePrice: new Big('719.46'), | 
					 | 
					 | 
					            averagePrice: new Big('719.46'), | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -731,7 +742,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        .spyOn(Date, 'now') | 
					 | 
					 | 
					        .spyOn(Date, 'now') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        .mockImplementation(() => new Date(Date.UTC(2020, 9, 24)).getTime()); // 2020-10-24
 | 
					 | 
					 | 
					        .mockImplementation(() => new Date(Date.UTC(2020, 9, 24)).getTime()); // 2020-10-24
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        parse('2019-01-01', DATE_FORMAT, new Date()) | 
					 | 
					 | 
					        parseDate('2019-01-01') | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      ); | 
					 | 
					 | 
					      ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      spy.mockRestore(); | 
					 | 
					 | 
					      spy.mockRestore(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -739,7 +750,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        hasErrors: false, | 
					 | 
					 | 
					        hasErrors: false, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        currentValue: new Big('4871.5'), | 
					 | 
					 | 
					        currentValue: new Big('4871.5'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        grossPerformance: new Big('240.4'), | 
					 | 
					 | 
					        grossPerformance: new Big('240.4'), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        grossPerformancePercentage: new Big('0.08908669575467971768'), | 
					 | 
					 | 
					        grossPerformancePercentage: new Big('0.08839407904876477102'), | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        positions: [ | 
					 | 
					 | 
					        positions: [ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          { | 
					 | 
					 | 
					          { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            averagePrice: new Big('178.438'), | 
					 | 
					 | 
					            averagePrice: new Big('178.438'), | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -811,7 +822,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      // gross performance percentage: 1.100526008 * 1.158880728 = 1.275378381 => 27.5378381 %
 | 
					 | 
					 | 
					      // gross performance percentage: 1.100526008 * 1.158880728 = 1.275378381 => 27.5378381 %
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        parse('2020-01-01', DATE_FORMAT, new Date()) | 
					 | 
					 | 
					        parseDate('2020-01-01') | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      ); | 
					 | 
					 | 
					      ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      spy.mockRestore(); | 
					 | 
					 | 
					      spy.mockRestore(); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -819,7 +830,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        hasErrors: false, | 
					 | 
					 | 
					        hasErrors: false, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        currentValue: new Big('3897.2'), | 
					 | 
					 | 
					        currentValue: new Big('3897.2'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        grossPerformance: new Big('303.2'), | 
					 | 
					 | 
					        grossPerformance: new Big('303.2'), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        grossPerformancePercentage: new Big('0.2759628350186678759'), | 
					 | 
					 | 
					        grossPerformancePercentage: new Big('0.27537838148272398344'), | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        positions: [ | 
					 | 
					 | 
					        positions: [ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          { | 
					 | 
					 | 
					          { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            averagePrice: new Big('146.185'), | 
					 | 
					 | 
					            averagePrice: new Big('146.185'), | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -892,7 +903,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        hasErrors: false, | 
					 | 
					 | 
					        hasErrors: false, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        currentValue: new Big('1192327.999656600298238721'), | 
					 | 
					 | 
					        currentValue: new Big('1192327.999656600298238721'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        grossPerformance: new Big('92327.999656600898394721'), | 
					 | 
					 | 
					        grossPerformance: new Big('92327.999656600898394721'), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        grossPerformancePercentage: new Big('0.09788598099999947809'), | 
					 | 
					 | 
					        grossPerformancePercentage: new Big('0.09788498099999947809'), | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        positions: [ | 
					 | 
					 | 
					        positions: [ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          { | 
					 | 
					 | 
					          { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            averagePrice: new Big('1.01287018290924923237'), // 1'100'000 / 1'086'022.689344542
 | 
					 | 
					 | 
					            averagePrice: new Big('1.01287018290924923237'), // 1'100'000 / 1'086'022.689344542
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -910,6 +921,108 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        ] | 
					 | 
					 | 
					        ] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      }); | 
					 | 
					 | 
					      }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }); | 
					 | 
					 | 
					    }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    /** | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					     * Source: https://www.chsoft.ch/en/assets/Dateien/files/PDF/ePoca/en/Practical%20Performance%20Calculation.pdf
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					     */ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    it('with example from chsoft.ch: Performance of a Combination of Investments', async () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      const portfolioCalculator = new PortfolioCalculator( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        currentRateService, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        Currency.CHF | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      portfolioCalculator.setTransactionPoints([ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          date: '2012-12-31', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          items: [ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              name: 'Sub Portfolio A', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              quantity: new Big('200'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              symbol: 'SPA', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              investment: new Big('200'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              currency: Currency.CHF, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              firstBuyDate: '2012-12-31', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              transactionCount: 1 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            }, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              name: 'Sub Portfolio B', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              quantity: new Big('300'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              symbol: 'SPB', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              investment: new Big('300'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              currency: Currency.CHF, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              firstBuyDate: '2012-12-31', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              transactionCount: 1 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          ] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        }, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          date: '2013-12-31', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          items: [ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              name: 'Sub Portfolio A', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              quantity: new Big('200'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              symbol: 'SPA', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              investment: new Big('200'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              currency: Currency.CHF, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              firstBuyDate: '2012-12-31', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              transactionCount: 1 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            }, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              name: 'Sub Portfolio B', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              quantity: new Big('300'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              symbol: 'SPB', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              investment: new Big('300'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              currency: Currency.CHF, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              firstBuyDate: '2012-12-31', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              transactionCount: 1 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          ] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      ]); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      const spy = jest | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        .spyOn(Date, 'now') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        .mockImplementation(() => new Date(Date.UTC(2013, 11, 31)).getTime()); // 2013-12-31
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      const currentPositions = await portfolioCalculator.getCurrentPositions( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        parseDate('2012-12-31') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      spy.mockRestore(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      expect(currentPositions).toEqual({ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        currentValue: new Big('517'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        grossPerformance: new Big('17'), // 517 - 500
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        grossPerformancePercentage: new Big('0.034'), // ((200 * 0.025) + (300 * 0.04)) / (200 + 300) = 3.4%
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        hasErrors: false, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        positions: [ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            averagePrice: new Big('1'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            firstBuyDate: '2012-12-31', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            quantity: new Big('200'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            symbol: 'SPA', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            investment: new Big('200'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            marketPrice: 1.025, // 205 / 200
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            transactionCount: 1, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            grossPerformance: new Big('5'), // 205 - 200
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            grossPerformancePercentage: new Big('0.025'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            name: 'Sub Portfolio A', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            currency: 'CHF' | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          }, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            averagePrice: new Big('1'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            firstBuyDate: '2012-12-31', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            quantity: new Big('300'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            symbol: 'SPB', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            investment: new Big('300'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            marketPrice: 1.04, // 312 / 300
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            transactionCount: 1, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            grossPerformance: new Big('12'), // 312 - 300
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            grossPerformancePercentage: new Big('0.04'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            name: 'Sub Portfolio B', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            currency: 'CHF' | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        ] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  }); | 
					 | 
					 | 
					  }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  describe('calculate timeline', () => { | 
					 | 
					 | 
					  describe('calculate timeline', () => { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					
  |