Browse Source

Merge 6f57439e56 into 29b8d63951

pull/3857/merge
dandevaud 1 month ago
committed by GitHub
parent
commit
3ffade4df9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 18
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts
  2. 118
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts

18
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts

@ -154,25 +154,25 @@ describe('PortfolioCalculator', () => {
dividendInBaseCurrency: new Big('0.62'), dividendInBaseCurrency: new Big('0.62'),
fee: new Big('19'), fee: new Big('19'),
firstBuyDate: '2021-09-16', firstBuyDate: '2021-09-16',
grossPerformance: new Big('33.25'), grossPerformance: new Big('33.87'),
grossPerformancePercentage: new Big('0.11136043941322258691'), grossPerformancePercentage: new Big('0.11343693482483756447'),
grossPerformancePercentageWithCurrencyEffect: new Big( grossPerformancePercentageWithCurrencyEffect: new Big(
'0.11136043941322258691' '0.11343693482483756447'
), ),
grossPerformanceWithCurrencyEffect: new Big('33.25'), grossPerformanceWithCurrencyEffect: new Big('33.87'),
investment: new Big('298.58'), investment: new Big('298.58'),
investmentWithCurrencyEffect: new Big('298.58'), investmentWithCurrencyEffect: new Big('298.58'),
marketPrice: 331.83, marketPrice: 331.83,
marketPriceInBaseCurrency: 331.83, marketPriceInBaseCurrency: 331.83,
netPerformance: new Big('14.25'), netPerformance: new Big('14.87'),
netPerformancePercentage: new Big('0.04772590260566682296'), netPerformancePercentage: new Big('0.04980239801728180052'),
netPerformancePercentageWithCurrencyEffectMap: { netPerformancePercentageWithCurrencyEffectMap: {
max: new Big('0.04772590260566682296') max: new Big('0.04980239801728180052')
}, },
netPerformanceWithCurrencyEffectMap: { netPerformanceWithCurrencyEffectMap: {
'1d': new Big('-5.39'), '1d': new Big('-5.39'),
'5y': new Big('14.25'), '5y': new Big('14.87'),
max: new Big('14.25'), max: new Big('14.87'),
wtd: new Big('-5.39') wtd: new Big('-5.39')
}, },
quantity: new Big('1'), quantity: new Big('1'),

118
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts

@ -142,6 +142,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
let grossPerformanceAtStartDateWithCurrencyEffect = new Big(0); let grossPerformanceAtStartDateWithCurrencyEffect = new Big(0);
let grossPerformanceFromSells = new Big(0); let grossPerformanceFromSells = new Big(0);
let grossPerformanceFromSellsWithCurrencyEffect = new Big(0); let grossPerformanceFromSellsWithCurrencyEffect = new Big(0);
let grossPerformanceFromDividends = new Big(0);
let grossPerformanceFromDividendsWithCurrencyEffect = new Big(0);
let initialValue: Big; let initialValue: Big;
let initialValueWithCurrencyEffect: Big; let initialValueWithCurrencyEffect: Big;
let investmentAtStartDate: Big; let investmentAtStartDate: Big;
@ -559,28 +561,27 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
order.unitPriceInBaseCurrencyWithCurrencyEffect order.unitPriceInBaseCurrencyWithCurrencyEffect
); );
const grossPerformanceFromSell = ({
order.type === 'SELL' grossPerformanceFromSells,
? order.unitPriceInBaseCurrency grossPerformanceFromSellsWithCurrencyEffect
.minus(lastAveragePrice) } = this.handleSellOrder(
.mul(order.quantity) order,
: new Big(0); lastAveragePrice,
lastAveragePriceWithCurrencyEffect,
const grossPerformanceFromSellWithCurrencyEffect = grossPerformanceFromSells,
order.type === 'SELL' grossPerformanceFromSellsWithCurrencyEffect
? order.unitPriceInBaseCurrencyWithCurrencyEffect ));
.minus(lastAveragePriceWithCurrencyEffect)
.mul(order.quantity) ({
: new Big(0); grossPerformanceFromDividends,
grossPerformanceFromDividendsWithCurrencyEffect
grossPerformanceFromSells = grossPerformanceFromSells.plus( } = this.handleDividend(
grossPerformanceFromSell order,
); grossPerformanceFromDividends,
grossPerformanceFromDividendsWithCurrencyEffect,
grossPerformanceFromSellsWithCurrencyEffect = currentExchangeRate,
grossPerformanceFromSellsWithCurrencyEffect.plus( exchangeRateAtOrderDate
grossPerformanceFromSellWithCurrencyEffect ));
);
lastAveragePrice = totalQuantityFromBuyTransactions.eq(0) lastAveragePrice = totalQuantityFromBuyTransactions.eq(0)
? new Big(0) ? new Big(0)
@ -602,19 +603,21 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
grossPerformanceFromSells.toNumber() grossPerformanceFromSells.toNumber()
); );
console.log( console.log(
'grossPerformanceFromSellWithCurrencyEffect', 'grossPerformanceFromSellsWithCurrencyEffect',
grossPerformanceFromSellWithCurrencyEffect.toNumber() grossPerformanceFromSellsWithCurrencyEffect.toNumber()
); );
} }
const newGrossPerformance = valueOfInvestment const newGrossPerformance = valueOfInvestment
.minus(totalInvestment) .minus(totalInvestment)
.plus(grossPerformanceFromSells); .plus(grossPerformanceFromSells)
.plus(grossPerformanceFromDividends);
const newGrossPerformanceWithCurrencyEffect = const newGrossPerformanceWithCurrencyEffect =
valueOfInvestmentWithCurrencyEffect valueOfInvestmentWithCurrencyEffect
.minus(totalInvestmentWithCurrencyEffect) .minus(totalInvestmentWithCurrencyEffect)
.plus(grossPerformanceFromSellsWithCurrencyEffect); .plus(grossPerformanceFromSellsWithCurrencyEffect)
.plus(grossPerformanceFromDividendsWithCurrencyEffect);
grossPerformance = newGrossPerformance; grossPerformance = newGrossPerformance;
@ -966,4 +969,67 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
timeWeightedAverageInvestmentBetweenStartAndEndDateWithCurrencyEffect timeWeightedAverageInvestmentBetweenStartAndEndDateWithCurrencyEffect
}; };
} }
private handleSellOrder(
order: PortfolioOrderItem,
lastAveragePrice,
lastAveragePriceWithCurrencyEffect,
grossPerformanceFromSells,
grossPerformanceFromSellsWithCurrencyEffect
) {
if (order.type === 'SELL') {
const grossPerformanceFromSell = order.unitPriceInBaseCurrency
.minus(lastAveragePrice)
.mul(order.quantity);
const grossPerformanceFromSellWithCurrencyEffect =
order.unitPriceInBaseCurrencyWithCurrencyEffect
.minus(lastAveragePriceWithCurrencyEffect)
.mul(order.quantity);
grossPerformanceFromSells = grossPerformanceFromSells.plus(
grossPerformanceFromSell
);
grossPerformanceFromSellsWithCurrencyEffect =
grossPerformanceFromSellsWithCurrencyEffect.plus(
grossPerformanceFromSellWithCurrencyEffect
);
}
return {
grossPerformanceFromSells,
grossPerformanceFromSellsWithCurrencyEffect
};
}
private handleDividend(
order: PortfolioOrderItem,
grossPerformanceFromDividends,
grossPerformanceFromDividendsWithCurrencyEffect,
currentExchangeRate: number,
exchangeRateAtDateOfOrder: number
) {
if (order.type === 'DIVIDEND') {
const grossPerformanceFromDividend = order.unitPrice
.mul(currentExchangeRate)
.mul(order.quantity);
const grossPerformanceFromDividendWithCurrencyEffect = order.unitPrice
.mul(exchangeRateAtDateOfOrder)
.mul(order.quantity);
grossPerformanceFromDividends = grossPerformanceFromDividends.plus(
grossPerformanceFromDividend
);
grossPerformanceFromDividendsWithCurrencyEffect =
grossPerformanceFromDividendsWithCurrencyEffect.plus(
grossPerformanceFromDividendWithCurrencyEffect
);
}
return {
grossPerformanceFromDividends,
grossPerformanceFromDividendsWithCurrencyEffect
};
}
} }

Loading…
Cancel
Save