| 
						
						
						
					 | 
				
				 | 
				
					@ -1,4 +1,3 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { TimelineInfoInterface } from '@ghostfolio/api/app/portfolio/interfaces/timeline-info.interface'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -20,32 +19,19 @@ import { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  differenceInDays, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  endOfDay, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  format, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  isAfter, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  isBefore, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  isSameDay, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  isSameMonth, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  isSameYear, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  max, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  min, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  set, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  subDays | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} from 'date-fns'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  cloneDeep, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  first, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  flatten, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  isNumber, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  last, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  sortBy, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uniq | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} from 'lodash'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { cloneDeep, first, isNumber, last, sortBy, uniq } from 'lodash'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { CurrentRateService } from './current-rate.service'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { CurrentPositions } from './interfaces/current-positions.interface'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { GetValueObject } from './interfaces/get-value-object.interface'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { PortfolioOrderItem } from './interfaces/portfolio-calculator.interface'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { PortfolioOrder } from './interfaces/portfolio-order.interface'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { TimelinePeriod } from './interfaces/timeline-period.interface'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  Accuracy, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  TimelineSpecification | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -776,107 +762,6 @@ export class PortfolioCalculator { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  public async calculateTimeline( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    timelineSpecification: TimelineSpecification[], | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    endDate: string | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  ): Promise<TimelineInfoInterface> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (timelineSpecification.length === 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      return { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        maxNetPerformance: new Big(0), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        minNetPerformance: new Big(0), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        timelinePeriods: [] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const startDate = timelineSpecification[0].start; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const start = parseDate(startDate); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const end = parseDate(endDate); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const timelinePeriodPromises: Promise<TimelineInfoInterface>[] = []; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let i = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let j = -1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let currentDate = start; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      !isAfter(currentDate, end); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      currentDate = this.addToDate( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        currentDate, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        timelineSpecification[i].accuracy | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      ) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (this.isNextItemActive(timelineSpecification, currentDate, i)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        i++; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      while ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        j + 1 < this.transactionPoints.length && | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        !isAfter(parseDate(this.transactionPoints[j + 1].date), currentDate) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      ) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        j++; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let periodEndDate = currentDate; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (timelineSpecification[i].accuracy === 'day') { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        let nextEndDate = end; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (j + 1 < this.transactionPoints.length) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          nextEndDate = parseDate(this.transactionPoints[j + 1].date); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        periodEndDate = min([ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          addMonths(currentDate, 3), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          max([currentDate, nextEndDate]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const timePeriodForDates = this.getTimePeriodForDate( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        j, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        currentDate, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        endOfDay(periodEndDate) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      currentDate = periodEndDate; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (timePeriodForDates != null) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        timelinePeriodPromises.push(timePeriodForDates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let minNetPerformance = new Big(0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let maxNetPerformance = new Big(0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const timelineInfoInterfaces: TimelineInfoInterface[] = await Promise.all( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      timelinePeriodPromises | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    try { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      minNetPerformance = timelineInfoInterfaces | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .map((timelineInfo) => timelineInfo.minNetPerformance) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .filter((performance) => performance !== null) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .reduce((minPerformance, current) => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if (minPerformance.lt(current)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return minPerformance; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return current; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      maxNetPerformance = timelineInfoInterfaces | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .map((timelineInfo) => timelineInfo.maxNetPerformance) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .filter((performance) => performance !== null) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .reduce((maxPerformance, current) => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if (maxPerformance.gt(current)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return maxPerformance; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return current; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } catch {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const timelinePeriods = timelineInfoInterfaces.map( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      (timelineInfo) => timelineInfo.timelinePeriods | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      maxNetPerformance, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      minNetPerformance, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      timelinePeriods: flatten(timelinePeriods) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  private calculateOverallPerformance(positions: TimelinePosition[]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let currentValue = new Big(0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let grossPerformance = new Big(0); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -983,123 +868,6 @@ export class PortfolioCalculator { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  private async getTimePeriodForDate( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    j: number, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    startDate: Date, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    endDate: Date | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  ): Promise<TimelineInfoInterface> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let investment: Big = new Big(0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let fees: Big = new Big(0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const marketSymbolMap: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      [date: string]: { [symbol: string]: Big }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } = {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (j >= 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const currencies: { [name: string]: string } = {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const dataGatheringItems: IDataGatheringItem[] = []; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      for (const item of this.transactionPoints[j].items) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        currencies[item.symbol] = item.currency; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        dataGatheringItems.push({ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          dataSource: item.dataSource, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          symbol: item.symbol | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        investment = investment.plus(item.investment); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        fees = fees.plus(item.fee); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let marketSymbols: GetValueObject[] = []; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (dataGatheringItems.length > 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        try { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          const { values } = await this.currentRateService.getValues({ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            dataGatheringItems, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            dateQuery: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              gte: startDate, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              lt: endOfDay(endDate) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          marketSymbols = values; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } catch (error) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          Logger.error( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            `Failed to fetch info for date ${startDate} with exception`, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            error, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            'PortfolioCalculator' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          return null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      for (const marketSymbol of marketSymbols) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const date = format(marketSymbol.date, DATE_FORMAT); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (!marketSymbolMap[date]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          marketSymbolMap[date] = {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (marketSymbol.marketPrice) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          marketSymbolMap[date][marketSymbol.symbol] = new Big( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            marketSymbol.marketPrice | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const results: TimelinePeriod[] = []; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let maxNetPerformance: Big = null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let minNetPerformance: Big = null; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let currentDate = startDate; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      isBefore(currentDate, endDate); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      currentDate = addDays(currentDate, 1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let value = new Big(0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const currentDateAsString = format(currentDate, DATE_FORMAT); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let invalid = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (j >= 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (const item of this.transactionPoints[j].items) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            !marketSymbolMap[currentDateAsString]?.hasOwnProperty(item.symbol) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          ) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            invalid = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          value = value.plus( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            item.quantity.mul(marketSymbolMap[currentDateAsString][item.symbol]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (!invalid) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const grossPerformance = value.minus(investment); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const netPerformance = grossPerformance.minus(fees); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          minNetPerformance === null || | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          minNetPerformance.gt(netPerformance) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          minNetPerformance = netPerformance; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          maxNetPerformance === null || | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          maxNetPerformance.lt(netPerformance) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          maxNetPerformance = netPerformance; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const result = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          grossPerformance, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          investment, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          netPerformance, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          value, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          date: currentDateAsString | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        results.push(result); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      maxNetPerformance, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      minNetPerformance, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      timelinePeriods: results | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  private getFactor(type: TypeOfOrder) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let factor: number; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |