| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -321,9 +321,44 @@ export class PortfolioService { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    aSymbol: string | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  ): Promise<PortfolioPositionDetail> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const userId = await this.getUserId(aImpersonationId); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const portfolio = await this.createPortfolio(userId); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const position = portfolio.getPositions(new Date())[aSymbol]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const portfolioCalculator = new PortfolioCalculator( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      this.currentRateService, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      this.request.user.Settings.currency | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const { transactionPoints, orders } = await this.getTransactionPoints( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      userId | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (transactionPoints?.length <= 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      return { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        averagePrice: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        currency: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        firstBuyDate: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        grossPerformance: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        grossPerformancePercent: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        historicalData: [], | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        investment: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        marketPrice: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        maxPrice: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        minPrice: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        quantity: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        symbol: aSymbol, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        transactionCount: undefined | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    portfolioCalculator.setTransactionPoints(transactionPoints); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const portfolioStart = parseDate(transactionPoints[0].date); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const currentPositions = await portfolioCalculator.getCurrentPositions( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      portfolioStart | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const position = currentPositions.positions.find( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      (item) => item.symbol === aSymbol | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (position) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -331,11 +366,10 @@ export class PortfolioService { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        currency, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        firstBuyDate, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        investment, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        marketPrice, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        quantity, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        transactionCount | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } = position; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let marketPrice = position.marketPrice; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const orders = portfolio.getOrders(aSymbol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const historicalData = await this.dataProviderService.getHistorical( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        [aSymbol], | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -344,33 +378,29 @@ export class PortfolioService { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        new Date() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (marketPrice === 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        marketPrice = averagePrice; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const historicalDataArray: HistoricalDataItem[] = []; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let currentAveragePrice: number; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let maxPrice = marketPrice; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let minPrice = marketPrice; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (historicalData[aSymbol]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        let j = -1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (const [date, { marketPrice }] of Object.entries( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          historicalData[aSymbol] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        )) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          const currentDate = parse(date, DATE_FORMAT, new Date()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            isSameDay(currentDate, parseISO(orders[0]?.getDate())) || | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            isAfter(currentDate, parseISO(orders[0]?.getDate())) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          while ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            j + 1 < transactionPoints.length && | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            !isAfter(parseDate(transactionPoints[j + 1].date), parseDate(date)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          ) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Get snapshot of first day of next month
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const snapshot = portfolio.get( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              addMonths(setDate(currentDate, 1), 1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            )?.[0]?.positions[aSymbol]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            orders.shift(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (snapshot?.averagePrice) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              currentAveragePrice = snapshot.averagePrice; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            j++; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          let currentAveragePrice = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          const currentSymbol = transactionPoints[j].items.find( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            (item) => item.symbol === aSymbol | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if (currentSymbol) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            currentAveragePrice = currentSymbol.investment | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              .div(currentSymbol.quantity) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              .toNumber(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          historicalDataArray.push({ | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -379,58 +409,40 @@ export class PortfolioService { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            value: marketPrice | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            marketPrice && | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            (marketPrice > maxPrice || maxPrice === undefined) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          ) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            maxPrice = marketPrice; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            marketPrice && | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            (marketPrice < minPrice || minPrice === undefined) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          ) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            minPrice = marketPrice; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          maxPrice = Math.max(marketPrice ?? 0, maxPrice); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          minPrice = Math.min(marketPrice ?? Number.MAX_SAFE_INTEGER, minPrice); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      return { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        averagePrice, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        averagePrice: averagePrice.toNumber(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        currency, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        firstBuyDate, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        investment, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        investment: investment.toNumber(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        marketPrice, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        maxPrice, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        minPrice, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        quantity, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        quantity: quantity.toNumber(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        transactionCount, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        grossPerformance: this.exchangeRateDataService.toCurrency( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          marketPrice - averagePrice, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          currency, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          this.request.user.Settings.currency | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        grossPerformancePercent: roundTo( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          (marketPrice - averagePrice) / averagePrice, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          4 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        grossPerformance: position.grossPerformance.toNumber(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        grossPerformancePercent: position.grossPerformancePercentage.toNumber(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        historicalData: historicalDataArray, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        symbol: aSymbol | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } else if (portfolio.getMinDate()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const currentData = await this.dataProviderService.get([aSymbol]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let historicalData = await this.dataProviderService.getHistorical( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        [aSymbol], | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        'day', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        portfolio.getMinDate(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        portfolioStart, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        new Date() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (isEmpty(historicalData)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        historicalData = await this.dataProviderService.getHistoricalRaw( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          [{ dataSource: DataSource.YAHOO, symbol: aSymbol }], | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          portfolio.getMinDate(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          portfolioStart, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          new Date() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -462,22 +474,6 @@ export class PortfolioService { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        transactionCount: undefined | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      averagePrice: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      currency: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      firstBuyDate: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      grossPerformance: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      grossPerformancePercent: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      historicalData: [], | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      investment: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      marketPrice: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      maxPrice: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      minPrice: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      quantity: undefined, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      symbol: aSymbol, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      transactionCount: undefined | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  public async getPositions( | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |