Browse Source

Include dividends in portfolio performance

pull/7961/head
Thomas Kaul 1 week ago
parent
commit
c572edcefc
  1. 17
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  2. 3
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur.spec.ts
  3. 3
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd.spec.ts
  4. 3
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-cash.spec.ts
  5. 44
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-with-dividend.spec.ts
  6. 3
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell.spec.ts
  7. 11
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts
  8. 4
      apps/api/src/app/portfolio/portfolio.service.ts
  9. 1
      apps/api/src/app/portfolio/types/performance-percentages.type.ts
  10. 65
      apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html
  11. 1
      apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts
  12. 4
      apps/client/src/app/pages/faq/overview/faq-overview-page.html
  13. 97
      apps/client/src/app/pages/portfolio/analysis/analysis-page.html
  14. 1
      libs/common/src/lib/interfaces/historical-data-item.interface.ts
  15. 1
      libs/common/src/lib/interfaces/portfolio-performance.interface.ts

17
apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

@ -946,6 +946,7 @@ export abstract class PortfolioCalculator {
const currentExchangeRate = exchangeRates[format(new Date(), DATE_FORMAT)]; const currentExchangeRate = exchangeRates[format(new Date(), DATE_FORMAT)];
const currentValues: { [date: string]: Big } = {}; const currentValues: { [date: string]: Big } = {};
const currentValuesWithCurrencyEffect: { [date: string]: Big } = {}; const currentValuesWithCurrencyEffect: { [date: string]: Big } = {};
let dividends = new Big(0);
let fees = new Big(0); let fees = new Big(0);
let feesAtStartDate = new Big(0); let feesAtStartDate = new Big(0);
let feesAtStartDateWithCurrencyEffect = new Big(0); let feesAtStartDateWithCurrencyEffect = new Big(0);
@ -1123,6 +1124,16 @@ export abstract class PortfolioCalculator {
activity.feeInBaseCurrencyWithCurrencyEffect ?? 0 activity.feeInBaseCurrencyWithCurrencyEffect ?? 0
); );
if (activity.type === 'DIVIDEND') {
// The amount of a dividend in the base currency is the same with and
// without currency effect, like the dividend of the holding
dividends = dividends.plus(
activity.quantity
.mul(activity.unitPrice)
.mul(exchangeRateAtActivityDate ?? 1)
);
}
totalQuantity = totalQuantity.plus( totalQuantity = totalQuantity.plus(
activity.quantity.mul(getFactor(activity.type)) activity.quantity.mul(getFactor(activity.type))
); );
@ -1190,12 +1201,14 @@ export abstract class PortfolioCalculator {
const newGrossPerformance = valueOfInvestment const newGrossPerformance = valueOfInvestment
.minus(totalInvestment) .minus(totalInvestment)
.plus(grossPerformanceFromSells); .plus(grossPerformanceFromSells)
.plus(dividends);
const newGrossPerformanceWithCurrencyEffect = const newGrossPerformanceWithCurrencyEffect =
valueOfInvestmentWithCurrencyEffect valueOfInvestmentWithCurrencyEffect
.minus(totalInvestmentWithCurrencyEffect) .minus(totalInvestmentWithCurrencyEffect)
.plus(grossPerformanceFromSellsWithCurrencyEffect); .plus(grossPerformanceFromSellsWithCurrencyEffect)
.plus(dividends);
grossPerformance = newGrossPerformance; grossPerformance = newGrossPerformance;

3
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur.spec.ts

@ -143,6 +143,7 @@ describe('PortfolioCalculator', () => {
expect(portfolioSnapshot.historicalData[0]).toEqual({ expect(portfolioSnapshot.historicalData[0]).toEqual({
date: '2021-12-11', date: '2021-12-11',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
netPerformance: 0, netPerformance: 0,
@ -163,6 +164,7 @@ describe('PortfolioCalculator', () => {
expect(portfolioSnapshot.historicalData[1]).toEqual({ expect(portfolioSnapshot.historicalData[1]).toEqual({
date: '2021-12-12', date: '2021-12-12',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 44558.42, investmentValueWithCurrencyEffect: 44558.42,
netPerformance: 5535.42, // 1 * (50098.3 - 44558.42) - 4.46 = 5535.42 netPerformance: 5535.42, // 1 * (50098.3 - 44558.42) - 4.46 = 5535.42
@ -184,6 +186,7 @@ describe('PortfolioCalculator', () => {
).toEqual({ ).toEqual({
date: '2022-01-14', date: '2022-01-14',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
netPerformance: -1463.18, netPerformance: -1463.18,

3
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd.spec.ts

@ -143,6 +143,7 @@ describe('PortfolioCalculator', () => {
expect(portfolioSnapshot.historicalData[0]).toEqual({ expect(portfolioSnapshot.historicalData[0]).toEqual({
date: '2021-12-11', date: '2021-12-11',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
netPerformance: 0, netPerformance: 0,
@ -163,6 +164,7 @@ describe('PortfolioCalculator', () => {
expect(portfolioSnapshot.historicalData[1]).toEqual({ expect(portfolioSnapshot.historicalData[1]).toEqual({
date: '2021-12-12', date: '2021-12-12',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 44558.42, investmentValueWithCurrencyEffect: 44558.42,
netPerformance: 5535.42, // 1 * (50098.3 - 44558.42) - 4.46 = 5535.42 netPerformance: 5535.42, // 1 * (50098.3 - 44558.42) - 4.46 = 5535.42
@ -184,6 +186,7 @@ describe('PortfolioCalculator', () => {
).toEqual({ ).toEqual({
date: '2022-01-14', date: '2022-01-14',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
netPerformance: -1463.18, netPerformance: -1463.18,

3
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-cash.spec.ts

@ -322,6 +322,7 @@ describe('PortfolioCalculator', () => {
expect(portfolioSnapshot.historicalData.at(-1)).toEqual({ expect(portfolioSnapshot.historicalData.at(-1)).toEqual({
date: '2025-01-01', date: '2025-01-01',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
netPerformance: 0, netPerformance: 0,
@ -462,6 +463,7 @@ describe('PortfolioCalculator', () => {
expect(portfolioSnapshot.historicalData.at(-1)).toEqual({ expect(portfolioSnapshot.historicalData.at(-1)).toEqual({
date: '2025-01-01', date: '2025-01-01',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
netPerformance: 0, netPerformance: 0,
@ -606,6 +608,7 @@ describe('PortfolioCalculator', () => {
expect(portfolioSnapshot.historicalData.at(-1)).toEqual({ expect(portfolioSnapshot.historicalData.at(-1)).toEqual({
date: '2025-01-01', date: '2025-01-01',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
netPerformance: 0, netPerformance: 0,

44
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-with-dividend.spec.ts

@ -155,25 +155,25 @@ describe('PortfolioCalculator', () => {
'0.001144362748184' '0.001144362748184'
), ),
fee: new Big('19'), fee: new Big('19'),
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'),
@ -199,11 +199,12 @@ describe('PortfolioCalculator', () => {
'1d': { '1d': {
date: '2023-07-10', date: '2023-07-10',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
netPerformance: -5.390000000000001, netPerformance: -5.390000000000002,
netPerformanceInPercentage: -0.015983630864124312, netPerformanceInPercentage: -0.015983630864124316,
netPerformanceInPercentageWithCurrencyEffect: -0.015983630864124312, netPerformanceInPercentageWithCurrencyEffect: -0.015983630864124316,
netPerformanceWithCurrencyEffect: -5.390000000000001, netPerformanceWithCurrencyEffect: -5.390000000000002,
totalInvestmentValueWithCurrencyEffect: 298.58, totalInvestmentValueWithCurrencyEffect: 298.58,
valueWithCurrencyEffect: 331.83 valueWithCurrencyEffect: 331.83
}, },
@ -211,21 +212,22 @@ describe('PortfolioCalculator', () => {
date: '2023-07-10', date: '2023-07-10',
dividendInBaseCurrency: 0.62, dividendInBaseCurrency: 0.62,
dividendInPercentageWithCurrencyEffect: 0.002076495411614967, dividendInPercentageWithCurrencyEffect: 0.002076495411614967,
netPerformance: 14.25, netPerformance: 14.87,
netPerformanceInPercentage: 0.04772590260566659, netPerformanceInPercentage: 0.049802398017281556,
netPerformanceInPercentageWithCurrencyEffect: 0.04772590260566659, netPerformanceInPercentageWithCurrencyEffect: 0.049802398017281556,
netPerformanceWithCurrencyEffect: 14.25, netPerformanceWithCurrencyEffect: 14.87,
totalInvestmentValueWithCurrencyEffect: 298.58, totalInvestmentValueWithCurrencyEffect: 298.58,
valueWithCurrencyEffect: 331.83 valueWithCurrencyEffect: 331.83
}, },
ytd: { ytd: {
date: '2023-07-10', date: '2023-07-10',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
netPerformance: -7.68, netPerformance: -7.6800000000000015,
netPerformanceInPercentage: -0.022620835910577012, netPerformanceInPercentage: -0.022620835910577015,
netPerformanceInPercentageWithCurrencyEffect: -0.022620835910577012, netPerformanceInPercentageWithCurrencyEffect: -0.022620835910577015,
netPerformanceWithCurrencyEffect: -7.68, netPerformanceWithCurrencyEffect: -7.6800000000000015,
totalInvestmentValueWithCurrencyEffect: 298.58, totalInvestmentValueWithCurrencyEffect: 298.58,
valueWithCurrencyEffect: 331.83 valueWithCurrencyEffect: 331.83
} }

3
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell.spec.ts

@ -140,6 +140,7 @@ describe('PortfolioCalculator', () => {
expect(portfolioSnapshot.historicalData[0]).toEqual({ expect(portfolioSnapshot.historicalData[0]).toEqual({
date: '2022-03-06', date: '2022-03-06',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
netPerformance: 0, netPerformance: 0,
@ -161,6 +162,7 @@ describe('PortfolioCalculator', () => {
expect(portfolioSnapshot.historicalData[1]).toEqual({ expect(portfolioSnapshot.historicalData[1]).toEqual({
date: '2022-03-07', date: '2022-03-07',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 151.6, investmentValueWithCurrencyEffect: 151.6,
netPerformance: 0, // 2 * (75.8 - 75.8) = 0 netPerformance: 0, // 2 * (75.8 - 75.8) = 0
@ -182,6 +184,7 @@ describe('PortfolioCalculator', () => {
).toEqual({ ).toEqual({
date: '2022-04-11', date: '2022-04-11',
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
investmentValueWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0,
netPerformance: 19.86, netPerformance: 19.86,

11
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts

@ -192,6 +192,13 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
} }
] of Object.entries(accumulatedValuesByDate)) { ] of Object.entries(accumulatedValuesByDate)) {
performancePercentagesByDate[date] = { performancePercentagesByDate[date] = {
dividendInPercentage:
hasDividendWithoutAverageInvestment ||
totalAverageInvestmentValue.eq(0)
? 0
: totalDividendValueWithCurrencyEffect
.div(totalAverageInvestmentValue)
.toNumber(),
dividendInPercentageWithCurrencyEffect: dividendInPercentageWithCurrencyEffect:
hasDividendWithoutAverageInvestment || hasDividendWithoutAverageInvestment ||
totalAverageInvestmentValueWithCurrencyEffect.eq(0) totalAverageInvestmentValueWithCurrencyEffect.eq(0)
@ -275,6 +282,10 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
: 0; : 0;
performancePercentagesByDate[historicalDataItem.date] = { performancePercentagesByDate[historicalDataItem.date] = {
dividendInPercentage:
!hasDividendWithoutAverageInvestment && averageInvestmentValue > 0
? historicalDataItem.dividendInBaseCurrency / averageInvestmentValue
: 0,
dividendInPercentageWithCurrencyEffect: dividendInPercentageWithCurrencyEffect:
!hasDividendWithoutAverageInvestment && !hasDividendWithoutAverageInvestment &&
averageInvestmentValueWithCurrencyEffect > 0 averageInvestmentValueWithCurrencyEffect > 0

4
apps/api/src/app/portfolio/portfolio.service.ts

@ -1222,6 +1222,7 @@ export class PortfolioService {
currentNetWorth: 0, currentNetWorth: 0,
currentValueInBaseCurrency: 0, currentValueInBaseCurrency: 0,
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendPercentage: 0,
dividendPercentageWithCurrencyEffect: 0, dividendPercentageWithCurrencyEffect: 0,
netPerformance: 0, netPerformance: 0,
netPerformancePercentage: 0, netPerformancePercentage: 0,
@ -1255,6 +1256,7 @@ export class PortfolioService {
const { const {
dividendInBaseCurrency, dividendInBaseCurrency,
dividendInPercentage,
dividendInPercentageWithCurrencyEffect, dividendInPercentageWithCurrencyEffect,
netPerformance, netPerformance,
netPerformanceInPercentage, netPerformanceInPercentage,
@ -1266,6 +1268,7 @@ export class PortfolioService {
valueWithCurrencyEffect valueWithCurrencyEffect
} = chart?.at(-1) ?? { } = chart?.at(-1) ?? {
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendInPercentage: 0,
dividendInPercentageWithCurrencyEffect: 0, dividendInPercentageWithCurrencyEffect: 0,
netPerformance: 0, netPerformance: 0,
netPerformanceInPercentage: 0, netPerformanceInPercentage: 0,
@ -1289,6 +1292,7 @@ export class PortfolioService {
totalInvestmentValueWithCurrencyEffect, totalInvestmentValueWithCurrencyEffect,
currentNetWorth: netWorth, currentNetWorth: netWorth,
currentValueInBaseCurrency: valueWithCurrencyEffect, currentValueInBaseCurrency: valueWithCurrencyEffect,
dividendPercentage: dividendInPercentage,
dividendPercentageWithCurrencyEffect: dividendPercentageWithCurrencyEffect:
dividendInPercentageWithCurrencyEffect, dividendInPercentageWithCurrencyEffect,
netPerformancePercentage: netPerformanceInPercentage, netPerformancePercentage: netPerformanceInPercentage,

1
apps/api/src/app/portfolio/types/performance-percentages.type.ts

@ -3,6 +3,7 @@ import { HistoricalDataItem } from '@ghostfolio/common/interfaces';
export type PerformancePercentages = Required< export type PerformancePercentages = Required<
Pick< Pick<
HistoricalDataItem, HistoricalDataItem,
| 'dividendInPercentage'
| 'dividendInPercentageWithCurrencyEffect' | 'dividendInPercentageWithCurrencyEffect'
| 'netPerformanceInPercentage' | 'netPerformanceInPercentage'
| 'netPerformanceInPercentageWithCurrencyEffect' | 'netPerformanceInPercentageWithCurrencyEffect'

65
apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html

@ -94,14 +94,39 @@
[locale]="locale" [locale]="locale"
[precision]="precision" [precision]="precision"
[unit]="displayedCurrency" [unit]="displayedCurrency"
[value]="summary?.grossPerformanceWithCurrencyEffect" [value]="
user?.settings?.isExperimentalFeatures &&
summary?.grossPerformanceWithCurrencyEffect !== null
? summary?.grossPerformanceWithCurrencyEffect -
summary?.dividendInBaseCurrency
: summary?.grossPerformanceWithCurrencyEffect
"
/> />
</div> </div>
</div> </div>
@if (user?.settings?.isExperimentalFeatures) {
<div class="flex-nowrap px-3 py-1 row">
<div class="flex-grow-1 text-truncate" i18n>Dividend</div>
<div class="d-flex justify-content-end">
@if (isNumber(summary?.dividendInBaseCurrency)) {
<span class="mr-1">+</span>
}
<gf-value
class="justify-content-end"
[isCurrency]="true"
[isLoading]="isLoading"
[locale]="locale"
[precision]="precision"
[unit]="displayedCurrency"
[value]="summary?.dividendInBaseCurrency"
/>
</div>
</div>
}
<div class="flex-nowrap px-3 py-1 row"> <div class="flex-nowrap px-3 py-1 row">
<div class="flex-grow-1 text-truncate" i18n>Fees</div> <div class="flex-grow-1 text-truncate" i18n>Fees</div>
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
@if (summary?.fees || summary?.fees === 0) { @if (isNumber(summary?.fees)) {
<span class="mr-1">-</span> <span class="mr-1">-</span>
} }
<gf-value <gf-value
@ -141,7 +166,8 @@
) { ) {
<abbr <abbr
class="d-none d-sm-inline-block initialism ml-2 text-muted" class="d-none d-sm-inline-block initialism ml-2 text-muted"
title="Return on Average Investment" i18n-title
title="Return on Average Investment (total return with dividends)"
>(ROAI)</abbr >(ROAI)</abbr
> >
} }
@ -367,10 +393,7 @@
<div class="flex-nowrap px-3 py-1 row"> <div class="flex-nowrap px-3 py-1 row">
<div class="flex-grow-1 text-truncate" i18n>Liabilities</div> <div class="flex-grow-1 text-truncate" i18n>Liabilities</div>
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
@if ( @if (isNumber(summary?.liabilitiesInBaseCurrency)) {
summary?.liabilitiesInBaseCurrency ||
summary?.liabilitiesInBaseCurrency === 0
) {
<span class="mr-1">-</span> <span class="mr-1">-</span>
} }
<gf-value <gf-value
@ -488,18 +511,20 @@
/> />
</div> </div>
</div> </div>
<div class="flex-nowrap px-3 py-1 row"> @if (!user?.settings?.isExperimentalFeatures) {
<div class="flex-grow-1 text-truncate" i18n>Dividend</div> <div class="flex-nowrap px-3 py-1 row">
<div class="justify-content-end"> <div class="flex-grow-1 text-truncate" i18n>Dividend</div>
<gf-value <div class="justify-content-end">
class="justify-content-end" <gf-value
[isCurrency]="true" class="justify-content-end"
[isLoading]="isLoading" [isCurrency]="true"
[locale]="locale" [isLoading]="isLoading"
[precision]="precision" [locale]="locale"
[unit]="displayedCurrency" [precision]="precision"
[value]="summary?.dividendInBaseCurrency" [unit]="displayedCurrency"
/> [value]="summary?.dividendInBaseCurrency"
/>
</div>
</div> </div>
</div> }
</div> </div>

1
apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts

@ -55,6 +55,7 @@ export class GfPortfolioSummaryComponent implements OnChanges {
'BUY_AND_SELL_ACTIVITIES_TOOLTIP' 'BUY_AND_SELL_ACTIVITIES_TOOLTIP'
); );
protected readonly isNumber = isNumber;
protected readonly PerformanceCalculationType = PerformanceCalculationType; protected readonly PerformanceCalculationType = PerformanceCalculationType;
protected isCashExpanded = false; protected isCashExpanded = false;

4
apps/client/src/app/pages/faq/overview/faq-overview-page.html

@ -52,8 +52,8 @@
calculation method based on the average amount of capital invested calculation method based on the average amount of capital invested
over time. ROAI aims to provide a more insightful view of investment over time. ROAI aims to provide a more insightful view of investment
performance than simpler approaches, especially when contributions are performance than simpler approaches, especially when contributions are
made over time. Dividends are not part of the made over time. Dividends are included in the calculation (total
calculation.</mat-card-content return).</mat-card-content
> >
</mat-card> </mat-card>
<mat-card appearance="outlined" class="mb-3"> <mat-card appearance="outlined" class="mb-3">

97
apps/client/src/app/pages/portfolio/analysis/analysis-page.html

@ -167,7 +167,13 @@
[isLoading]="isLoadingInvestmentChart" [isLoading]="isLoadingInvestmentChart"
[locale]="user?.settings?.locale" [locale]="user?.settings?.locale"
[unit]="user?.settings?.baseCurrency" [unit]="user?.settings?.baseCurrency"
[value]="performance?.netPerformance" [value]="
user?.settings?.isExperimentalFeatures &&
performance?.netPerformance !== null
? performance?.netPerformance -
performance?.dividendInBaseCurrency
: performance?.netPerformance
"
/> />
</div> </div>
</div> </div>
@ -183,10 +189,54 @@
[isLoading]="isLoadingInvestmentChart" [isLoading]="isLoadingInvestmentChart"
[isPercent]="true" [isPercent]="true"
[locale]="user?.settings?.locale" [locale]="user?.settings?.locale"
[value]="performance?.netPerformancePercentage" [value]="
user?.settings?.isExperimentalFeatures
? performance?.netPerformancePercentage -
performance?.dividendPercentage
: performance?.netPerformancePercentage
"
/> />
</div> </div>
</div> </div>
@if (user?.settings?.isExperimentalFeatures) {
<div class="d-flex py-1">
<div
class="align-items-center d-flex flex-grow-1 mr-2 text-truncate"
>
<span i18n>Absolute Dividend Performance</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
}
</div>
<div class="d-flex justify-content-end">
<gf-value
class="justify-content-end"
position="end"
[isCurrency]="true"
[isLoading]="isLoadingInvestmentChart"
[locale]="user?.settings?.locale"
[unit]="user?.settings?.baseCurrency"
[value]="performance?.dividendInBaseCurrency"
/>
</div>
</div>
<div class="d-flex mb-3 ml-3 py-1">
<div class="flex-grow-1 mr-2 text-truncate">
<ng-container i18n>Dividend Performance</ng-container>
</div>
<div class="d-flex justify-content-end">
<gf-value
class="justify-content-end"
position="end"
[colorizeSign]="true"
[isLoading]="isLoadingInvestmentChart"
[isPercent]="true"
[locale]="user?.settings?.locale"
[value]="performance?.dividendPercentage"
/>
</div>
</div>
}
<div class="d-flex py-1"> <div class="d-flex py-1">
<div <div
class="align-items-center d-flex flex-grow-1 mr-2 text-truncate" class="align-items-center d-flex flex-grow-1 mr-2 text-truncate"
@ -260,7 +310,8 @@
) { ) {
<abbr <abbr
class="d-none d-sm-inline-block initialism ml-2 text-muted" class="d-none d-sm-inline-block initialism ml-2 text-muted"
title="Return on Average Investment" i18n-title
title="Return on Average Investment (total return with dividends)"
>(ROAI)</abbr >(ROAI)</abbr
> >
} }
@ -279,46 +330,6 @@
/> />
</div> </div>
</div> </div>
@if (user?.settings?.isExperimentalFeatures) {
<div><hr /></div>
<div class="d-flex py-1">
<div
class="align-items-center d-flex flex-grow-1 mr-2 text-truncate"
>
<span i18n>Absolute Dividend Performance</span>
@if (user?.subscription?.type === 'Basic') {
<gf-premium-indicator class="ml-1" />
}
</div>
<div class="d-flex justify-content-end">
<gf-value
class="justify-content-end"
position="end"
[isCurrency]="true"
[isLoading]="isLoadingInvestmentChart"
[locale]="user?.settings?.locale"
[unit]="user?.settings?.baseCurrency"
[value]="performance?.dividendInBaseCurrency"
/>
</div>
</div>
<div class="d-flex ml-3 py-1">
<div class="flex-grow-1 mr-2 text-truncate">
<ng-container i18n>Dividend Performance</ng-container>
</div>
<div class="d-flex justify-content-end">
<gf-value
class="justify-content-end"
position="end"
[colorizeSign]="true"
[isLoading]="isLoadingInvestmentChart"
[isPercent]="true"
[locale]="user?.settings?.locale"
[value]="performance?.dividendPercentageWithCurrencyEffect"
/>
</div>
</div>
}
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
</div> </div>

1
libs/common/src/lib/interfaces/historical-data-item.interface.ts

@ -2,6 +2,7 @@ export interface HistoricalDataItem {
averagePrice?: number; averagePrice?: number;
date: string; date: string;
dividendInBaseCurrency?: number; dividendInBaseCurrency?: number;
dividendInPercentage?: number;
dividendInPercentageWithCurrencyEffect?: number; dividendInPercentageWithCurrencyEffect?: number;
grossPerformancePercent?: number; grossPerformancePercent?: number;
investmentValueWithCurrencyEffect?: number; investmentValueWithCurrencyEffect?: number;

1
libs/common/src/lib/interfaces/portfolio-performance.interface.ts

@ -3,6 +3,7 @@ export interface PortfolioPerformance {
currentNetWorth?: number; currentNetWorth?: number;
currentValueInBaseCurrency: number; currentValueInBaseCurrency: number;
dividendInBaseCurrency: number; dividendInBaseCurrency: number;
dividendPercentage?: number;
dividendPercentageWithCurrencyEffect?: number; dividendPercentageWithCurrencyEffect?: number;
netPerformance: number; netPerformance: number;
netPerformancePercentage: number; netPerformancePercentage: number;

Loading…
Cancel
Save