|
|
@ -223,15 +223,19 @@ export abstract class PortfolioCalculator { |
|
|
): PortfolioSnapshot; |
|
|
): PortfolioSnapshot; |
|
|
|
|
|
|
|
|
protected abstract calculatePerformancePercentages({ |
|
|
protected abstract calculatePerformancePercentages({ |
|
|
accumulatedValuesByDate |
|
|
accumulatedValuesByDate, |
|
|
|
|
|
holdings |
|
|
}: { |
|
|
}: { |
|
|
accumulatedValuesByDate: { [date: string]: AccumulatedValues }; |
|
|
accumulatedValuesByDate: { [date: string]: AccumulatedValues }; |
|
|
|
|
|
holdings: PortfolioSnapshotHolding[]; |
|
|
}): { [date: string]: PerformancePercentages }; |
|
|
}): { [date: string]: PerformancePercentages }; |
|
|
|
|
|
|
|
|
protected abstract calculatePerformancePercentagesForDateRange({ |
|
|
protected abstract calculatePerformancePercentagesForDateRange({ |
|
|
historicalDataItems |
|
|
historicalDataItems, |
|
|
|
|
|
holdings |
|
|
}: { |
|
|
}: { |
|
|
historicalDataItems: HistoricalDataItem[]; |
|
|
historicalDataItems: HistoricalDataItem[]; |
|
|
|
|
|
holdings: PortfolioSnapshotHolding[]; |
|
|
}): { [date: string]: PerformancePercentages }; |
|
|
}): { [date: string]: PerformancePercentages }; |
|
|
|
|
|
|
|
|
@LogPerformance |
|
|
@LogPerformance |
|
|
@ -544,7 +548,8 @@ export abstract class PortfolioCalculator { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const totalDividendValueByDate = this.getTotalDividendValueByDate({ |
|
|
const totalDividendValueWithCurrencyEffectByDate = |
|
|
|
|
|
this.getTotalDividendValueWithCurrencyEffectByDate({ |
|
|
chartDates, |
|
|
chartDates, |
|
|
exchangeRatesByCurrency, |
|
|
exchangeRatesByCurrency, |
|
|
holdings: positions |
|
|
holdings: positions |
|
|
@ -626,7 +631,8 @@ export abstract class PortfolioCalculator { |
|
|
accumulatedValuesByDate[dateString] |
|
|
accumulatedValuesByDate[dateString] |
|
|
?.totalCurrentValueWithCurrencyEffect ?? new Big(0) |
|
|
?.totalCurrentValueWithCurrencyEffect ?? new Big(0) |
|
|
).add(currentValueWithCurrencyEffect), |
|
|
).add(currentValueWithCurrencyEffect), |
|
|
totalDividendValue: totalDividendValueByDate[dateString], |
|
|
totalDividendValueWithCurrencyEffect: |
|
|
|
|
|
totalDividendValueWithCurrencyEffectByDate[dateString], |
|
|
totalInvestmentValue: ( |
|
|
totalInvestmentValue: ( |
|
|
accumulatedValuesByDate[dateString]?.totalInvestmentValue ?? |
|
|
accumulatedValuesByDate[dateString]?.totalInvestmentValue ?? |
|
|
new Big(0) |
|
|
new Big(0) |
|
|
@ -651,8 +657,18 @@ export abstract class PortfolioCalculator { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const positionsIncludedInHoldings = positions |
|
|
|
|
|
.filter(({ includeInHoldings }) => { |
|
|
|
|
|
return includeInHoldings; |
|
|
|
|
|
}) |
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
|
|
.map(({ includeInHoldings, includeInPerformance, ...rest }) => { |
|
|
|
|
|
return rest; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
const performancePercentagesByDate = this.calculatePerformancePercentages({ |
|
|
const performancePercentagesByDate = this.calculatePerformancePercentages({ |
|
|
accumulatedValuesByDate |
|
|
accumulatedValuesByDate, |
|
|
|
|
|
holdings: positionsIncludedInHoldings |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
const historicalData: HistoricalDataItem[] = Object.entries( |
|
|
const historicalData: HistoricalDataItem[] = Object.entries( |
|
|
@ -663,7 +679,7 @@ export abstract class PortfolioCalculator { |
|
|
totalCashValueWithCurrencyEffect, |
|
|
totalCashValueWithCurrencyEffect, |
|
|
totalCurrentValue, |
|
|
totalCurrentValue, |
|
|
totalCurrentValueWithCurrencyEffect, |
|
|
totalCurrentValueWithCurrencyEffect, |
|
|
totalDividendValue, |
|
|
totalDividendValueWithCurrencyEffect, |
|
|
totalInvestmentValue, |
|
|
totalInvestmentValue, |
|
|
totalInvestmentValueWithCurrencyEffect, |
|
|
totalInvestmentValueWithCurrencyEffect, |
|
|
totalNetPerformanceValue, |
|
|
totalNetPerformanceValue, |
|
|
@ -674,7 +690,7 @@ export abstract class PortfolioCalculator { |
|
|
return { |
|
|
return { |
|
|
...performancePercentagesByDate[date], |
|
|
...performancePercentagesByDate[date], |
|
|
date, |
|
|
date, |
|
|
dividendInBaseCurrency: totalDividendValue.toNumber(), |
|
|
dividendInBaseCurrency: totalDividendValueWithCurrencyEffect.toNumber(), |
|
|
investmentValueWithCurrencyEffect: |
|
|
investmentValueWithCurrencyEffect: |
|
|
investmentValueWithCurrencyEffect.toNumber(), |
|
|
investmentValueWithCurrencyEffect.toNumber(), |
|
|
netPerformance: totalNetPerformanceValue.toNumber(), |
|
|
netPerformance: totalNetPerformanceValue.toNumber(), |
|
|
@ -692,15 +708,6 @@ export abstract class PortfolioCalculator { |
|
|
|
|
|
|
|
|
const overall = this.calculateOverallPerformance(positions); |
|
|
const overall = this.calculateOverallPerformance(positions); |
|
|
|
|
|
|
|
|
const positionsIncludedInHoldings = positions |
|
|
|
|
|
.filter(({ includeInHoldings }) => { |
|
|
|
|
|
return includeInHoldings; |
|
|
|
|
|
}) |
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
|
|
.map(({ includeInHoldings, includeInPerformance, ...rest }) => { |
|
|
|
|
|
return rest; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
return { |
|
|
return { |
|
|
...overall, |
|
|
...overall, |
|
|
errors, |
|
|
errors, |
|
|
@ -1363,6 +1370,8 @@ export abstract class PortfolioCalculator { |
|
|
// Take the values at the start date from the first day of the date
|
|
|
// Take the values at the start date from the first day of the date
|
|
|
// range
|
|
|
// range
|
|
|
if (historicalDataItemsOfDateRange.length === 0) { |
|
|
if (historicalDataItemsOfDateRange.length === 0) { |
|
|
|
|
|
// TODO: Remove the fallback to 0 with the next release, when each
|
|
|
|
|
|
// cached portfolio snapshot contains the dividend
|
|
|
dividendInBaseCurrencyAtStartDate = |
|
|
dividendInBaseCurrencyAtStartDate = |
|
|
historicalDataItem.dividendInBaseCurrency ?? 0; |
|
|
historicalDataItem.dividendInBaseCurrency ?? 0; |
|
|
|
|
|
|
|
|
@ -1390,7 +1399,8 @@ export abstract class PortfolioCalculator { |
|
|
|
|
|
|
|
|
const performancePercentagesByDate = |
|
|
const performancePercentagesByDate = |
|
|
this.calculatePerformancePercentagesForDateRange({ |
|
|
this.calculatePerformancePercentagesForDateRange({ |
|
|
historicalDataItems: historicalDataItemsOfDateRange |
|
|
historicalDataItems: historicalDataItemsOfDateRange, |
|
|
|
|
|
holdings: this.snapshot.positions |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
const chart = historicalDataItemsOfDateRange.map((historicalDataItem) => { |
|
|
const chart = historicalDataItemsOfDateRange.map((historicalDataItem) => { |
|
|
@ -1752,7 +1762,7 @@ export abstract class PortfolioCalculator { |
|
|
return chartDateMap; |
|
|
return chartDateMap; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private getTotalDividendValueByDate({ |
|
|
private getTotalDividendValueWithCurrencyEffectByDate({ |
|
|
chartDates, |
|
|
chartDates, |
|
|
exchangeRatesByCurrency, |
|
|
exchangeRatesByCurrency, |
|
|
holdings |
|
|
holdings |
|
|
@ -1786,10 +1796,11 @@ export abstract class PortfolioCalculator { |
|
|
} |
|
|
} |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
const totalDividendValueByDate: { [date: string]: Big } = {}; |
|
|
const totalDividendValueWithCurrencyEffectByDate: { [date: string]: Big } = |
|
|
|
|
|
{}; |
|
|
|
|
|
|
|
|
let index = 0; |
|
|
let index = 0; |
|
|
let totalDividendValue = new Big(0); |
|
|
let totalDividendValueWithCurrencyEffect = new Big(0); |
|
|
|
|
|
|
|
|
// The activities and the chart dates are sorted by date, so one pass over
|
|
|
// The activities and the chart dates are sorted by date, so one pass over
|
|
|
// both gives the dividends received up to each chart date
|
|
|
// both gives the dividends received up to each chart date
|
|
|
@ -1801,7 +1812,8 @@ export abstract class PortfolioCalculator { |
|
|
const { assetProfile, date, quantity, unitPrice } = |
|
|
const { assetProfile, date, quantity, unitPrice } = |
|
|
dividendActivities[index]; |
|
|
dividendActivities[index]; |
|
|
|
|
|
|
|
|
totalDividendValue = totalDividendValue.plus( |
|
|
totalDividendValueWithCurrencyEffect = |
|
|
|
|
|
totalDividendValueWithCurrencyEffect.plus( |
|
|
quantity |
|
|
quantity |
|
|
.mul(unitPrice) |
|
|
.mul(unitPrice) |
|
|
.mul( |
|
|
.mul( |
|
|
@ -1814,10 +1826,11 @@ export abstract class PortfolioCalculator { |
|
|
index++; |
|
|
index++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
totalDividendValueByDate[chartDate] = totalDividendValue; |
|
|
totalDividendValueWithCurrencyEffectByDate[chartDate] = |
|
|
|
|
|
totalDividendValueWithCurrencyEffect; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return totalDividendValueByDate; |
|
|
return totalDividendValueWithCurrencyEffectByDate; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@LogPerformance |
|
|
@LogPerformance |
|
|
|