diff --git a/README.md b/README.md index b9352e3bd3..142d3199cc 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Ghostfolio is for you if you are... - ✅ Create, update and delete transactions - ✅ Multi account management -- ✅ Portfolio performance: Return on Average Investment (ROAI) for `Today`, `WTD`, `MTD`, `YTD`, `1Y`, `5Y`, `Max` +- ✅ Portfolio performance: Return on Average Investment (ROAI) including dividends (total return) for `Today`, `WTD`, `MTD`, `YTD`, `1Y`, `5Y`, `Max` - ✅ Various charts - ✅ Static analysis to identify potential risks in your portfolio - ✅ Import and export transactions diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index e03b530258..9c5f1a26e3 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/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 currentValues: { [date: string]: Big } = {}; const currentValuesWithCurrencyEffect: { [date: string]: Big } = {}; + let dividends = new Big(0); let fees = new Big(0); let feesAtStartDate = new Big(0); let feesAtStartDateWithCurrencyEffect = new Big(0); @@ -1188,14 +1189,26 @@ export abstract class PortfolioCalculator { ); } + 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) + ); + } + const newGrossPerformance = valueOfInvestment .minus(totalInvestment) - .plus(grossPerformanceFromSells); + .plus(grossPerformanceFromSells) + .plus(dividends); const newGrossPerformanceWithCurrencyEffect = valueOfInvestmentWithCurrencyEffect .minus(totalInvestmentWithCurrencyEffect) - .plus(grossPerformanceFromSellsWithCurrencyEffect); + .plus(grossPerformanceFromSellsWithCurrencyEffect) + .plus(dividends); grossPerformance = newGrossPerformance; diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-with-dividend.spec.ts index 2c6ff79b6d..151a2a914c 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -155,25 +155,25 @@ describe('PortfolioCalculator', () => { '0.001144362748184' ), fee: new Big('19'), - grossPerformance: new Big('33.25'), - grossPerformancePercentage: new Big('0.11136043941322258691'), + grossPerformance: new Big('33.87'), + grossPerformancePercentage: new Big('0.11343693482483756447'), grossPerformancePercentageWithCurrencyEffect: new Big( - '0.11136043941322258691' + '0.11343693482483756447' ), - grossPerformanceWithCurrencyEffect: new Big('33.25'), + grossPerformanceWithCurrencyEffect: new Big('33.87'), investment: new Big('298.58'), investmentWithCurrencyEffect: new Big('298.58'), marketPrice: 331.83, marketPriceInBaseCurrency: 331.83, - netPerformance: new Big('14.25'), - netPerformancePercentage: new Big('0.04772590260566682296'), + netPerformance: new Big('14.87'), + netPerformancePercentage: new Big('0.04980239801728180052'), netPerformancePercentageWithCurrencyEffectMap: { - max: new Big('0.04772590260566682296') + max: new Big('0.04980239801728180052') }, netPerformanceWithCurrencyEffectMap: { '1d': new Big('-5.39'), - '5y': new Big('14.25'), - max: new Big('14.25'), + '5y': new Big('14.87'), + max: new Big('14.87'), wtd: new Big('-5.39') }, quantity: new Big('1'), @@ -200,10 +200,10 @@ describe('PortfolioCalculator', () => { date: '2023-07-10', dividendInBaseCurrency: 0, dividendInPercentageWithCurrencyEffect: 0, - netPerformance: -5.390000000000001, - netPerformanceInPercentage: -0.015983630864124312, - netPerformanceInPercentageWithCurrencyEffect: -0.015983630864124312, - netPerformanceWithCurrencyEffect: -5.390000000000001, + netPerformance: -5.390000000000002, + netPerformanceInPercentage: -0.015983630864124316, + netPerformanceInPercentageWithCurrencyEffect: -0.015983630864124316, + netPerformanceWithCurrencyEffect: -5.390000000000002, totalInvestmentValueWithCurrencyEffect: 298.58, valueWithCurrencyEffect: 331.83 }, @@ -211,10 +211,10 @@ describe('PortfolioCalculator', () => { date: '2023-07-10', dividendInBaseCurrency: 0.62, dividendInPercentageWithCurrencyEffect: 0.002076495411614967, - netPerformance: 14.25, - netPerformanceInPercentage: 0.04772590260566659, - netPerformanceInPercentageWithCurrencyEffect: 0.04772590260566659, - netPerformanceWithCurrencyEffect: 14.25, + netPerformance: 14.87, + netPerformanceInPercentage: 0.049802398017281556, + netPerformanceInPercentageWithCurrencyEffect: 0.049802398017281556, + netPerformanceWithCurrencyEffect: 14.87, totalInvestmentValueWithCurrencyEffect: 298.58, valueWithCurrencyEffect: 331.83 }, @@ -222,10 +222,10 @@ describe('PortfolioCalculator', () => { date: '2023-07-10', dividendInBaseCurrency: 0, dividendInPercentageWithCurrencyEffect: 0, - netPerformance: -7.68, - netPerformanceInPercentage: -0.022620835910577012, - netPerformanceInPercentageWithCurrencyEffect: -0.022620835910577012, - netPerformanceWithCurrencyEffect: -7.68, + netPerformance: -7.6800000000000015, + netPerformanceInPercentage: -0.022620835910577015, + netPerformanceInPercentageWithCurrencyEffect: -0.022620835910577015, + netPerformanceWithCurrencyEffect: -7.6800000000000015, totalInvestmentValueWithCurrencyEffect: 298.58, valueWithCurrencyEffect: 331.83 } diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html index 0a0beba910..0ed3b0527a 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html @@ -98,25 +98,20 @@ /> - @if (user?.settings?.isExperimentalFeatures) { -