|
|
@ -1,3 +1,4 @@ |
|
|
|
import { TimelineInfoInterface } from '@ghostfolio/api/app/portfolio/interfaces/timeline-info.interface'; |
|
|
|
import { OrderType } from '@ghostfolio/api/models/order-type'; |
|
|
|
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; |
|
|
|
import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; |
|
|
@ -365,16 +366,20 @@ export class PortfolioCalculator { |
|
|
|
public async calculateTimeline( |
|
|
|
timelineSpecification: TimelineSpecification[], |
|
|
|
endDate: string |
|
|
|
): Promise<TimelinePeriod[]> { |
|
|
|
): Promise<TimelineInfoInterface> { |
|
|
|
if (timelineSpecification.length === 0) { |
|
|
|
return []; |
|
|
|
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<TimelinePeriod[]>[] = []; |
|
|
|
const timelinePeriodPromises: Promise<TimelineInfoInterface>[] = []; |
|
|
|
let i = 0; |
|
|
|
let j = -1; |
|
|
|
for ( |
|
|
@ -417,11 +422,40 @@ export class PortfolioCalculator { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const timelinePeriods: TimelinePeriod[][] = await Promise.all( |
|
|
|
const timelineInfoInterfaces: TimelineInfoInterface[] = await Promise.all( |
|
|
|
timelinePeriodPromises |
|
|
|
); |
|
|
|
const minNetPerformance = timelineInfoInterfaces |
|
|
|
.map((timelineInfo) => timelineInfo.minNetPerformance) |
|
|
|
.filter((performance) => performance !== null) |
|
|
|
.reduce((minPerformance, current) => { |
|
|
|
if (minPerformance.lt(current)) { |
|
|
|
return minPerformance; |
|
|
|
} else { |
|
|
|
return current; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
return flatten(timelinePeriods); |
|
|
|
const maxNetPerformance = timelineInfoInterfaces |
|
|
|
.map((timelineInfo) => timelineInfo.maxNetPerformance) |
|
|
|
.filter((performance) => performance !== null) |
|
|
|
.reduce((maxPerformance, current) => { |
|
|
|
if (maxPerformance.gt(current)) { |
|
|
|
return maxPerformance; |
|
|
|
} else { |
|
|
|
return current; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
const timelinePeriods = timelineInfoInterfaces.map( |
|
|
|
(timelineInfo) => timelineInfo.timelinePeriods |
|
|
|
); |
|
|
|
|
|
|
|
return { |
|
|
|
maxNetPerformance, |
|
|
|
minNetPerformance, |
|
|
|
timelinePeriods: flatten(timelinePeriods) |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
private calculateOverallPerformance( |
|
|
@ -513,7 +547,7 @@ export class PortfolioCalculator { |
|
|
|
j: number, |
|
|
|
startDate: Date, |
|
|
|
endDate: Date |
|
|
|
): Promise<TimelinePeriod[]> { |
|
|
|
): Promise<TimelineInfoInterface> { |
|
|
|
let investment: Big = new Big(0); |
|
|
|
let fees: Big = new Big(0); |
|
|
|
|
|
|
@ -569,6 +603,8 @@ export class PortfolioCalculator { |
|
|
|
} |
|
|
|
|
|
|
|
const results: TimelinePeriod[] = []; |
|
|
|
let maxNetPerformance: Big = null; |
|
|
|
let minNetPerformance: Big = null; |
|
|
|
for ( |
|
|
|
let currentDate = startDate; |
|
|
|
isBefore(currentDate, endDate); |
|
|
@ -592,18 +628,36 @@ export class PortfolioCalculator { |
|
|
|
} |
|
|
|
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, |
|
|
|
netPerformance: grossPerformance.minus(fees) |
|
|
|
date: currentDateAsString |
|
|
|
}; |
|
|
|
results.push(result); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return results; |
|
|
|
return { |
|
|
|
maxNetPerformance, |
|
|
|
minNetPerformance, |
|
|
|
timelinePeriods: results |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
private getFactor(type: OrderType) { |
|
|
|