Browse Source

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>
pull/686/head
gizmodus 3 years ago
committed by GitHub
parent
commit
6eb4eae4a9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 46
      apps/api/src/app/portfolio/portfolio-calculator-new.ts

46
apps/api/src/app/portfolio/portfolio-calculator-new.ts

@ -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
}; };
} }

Loading…
Cancel
Save