|
|
@ -794,15 +794,25 @@ export abstract class PortfolioCalculator { |
|
|
|
|
|
|
|
|
const chart: HistoricalDataItem[] = []; |
|
|
const chart: HistoricalDataItem[] = []; |
|
|
|
|
|
|
|
|
|
|
|
let grossPerformanceAtStartDate: number; |
|
|
|
|
|
let grossPerformanceWithCurrencyEffectAtStartDate: number; |
|
|
let netPerformanceAtStartDate: number; |
|
|
let netPerformanceAtStartDate: number; |
|
|
let netPerformanceWithCurrencyEffectAtStartDate: number; |
|
|
let netPerformanceWithCurrencyEffectAtStartDate: number; |
|
|
const totalInvestmentValuesWithCurrencyEffect: number[] = []; |
|
|
const timeWeightedInvestmentValues: number[] = []; |
|
|
|
|
|
const timeWeightedInvestmentValuesWithCurrencyEffect: number[] = []; |
|
|
|
|
|
|
|
|
for (const historicalDataItem of historicalData) { |
|
|
for (const historicalDataItem of historicalData) { |
|
|
const date = resetHours(parseDate(historicalDataItem.date)); |
|
|
const date = resetHours(parseDate(historicalDataItem.date)); |
|
|
|
|
|
|
|
|
if (!isBefore(date, start) && !isAfter(date, end)) { |
|
|
if (!isBefore(date, start) && !isAfter(date, end)) { |
|
|
if (!isNumber(netPerformanceAtStartDate)) { |
|
|
if (!isNumber(netPerformanceAtStartDate)) { |
|
|
|
|
|
grossPerformanceAtStartDate = |
|
|
|
|
|
historicalDataItem.value - historicalDataItem.totalInvestment; |
|
|
|
|
|
|
|
|
|
|
|
grossPerformanceWithCurrencyEffectAtStartDate = |
|
|
|
|
|
historicalDataItem.valueWithCurrencyEffect - |
|
|
|
|
|
historicalDataItem.totalInvestmentValueWithCurrencyEffect; |
|
|
|
|
|
|
|
|
netPerformanceAtStartDate = historicalDataItem.netPerformance; |
|
|
netPerformanceAtStartDate = historicalDataItem.netPerformance; |
|
|
|
|
|
|
|
|
netPerformanceWithCurrencyEffectAtStartDate = |
|
|
netPerformanceWithCurrencyEffectAtStartDate = |
|
|
@ -816,33 +826,48 @@ export abstract class PortfolioCalculator { |
|
|
historicalDataItem.netPerformanceWithCurrencyEffect - |
|
|
historicalDataItem.netPerformanceWithCurrencyEffect - |
|
|
netPerformanceWithCurrencyEffectAtStartDate; |
|
|
netPerformanceWithCurrencyEffectAtStartDate; |
|
|
|
|
|
|
|
|
|
|
|
// Add the gross performance at the start date of the range to the
|
|
|
|
|
|
// investment of each day. Thus the range starts with the value of its
|
|
|
|
|
|
// first day, and subsequent buy and sell activities stay included.
|
|
|
|
|
|
if (historicalDataItem.totalInvestment > 0) { |
|
|
|
|
|
timeWeightedInvestmentValues.push( |
|
|
|
|
|
historicalDataItem.totalInvestment + grossPerformanceAtStartDate |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (historicalDataItem.totalInvestmentValueWithCurrencyEffect > 0) { |
|
|
if (historicalDataItem.totalInvestmentValueWithCurrencyEffect > 0) { |
|
|
totalInvestmentValuesWithCurrencyEffect.push( |
|
|
timeWeightedInvestmentValuesWithCurrencyEffect.push( |
|
|
historicalDataItem.totalInvestmentValueWithCurrencyEffect |
|
|
historicalDataItem.totalInvestmentValueWithCurrencyEffect + |
|
|
|
|
|
grossPerformanceWithCurrencyEffectAtStartDate |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const timeWeightedInvestmentValue = |
|
|
const timeWeightedInvestmentValue = |
|
|
totalInvestmentValuesWithCurrencyEffect.length > 0 |
|
|
timeWeightedInvestmentValues.length > 0 |
|
|
? sum(totalInvestmentValuesWithCurrencyEffect) / |
|
|
? sum(timeWeightedInvestmentValues) / |
|
|
totalInvestmentValuesWithCurrencyEffect.length |
|
|
timeWeightedInvestmentValues.length |
|
|
|
|
|
: 0; |
|
|
|
|
|
|
|
|
|
|
|
const timeWeightedInvestmentValueWithCurrencyEffect = |
|
|
|
|
|
timeWeightedInvestmentValuesWithCurrencyEffect.length > 0 |
|
|
|
|
|
? sum(timeWeightedInvestmentValuesWithCurrencyEffect) / |
|
|
|
|
|
timeWeightedInvestmentValuesWithCurrencyEffect.length |
|
|
: 0; |
|
|
: 0; |
|
|
|
|
|
|
|
|
chart.push({ |
|
|
chart.push({ |
|
|
...historicalDataItem, |
|
|
...historicalDataItem, |
|
|
netPerformance: |
|
|
netPerformance: netPerformanceSinceStartDate, |
|
|
historicalDataItem.netPerformance - netPerformanceAtStartDate, |
|
|
|
|
|
netPerformanceWithCurrencyEffect: |
|
|
netPerformanceWithCurrencyEffect: |
|
|
netPerformanceWithCurrencyEffectSinceStartDate, |
|
|
netPerformanceWithCurrencyEffectSinceStartDate, |
|
|
netPerformanceInPercentage: |
|
|
netPerformanceInPercentage: |
|
|
timeWeightedInvestmentValue === 0 |
|
|
timeWeightedInvestmentValue > 0 |
|
|
? 0 |
|
|
? netPerformanceSinceStartDate / timeWeightedInvestmentValue |
|
|
: netPerformanceSinceStartDate / timeWeightedInvestmentValue, |
|
|
: 0, |
|
|
netPerformanceInPercentageWithCurrencyEffect: |
|
|
netPerformanceInPercentageWithCurrencyEffect: |
|
|
timeWeightedInvestmentValue === 0 |
|
|
timeWeightedInvestmentValueWithCurrencyEffect > 0 |
|
|
? 0 |
|
|
? netPerformanceWithCurrencyEffectSinceStartDate / |
|
|
: netPerformanceWithCurrencyEffectSinceStartDate / |
|
|
timeWeightedInvestmentValueWithCurrencyEffect |
|
|
timeWeightedInvestmentValue |
|
|
: 0 |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|