|  | @ -22,7 +22,7 @@ import { | 
			
		
	
		
		
			
				
					|  |  | import { cloneDeep, first, last, sortBy } from 'lodash'; |  |  | import { cloneDeep, first, last, sortBy } from 'lodash'; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | export class TWRPortfolioCalculator extends PortfolioCalculator { |  |  | export class TWRPortfolioCalculator extends PortfolioCalculator { | 
			
		
	
		
		
			
				
					
					|  |  |   private chartDatesDescending: string[]; |  |  |   private chartDates: string[]; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |   protected calculateOverallPerformance( |  |  |   protected calculateOverallPerformance( | 
			
		
	
		
		
			
				
					|  |  |     positions: TimelinePosition[] |  |  |     positions: TimelinePosition[] | 
			
		
	
	
		
		
			
				
					|  | @ -228,11 +228,11 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     const dateOfFirstTransaction = new Date(first(orders).date); |  |  |     const dateOfFirstTransaction = new Date(first(orders).date); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     const unitPriceAtStartDate = |  |  |     const endDateString = format(end, DATE_FORMAT); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |       marketSymbolMap[format(start, DATE_FORMAT)]?.[symbol]; |  |  |     const startDateString = format(start, DATE_FORMAT); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     const unitPriceAtEndDate = |  |  |     const unitPriceAtStartDate = marketSymbolMap[startDateString]?.[symbol]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |       marketSymbolMap[format(end, DATE_FORMAT)]?.[symbol]; |  |  |     const unitPriceAtEndDate = marketSymbolMap[endDateString]?.[symbol]; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     if ( |  |  |     if ( | 
			
		
	
		
		
			
				
					|  |  |       !unitPriceAtEndDate || |  |  |       !unitPriceAtEndDate || | 
			
		
	
	
		
		
			
				
					|  | @ -278,7 +278,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     // Add a synthetic order at the start and the end date
 |  |  |     // Add a synthetic order at the start and the end date
 | 
			
		
	
		
		
			
				
					|  |  |     orders.push({ |  |  |     orders.push({ | 
			
		
	
		
		
			
				
					
					|  |  |       date: format(start, DATE_FORMAT), |  |  |       date: startDateString, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |       fee: new Big(0), |  |  |       fee: new Big(0), | 
			
		
	
		
		
			
				
					|  |  |       feeInBaseCurrency: new Big(0), |  |  |       feeInBaseCurrency: new Big(0), | 
			
		
	
		
		
			
				
					|  |  |       itemType: 'start', |  |  |       itemType: 'start', | 
			
		
	
	
		
		
			
				
					|  | @ -292,7 +292,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { | 
			
		
	
		
		
			
				
					|  |  |     }); |  |  |     }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     orders.push({ |  |  |     orders.push({ | 
			
		
	
		
		
			
				
					
					|  |  |       date: format(end, DATE_FORMAT), |  |  |       date: endDateString, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |       fee: new Big(0), |  |  |       fee: new Big(0), | 
			
		
	
		
		
			
				
					|  |  |       feeInBaseCurrency: new Big(0), |  |  |       feeInBaseCurrency: new Big(0), | 
			
		
	
		
		
			
				
					|  |  |       itemType: 'end', |  |  |       itemType: 'end', | 
			
		
	
	
		
		
			
				
					|  | @ -305,7 +305,6 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { | 
			
		
	
		
		
			
				
					|  |  |       unitPrice: unitPriceAtEndDate |  |  |       unitPrice: unitPriceAtEndDate | 
			
		
	
		
		
			
				
					|  |  |     }); |  |  |     }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     let day = start; |  |  |  | 
			
		
	
		
		
			
				
					|  |  |     let lastUnitPrice: Big; |  |  |     let lastUnitPrice: Big; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     const ordersByDate: { [date: string]: PortfolioOrderItem[] } = {}; |  |  |     const ordersByDate: { [date: string]: PortfolioOrderItem[] } = {}; | 
			
		
	
	
		
		
			
				
					|  | @ -315,15 +314,23 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { | 
			
		
	
		
		
			
				
					|  |  |       ordersByDate[order.date].push(order); |  |  |       ordersByDate[order.date].push(order); | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     while (isBefore(day, end)) { |  |  |     if (!this.chartDates) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |       const dateString = format(day, DATE_FORMAT); |  |  |       this.chartDates = Object.keys(chartDateMap).sort(); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     for (const dateString of this.chartDates) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       if (dateString < startDateString) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         continue; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       } else if (dateString > endDateString) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         break; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |       if (ordersByDate[dateString]?.length > 0) { |  |  |       if (ordersByDate[dateString]?.length > 0) { | 
			
		
	
		
		
			
				
					|  |  |         for (let order of ordersByDate[dateString]) { |  |  |         for (let order of ordersByDate[dateString]) { | 
			
		
	
		
		
			
				
					|  |  |           order.unitPriceFromMarketData = |  |  |           order.unitPriceFromMarketData = | 
			
		
	
		
		
			
				
					|  |  |             marketSymbolMap[dateString]?.[symbol] ?? lastUnitPrice; |  |  |             marketSymbolMap[dateString]?.[symbol] ?? lastUnitPrice; | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |       } else if (chartDateMap[dateString]) { |  |  |       } else { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |         orders.push({ |  |  |         orders.push({ | 
			
		
	
		
		
			
				
					|  |  |           date: dateString, |  |  |           date: dateString, | 
			
		
	
		
		
			
				
					|  |  |           fee: new Big(0), |  |  |           fee: new Big(0), | 
			
		
	
	
		
		
			
				
					|  | @ -343,8 +350,6 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { | 
			
		
	
		
		
			
				
					|  |  |       const lastOrder = last(orders); |  |  |       const lastOrder = last(orders); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |       lastUnitPrice = lastOrder.unitPriceFromMarketData ?? lastOrder.unitPrice; |  |  |       lastUnitPrice = lastOrder.unitPriceFromMarketData ?? lastOrder.unitPrice; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  |  | 
			
		
	
		
		
			
				
					|  |  |       day = addDays(day, 1); |  |  |  | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     // Sort orders so that the start and end placeholder order are at the correct
 |  |  |     // Sort orders so that the start and end placeholder order are at the correct
 | 
			
		
	
	
		
		
			
				
					|  | @ -821,14 +826,14 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { | 
			
		
	
		
		
			
				
					|  |  |         startDate = start; |  |  |         startDate = start; | 
			
		
	
		
		
			
				
					|  |  |       } |  |  |       } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |       const endDateString = format(endDate, DATE_FORMAT); |  |  |       const rangeEndDateString = format(endDate, DATE_FORMAT); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |       const startDateString = format(startDate, DATE_FORMAT); |  |  |       const rangeStartDateString = format(startDate, DATE_FORMAT); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |       const currentValuesAtDateRangeStartWithCurrencyEffect = |  |  |       const currentValuesAtDateRangeStartWithCurrencyEffect = | 
			
		
	
		
		
			
				
					
					|  |  |         currentValuesWithCurrencyEffect[startDateString] ?? new Big(0); |  |  |         currentValuesWithCurrencyEffect[rangeStartDateString] ?? new Big(0); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |       const investmentValuesAccumulatedAtStartDateWithCurrencyEffect = |  |  |       const investmentValuesAccumulatedAtStartDateWithCurrencyEffect = | 
			
		
	
		
		
			
				
					
					|  |  |         investmentValuesAccumulatedWithCurrencyEffect[startDateString] ?? |  |  |         investmentValuesAccumulatedWithCurrencyEffect[rangeStartDateString] ?? | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |         new Big(0); |  |  |         new Big(0); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |       const grossPerformanceAtDateRangeStartWithCurrencyEffect = |  |  |       const grossPerformanceAtDateRangeStartWithCurrencyEffect = | 
			
		
	
	
		
		
			
				
					|  | @ -839,14 +844,12 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { | 
			
		
	
		
		
			
				
					|  |  |       let average = new Big(0); |  |  |       let average = new Big(0); | 
			
		
	
		
		
			
				
					|  |  |       let dayCount = 0; |  |  |       let dayCount = 0; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |       if (!this.chartDatesDescending) { |  |  |       for (let i = this.chartDates.length - 1; i >= 0; i -= 1) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |         this.chartDatesDescending = Object.keys(chartDateMap).sort().reverse(); |  |  |         const date = this.chartDates[i]; | 
			
				
				
			
		
	
		
		
			
				
					|  |  |       } |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |       for (const date of this.chartDatesDescending) { |  |  |         if (date > rangeEndDateString) { | 
			
				
				
			
		
	
		
		
			
				
					|  |  |         if (date > endDateString) { |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					|  |  |           continue; |  |  |           continue; | 
			
		
	
		
		
			
				
					
					|  |  |         } else if (date < startDateString) { |  |  |         } else if (date < rangeStartDateString) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |           break; |  |  |           break; | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -869,13 +872,13 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { | 
			
		
	
		
		
			
				
					|  |  |       } |  |  |       } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |       netPerformanceWithCurrencyEffectMap[dateRange] = |  |  |       netPerformanceWithCurrencyEffectMap[dateRange] = | 
			
		
	
		
		
			
				
					
					|  |  |         netPerformanceValuesWithCurrencyEffect[endDateString]?.minus( |  |  |         netPerformanceValuesWithCurrencyEffect[rangeEndDateString]?.minus( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |           // If the date range is 'max', take 0 as a start value. Otherwise,
 |  |  |           // If the date range is 'max', take 0 as a start value. Otherwise,
 | 
			
		
	
		
		
			
				
					|  |  |           // the value of the end of the day of the start date is taken which
 |  |  |           // the value of the end of the day of the start date is taken which
 | 
			
		
	
		
		
			
				
					|  |  |           // differs from the buying price.
 |  |  |           // differs from the buying price.
 | 
			
		
	
		
		
			
				
					|  |  |           dateRange === 'max' |  |  |           dateRange === 'max' | 
			
		
	
		
		
			
				
					|  |  |             ? new Big(0) |  |  |             ? new Big(0) | 
			
		
	
		
		
			
				
					
					|  |  |             : (netPerformanceValuesWithCurrencyEffect[startDateString] ?? |  |  |             : (netPerformanceValuesWithCurrencyEffect[rangeStartDateString] ?? | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 new Big(0)) |  |  |                 new Big(0)) | 
			
		
	
		
		
			
				
					|  |  |         ) ?? new Big(0); |  |  |         ) ?? new Big(0); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | 
 |