|
|
@ -202,6 +202,7 @@ export abstract class PortfolioCalculator { |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const cashSymbols = new Set<string>(); |
|
|
const currencies: { [symbol: string]: string } = {}; |
|
|
const currencies: { [symbol: string]: string } = {}; |
|
|
const dataGatheringItems: DataGatheringItem[] = []; |
|
|
const dataGatheringItems: DataGatheringItem[] = []; |
|
|
let firstIndex = transactionPoints.length; |
|
|
let firstIndex = transactionPoints.length; |
|
|
@ -315,12 +316,11 @@ export abstract class PortfolioCalculator { |
|
|
const accumulatedValuesByDate: { |
|
|
const accumulatedValuesByDate: { |
|
|
[date: string]: { |
|
|
[date: string]: { |
|
|
investmentValueWithCurrencyEffect: Big; |
|
|
investmentValueWithCurrencyEffect: Big; |
|
|
totalAccountBalanceWithCurrencyEffect: Big; |
|
|
totalCashValueWithCurrencyEffect: Big; |
|
|
totalCurrentValue: Big; |
|
|
totalCurrentValue: Big; |
|
|
totalCurrentValueWithCurrencyEffect: Big; |
|
|
totalCurrentValueWithCurrencyEffect: Big; |
|
|
totalInvestmentValue: Big; |
|
|
totalInvestmentValue: Big; |
|
|
totalInvestmentValueWithCurrencyEffect: Big; |
|
|
totalInvestmentValueWithCurrencyEffect: Big; |
|
|
totalLiabilitiesWithCurrencyEffect: Big; |
|
|
|
|
|
totalNetPerformanceValue: Big; |
|
|
totalNetPerformanceValue: Big; |
|
|
totalNetPerformanceValueWithCurrencyEffect: Big; |
|
|
totalNetPerformanceValueWithCurrencyEffect: Big; |
|
|
totalTimeWeightedInvestmentValue: Big; |
|
|
totalTimeWeightedInvestmentValue: Big; |
|
|
@ -351,6 +351,8 @@ export abstract class PortfolioCalculator { |
|
|
] ?? 1 |
|
|
] ?? 1 |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
const valueInBaseCurrency = marketPriceInBaseCurrency.mul(item.quantity); |
|
|
|
|
|
|
|
|
const { |
|
|
const { |
|
|
currentValues, |
|
|
currentValues, |
|
|
currentValuesWithCurrencyEffect, |
|
|
currentValuesWithCurrencyEffect, |
|
|
@ -444,15 +446,14 @@ export abstract class PortfolioCalculator { |
|
|
quantity: item.quantity, |
|
|
quantity: item.quantity, |
|
|
symbol: item.symbol, |
|
|
symbol: item.symbol, |
|
|
tags: item.tags, |
|
|
tags: item.tags, |
|
|
valueInBaseCurrency: new Big(marketPriceInBaseCurrency).mul( |
|
|
valueInBaseCurrency |
|
|
item.quantity |
|
|
|
|
|
) |
|
|
|
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
if (item.assetSubClass === 'CASH') { |
|
|
if (item.assetSubClass === 'CASH') { |
|
|
totalCashInBaseCurrency = totalCashInBaseCurrency.plus( |
|
|
cashSymbols.add(item.symbol); |
|
|
marketPriceInBaseCurrency.mul(item.quantity) |
|
|
|
|
|
); |
|
|
totalCashInBaseCurrency = |
|
|
|
|
|
totalCashInBaseCurrency.plus(valueInBaseCurrency); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
totalInterestWithCurrencyEffect = totalInterestWithCurrencyEffect.plus( |
|
|
totalInterestWithCurrencyEffect = totalInterestWithCurrencyEffect.plus( |
|
|
@ -474,56 +475,7 @@ export abstract class PortfolioCalculator { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const accountBalanceItemsMap = this.accountBalanceItems.reduce( |
|
|
|
|
|
(map, { date, value }) => { |
|
|
|
|
|
map[date] = new Big(value); |
|
|
|
|
|
|
|
|
|
|
|
return map; |
|
|
|
|
|
}, |
|
|
|
|
|
{} as { [date: string]: Big } |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
const liabilityItemsMap = this.activities.reduce( |
|
|
|
|
|
(map, { assetProfile, date, quantity, type, unitPrice }) => { |
|
|
|
|
|
if (type === 'LIABILITY') { |
|
|
|
|
|
const exchangeRate = |
|
|
|
|
|
exchangeRatesByCurrency[ |
|
|
|
|
|
`${assetProfile.currency}${this.currency}` |
|
|
|
|
|
]?.[date] ?? 1; |
|
|
|
|
|
|
|
|
|
|
|
map[date] = (map[date] ?? new Big(0)).plus( |
|
|
|
|
|
quantity.mul(unitPrice).mul(exchangeRate) |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return map; |
|
|
|
|
|
}, |
|
|
|
|
|
{} as { [date: string]: Big } |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
const accountBalanceMap: { [date: string]: Big } = {}; |
|
|
|
|
|
const liabilitiesMap: { [date: string]: Big } = {}; |
|
|
|
|
|
|
|
|
|
|
|
let accumulatedLiabilities = new Big(0); |
|
|
|
|
|
let lastKnownBalance = new Big(0); |
|
|
|
|
|
|
|
|
|
|
|
for (const dateString of chartDates) { |
|
|
for (const dateString of chartDates) { |
|
|
if (accountBalanceItemsMap[dateString] !== undefined) { |
|
|
|
|
|
// If there's an exact balance for this date, update lastKnownBalance
|
|
|
|
|
|
lastKnownBalance = accountBalanceItemsMap[dateString]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Add the most recent balance to the accountBalanceMap
|
|
|
|
|
|
accountBalanceMap[dateString] = lastKnownBalance; |
|
|
|
|
|
|
|
|
|
|
|
if (liabilityItemsMap[dateString] !== undefined) { |
|
|
|
|
|
accumulatedLiabilities = accumulatedLiabilities.plus( |
|
|
|
|
|
liabilityItemsMap[dateString] |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
liabilitiesMap[dateString] = accumulatedLiabilities; |
|
|
|
|
|
|
|
|
|
|
|
for (const symbol of Object.keys(valuesBySymbol)) { |
|
|
for (const symbol of Object.keys(valuesBySymbol)) { |
|
|
const symbolValues = valuesBySymbol[symbol]; |
|
|
const symbolValues = valuesBySymbol[symbol]; |
|
|
|
|
|
|
|
|
@ -566,7 +518,14 @@ export abstract class PortfolioCalculator { |
|
|
accumulatedValuesByDate[dateString] |
|
|
accumulatedValuesByDate[dateString] |
|
|
?.investmentValueWithCurrencyEffect ?? new Big(0) |
|
|
?.investmentValueWithCurrencyEffect ?? new Big(0) |
|
|
).add(investmentValueWithCurrencyEffect), |
|
|
).add(investmentValueWithCurrencyEffect), |
|
|
totalAccountBalanceWithCurrencyEffect: accountBalanceMap[dateString], |
|
|
totalCashValueWithCurrencyEffect: ( |
|
|
|
|
|
accumulatedValuesByDate[dateString] |
|
|
|
|
|
?.totalCashValueWithCurrencyEffect ?? new Big(0) |
|
|
|
|
|
).add( |
|
|
|
|
|
cashSymbols.has(symbol) |
|
|
|
|
|
? currentValueWithCurrencyEffect |
|
|
|
|
|
: new Big(0) |
|
|
|
|
|
), |
|
|
totalCurrentValue: ( |
|
|
totalCurrentValue: ( |
|
|
accumulatedValuesByDate[dateString]?.totalCurrentValue ?? new Big(0) |
|
|
accumulatedValuesByDate[dateString]?.totalCurrentValue ?? new Big(0) |
|
|
).add(currentValue), |
|
|
).add(currentValue), |
|
|
@ -582,7 +541,6 @@ export abstract class PortfolioCalculator { |
|
|
accumulatedValuesByDate[dateString] |
|
|
accumulatedValuesByDate[dateString] |
|
|
?.totalInvestmentValueWithCurrencyEffect ?? new Big(0) |
|
|
?.totalInvestmentValueWithCurrencyEffect ?? new Big(0) |
|
|
).add(investmentValueAccumulatedWithCurrencyEffect), |
|
|
).add(investmentValueAccumulatedWithCurrencyEffect), |
|
|
totalLiabilitiesWithCurrencyEffect: liabilitiesMap[dateString], |
|
|
|
|
|
totalNetPerformanceValue: ( |
|
|
totalNetPerformanceValue: ( |
|
|
accumulatedValuesByDate[dateString]?.totalNetPerformanceValue ?? |
|
|
accumulatedValuesByDate[dateString]?.totalNetPerformanceValue ?? |
|
|
new Big(0) |
|
|
new Big(0) |
|
|
@ -608,12 +566,11 @@ export abstract class PortfolioCalculator { |
|
|
).map(([date, values]) => { |
|
|
).map(([date, values]) => { |
|
|
const { |
|
|
const { |
|
|
investmentValueWithCurrencyEffect, |
|
|
investmentValueWithCurrencyEffect, |
|
|
totalAccountBalanceWithCurrencyEffect, |
|
|
totalCashValueWithCurrencyEffect, |
|
|
totalCurrentValue, |
|
|
totalCurrentValue, |
|
|
totalCurrentValueWithCurrencyEffect, |
|
|
totalCurrentValueWithCurrencyEffect, |
|
|
totalInvestmentValue, |
|
|
totalInvestmentValue, |
|
|
totalInvestmentValueWithCurrencyEffect, |
|
|
totalInvestmentValueWithCurrencyEffect, |
|
|
totalLiabilitiesWithCurrencyEffect, |
|
|
|
|
|
totalNetPerformanceValue, |
|
|
totalNetPerformanceValue, |
|
|
totalNetPerformanceValueWithCurrencyEffect, |
|
|
totalNetPerformanceValueWithCurrencyEffect, |
|
|
totalTimeWeightedInvestmentValue, |
|
|
totalTimeWeightedInvestmentValue, |
|
|
@ -642,10 +599,8 @@ export abstract class PortfolioCalculator { |
|
|
netPerformance: totalNetPerformanceValue.toNumber(), |
|
|
netPerformance: totalNetPerformanceValue.toNumber(), |
|
|
netPerformanceWithCurrencyEffect: |
|
|
netPerformanceWithCurrencyEffect: |
|
|
totalNetPerformanceValueWithCurrencyEffect.toNumber(), |
|
|
totalNetPerformanceValueWithCurrencyEffect.toNumber(), |
|
|
netWorth: totalCurrentValueWithCurrencyEffect |
|
|
netWorth: totalCurrentValueWithCurrencyEffect.toNumber(), |
|
|
.minus(totalLiabilitiesWithCurrencyEffect) |
|
|
totalCashInBaseCurrency: totalCashValueWithCurrencyEffect.toNumber(), |
|
|
.toNumber(), |
|
|
|
|
|
totalAccountBalance: totalAccountBalanceWithCurrencyEffect.toNumber(), |
|
|
|
|
|
totalInvestment: totalInvestmentValue.toNumber(), |
|
|
totalInvestment: totalInvestmentValue.toNumber(), |
|
|
totalInvestmentValueWithCurrencyEffect: |
|
|
totalInvestmentValueWithCurrencyEffect: |
|
|
totalInvestmentValueWithCurrencyEffect.toNumber(), |
|
|
totalInvestmentValueWithCurrencyEffect.toNumber(), |
|
|
|