| 
						
						
						
					 | 
					@ -1,8 +1,7 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto'; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; | 
					 | 
					 | 
					import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { | 
					 | 
					 | 
					import { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  activityDummyData, | 
					 | 
					 | 
					  activityDummyData, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  loadActivityExportFile, | 
					 | 
					 | 
					  loadExportFile, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					  symbolProfileDummyData, | 
					 | 
					 | 
					  symbolProfileDummyData, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  userDummyData | 
					 | 
					 | 
					  userDummyData | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; | 
					 | 
					 | 
					} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -16,9 +15,9 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; | 
					 | 
					 | 
					import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; | 
					 | 
					 | 
					import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { parseDate } from '@ghostfolio/common/helper'; | 
					 | 
					 | 
					import { parseDate } from '@ghostfolio/common/helper'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					import { Export } from '@ghostfolio/common/interfaces'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; | 
					 | 
					 | 
					import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { Tag } from '@prisma/client'; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { Big } from 'big.js'; | 
					 | 
					 | 
					import { Big } from 'big.js'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { join } from 'node:path'; | 
					 | 
					 | 
					import { join } from 'node:path'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -53,7 +52,7 @@ jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					}); | 
					 | 
					 | 
					}); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					describe('PortfolioCalculator', () => { | 
					 | 
					 | 
					describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  let activityDtos: CreateOrderDto[]; | 
					 | 
					 | 
					  let exportResponse: Export; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  let configurationService: ConfigurationService; | 
					 | 
					 | 
					  let configurationService: ConfigurationService; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  let currentRateService: CurrentRateService; | 
					 | 
					 | 
					  let currentRateService: CurrentRateService; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -63,7 +62,7 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  let redisCacheService: RedisCacheService; | 
					 | 
					 | 
					  let redisCacheService: RedisCacheService; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  beforeAll(() => { | 
					 | 
					 | 
					  beforeAll(() => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    activityDtos = loadActivityExportFile( | 
					 | 
					 | 
					    exportResponse = loadExportFile( | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      join( | 
					 | 
					 | 
					      join( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        __dirname, | 
					 | 
					 | 
					        __dirname, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        '../../../../../../../test/import/ok/novn-buy-and-sell-partially.json' | 
					 | 
					 | 
					        '../../../../../../../test/import/ok/novn-buy-and-sell-partially.json' | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -100,28 +99,27 @@ describe('PortfolioCalculator', () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    it.only('with NOVN.SW buy and sell partially', async () => { | 
					 | 
					 | 
					    it.only('with NOVN.SW buy and sell partially', async () => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      jest.useFakeTimers().setSystemTime(parseDate('2022-04-11').getTime()); | 
					 | 
					 | 
					      jest.useFakeTimers().setSystemTime(parseDate('2022-04-11').getTime()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      const activities: Activity[] = activityDtos.map((activity) => ({ | 
					 | 
					 | 
					      const activities: Activity[] = exportResponse.activities.map( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        ...activityDummyData, | 
					 | 
					 | 
					        (activity) => ({ | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        ...activity, | 
					 | 
					 | 
					          ...activityDummyData, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        date: parseDate(activity.date), | 
					 | 
					 | 
					          ...activity, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        feeInAssetProfileCurrency: activity.fee, | 
					 | 
					 | 
					          date: parseDate(activity.date), | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        SymbolProfile: { | 
					 | 
					 | 
					          feeInAssetProfileCurrency: activity.fee, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					          ...symbolProfileDummyData, | 
					 | 
					 | 
					          SymbolProfile: { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					          currency: activity.currency, | 
					 | 
					 | 
					            ...symbolProfileDummyData, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					          dataSource: activity.dataSource, | 
					 | 
					 | 
					            currency: activity.currency, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					          name: 'Novartis AG', | 
					 | 
					 | 
					            dataSource: activity.dataSource, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					          symbol: activity.symbol | 
					 | 
					 | 
					            name: 'Novartis AG', | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        }, | 
					 | 
					 | 
					            symbol: activity.symbol | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        tags: activity.tags?.map((id) => { | 
					 | 
					 | 
					          }, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					          return { id } as Tag; | 
					 | 
					 | 
					          unitPriceInAssetProfileCurrency: activity.unitPrice | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        }), | 
					 | 
					 | 
					        }) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        unitPriceInAssetProfileCurrency: activity.unitPrice | 
					 | 
					 | 
					      ); | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					      })); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      const portfolioCalculator = portfolioCalculatorFactory.createCalculator({ | 
					 | 
					 | 
					      const portfolioCalculator = portfolioCalculatorFactory.createCalculator({ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        activities, | 
					 | 
					 | 
					        activities, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        calculationType: PerformanceCalculationType.ROAI, | 
					 | 
					 | 
					        calculationType: PerformanceCalculationType.ROAI, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        currency: 'CHF', | 
					 | 
					 | 
					        currency: exportResponse.user.settings.currency, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        userId: userDummyData.id | 
					 | 
					 | 
					        userId: userDummyData.id | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      }); | 
					 | 
					 | 
					      }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					
  |