Feature/fix twr performance 2 (#684)

* Fix TWR performance
* Weight holding period returns according to their investment value

Co-authored-by: Reto Kaul <retokaul@sublimd.com>
This commit is contained in:
gizmodus 2022-02-09 09:29:43 +01:00 committed by GitHub
parent 6ac693dd39
commit 6eb4eae4a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -344,6 +344,12 @@ export class PortfolioCalculatorNew {
let totalInvestment = new Big(0); let totalInvestment = new Big(0);
let totalUnits = new Big(0); let totalUnits = new Big(0);
const holdingPeriodPerformances: {
grossReturn: Big;
netReturn: Big;
valueOfInvestment: Big;
}[] = [];
// Add a synthetic order at the start and the end date // Add a synthetic order at the start and the end date
orders.push({ orders.push({
symbol, symbol,
@ -463,7 +469,7 @@ export class PortfolioCalculatorNew {
); );
const netHoldingPeriodReturn = valueOfInvestmentBeforeTransaction const netHoldingPeriodReturn = valueOfInvestmentBeforeTransaction
.sub(fees.sub(order.fee)) .sub(fees.minus(feesAtStartDate))
.sub( .sub(
lastValueOfInvestmentBeforeTransaction.plus( lastValueOfInvestmentBeforeTransaction.plus(
lastTransactionInvestment lastTransactionInvestment
@ -479,6 +485,14 @@ export class PortfolioCalculatorNew {
timeWeightedNetPerformancePercentage.mul( timeWeightedNetPerformancePercentage.mul(
new Big(1).plus(netHoldingPeriodReturn) new Big(1).plus(netHoldingPeriodReturn)
); );
holdingPeriodPerformances.push({
grossReturn: grossHoldingPeriodReturn,
netReturn: netHoldingPeriodReturn,
valueOfInvestment: lastValueOfInvestmentBeforeTransaction.plus(
lastTransactionInvestment
)
});
} }
grossPerformance = newGrossPerformance; grossPerformance = newGrossPerformance;
@ -508,13 +522,39 @@ export class PortfolioCalculatorNew {
.minus(grossPerformanceAtStartDate) .minus(grossPerformanceAtStartDate)
.minus(fees.minus(feesAtStartDate)); .minus(fees.minus(feesAtStartDate));
let valueOfInvestmentSum = new Big(0);
for (const holdingPeriodPerformance of holdingPeriodPerformances) {
valueOfInvestmentSum = valueOfInvestmentSum.add(
holdingPeriodPerformance.valueOfInvestment
);
}
let totalWeightedGrossPerformance = new Big(0);
let totalWeightedNetPerformance = new Big(0);
// Weight the holding period returns according to their value of investment
for (const holdingPeriodPerformance of holdingPeriodPerformances) {
totalWeightedGrossPerformance = totalWeightedGrossPerformance.plus(
holdingPeriodPerformance.grossReturn
.mul(holdingPeriodPerformance.valueOfInvestment)
.div(valueOfInvestmentSum)
);
totalWeightedNetPerformance = totalWeightedNetPerformance.plus(
holdingPeriodPerformance.netReturn
.mul(holdingPeriodPerformance.valueOfInvestment)
.div(valueOfInvestmentSum)
);
}
return { return {
initialValue, initialValue,
hasErrors: !initialValue || !unitPriceAtEndDate, hasErrors: !initialValue || !unitPriceAtEndDate,
netPerformance: totalNetPerformance, netPerformance: totalNetPerformance,
netPerformancePercentage: timeWeightedNetPerformancePercentage, netPerformancePercentage: totalWeightedNetPerformance,
grossPerformance: totalGrossPerformance, grossPerformance: totalGrossPerformance,
grossPerformancePercentage: timeWeightedGrossPerformancePercentage grossPerformancePercentage: totalWeightedGrossPerformance
}; };
} }