|
|
@ -1,9 +1,9 @@ |
|
|
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; |
|
|
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; |
|
|
import { AccumulatedValues } from '@ghostfolio/api/app/portfolio/interfaces/accumulated-values.interface'; |
|
|
import { AccumulatedValues } from '@ghostfolio/api/app/portfolio/interfaces/accumulated-values.interface'; |
|
|
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface'; |
|
|
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface'; |
|
|
import { NetPerformancePercentages } from '@ghostfolio/api/app/portfolio/interfaces/net-performance-percentages.interface'; |
|
|
|
|
|
import { PortfolioCalculatorActivityItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-activity-item.interface'; |
|
|
import { PortfolioCalculatorActivityItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-activity-item.interface'; |
|
|
import { PortfolioCalculatorHolding } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-holding.interface'; |
|
|
import { PortfolioCalculatorHolding } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-holding.interface'; |
|
|
|
|
|
import { NetPerformancePercentages } from '@ghostfolio/api/app/portfolio/types/net-performance-percentages.type'; |
|
|
import { |
|
|
import { |
|
|
getAnnualizedPerformancePercent, |
|
|
getAnnualizedPerformancePercent, |
|
|
getIntervalFromDateRange |
|
|
getIntervalFromDateRange |
|
|
@ -29,7 +29,7 @@ import { |
|
|
isBefore, |
|
|
isBefore, |
|
|
isThisYear |
|
|
isThisYear |
|
|
} from 'date-fns'; |
|
|
} from 'date-fns'; |
|
|
import { isNumber, sum } from 'lodash'; |
|
|
import { sum } from 'lodash'; |
|
|
|
|
|
|
|
|
export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
protected calculateNetPerformancePercentages({ |
|
|
protected calculateNetPerformancePercentages({ |
|
|
@ -82,8 +82,10 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
[date: string]: NetPerformancePercentages; |
|
|
[date: string]: NetPerformancePercentages; |
|
|
} = {}; |
|
|
} = {}; |
|
|
|
|
|
|
|
|
for (const historicalDataItem of historicalDataItems) { |
|
|
for (const [index, historicalDataItem] of historicalDataItems.entries()) { |
|
|
if (!isNumber(grossPerformanceAtStartDate)) { |
|
|
// Take the values at the start date from the first day of the date
|
|
|
|
|
|
// range
|
|
|
|
|
|
if (index === 0) { |
|
|
grossPerformanceAtStartDate = |
|
|
grossPerformanceAtStartDate = |
|
|
historicalDataItem.value - historicalDataItem.totalInvestment; |
|
|
historicalDataItem.value - historicalDataItem.totalInvestment; |
|
|
|
|
|
|
|
|
@ -142,7 +144,6 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
let hasErrors = false; |
|
|
let hasErrors = false; |
|
|
let totalAverageInvestment = new Big(0); |
|
|
let totalAverageInvestment = new Big(0); |
|
|
let totalAverageInvestmentWithCurrencyEffect = new Big(0); |
|
|
let totalAverageInvestmentWithCurrencyEffect = new Big(0); |
|
|
let totalDividendInBaseCurrency = new Big(0); |
|
|
|
|
|
let totalFeesWithCurrencyEffect = new Big(0); |
|
|
let totalFeesWithCurrencyEffect = new Big(0); |
|
|
const totalInterestWithCurrencyEffect = new Big(0); |
|
|
const totalInterestWithCurrencyEffect = new Big(0); |
|
|
let totalInvestment = new Big(0); |
|
|
let totalInvestment = new Big(0); |
|
|
@ -161,12 +162,6 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (currentPosition.dividendInBaseCurrency) { |
|
|
|
|
|
totalDividendInBaseCurrency = totalDividendInBaseCurrency.plus( |
|
|
|
|
|
currentPosition.dividendInBaseCurrency |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (currentPosition.feeInBaseCurrency) { |
|
|
if (currentPosition.feeInBaseCurrency) { |
|
|
totalFeesWithCurrencyEffect = totalFeesWithCurrencyEffect.plus( |
|
|
totalFeesWithCurrencyEffect = totalFeesWithCurrencyEffect.plus( |
|
|
currentPosition.feeInBaseCurrency |
|
|
currentPosition.feeInBaseCurrency |
|
|
@ -215,9 +210,28 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
? differenceInDays(new Date(), dateOfFirstActivity) |
|
|
? differenceInDays(new Date(), dateOfFirstActivity) |
|
|
: 0; |
|
|
: 0; |
|
|
|
|
|
|
|
|
|
|
|
// Take the dividend from the same source as the portfolio summary, so
|
|
|
|
|
|
// that the response shows one dividend only
|
|
|
|
|
|
const totalDividendInBaseCurrency = |
|
|
|
|
|
this.getDividendInBaseCurrencyOfHoldings(positions); |
|
|
|
|
|
|
|
|
|
|
|
// A holding without a market price, and a holding which is excluded from
|
|
|
|
|
|
// the performance, gives a dividend but no average investment. Such a
|
|
|
|
|
|
// holding makes the dividend yield too high. Therefore the dividend yield
|
|
|
|
|
|
// stays 0 in this case.
|
|
|
|
|
|
const hasDividendWithoutAverageInvestment = positions.some( |
|
|
|
|
|
({ averageInvestment, dividendInBaseCurrency, includeInPerformance }) => { |
|
|
|
|
|
return ( |
|
|
|
|
|
!dividendInBaseCurrency.eq(0) && |
|
|
|
|
|
(!includeInPerformance || averageInvestment.eq(0)) |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
const dividendYieldPercent = getAnnualizedPerformancePercent({ |
|
|
const dividendYieldPercent = getAnnualizedPerformancePercent({ |
|
|
daysInMarket, |
|
|
daysInMarket, |
|
|
netPerformancePercentage: totalAverageInvestment.eq(0) |
|
|
netPerformancePercentage: |
|
|
|
|
|
hasDividendWithoutAverageInvestment || totalAverageInvestment.eq(0) |
|
|
? new Big(0) |
|
|
? new Big(0) |
|
|
: totalDividendInBaseCurrency.div(totalAverageInvestment) |
|
|
: totalDividendInBaseCurrency.div(totalAverageInvestment) |
|
|
}); |
|
|
}); |
|
|
@ -225,7 +239,9 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
const dividendYieldPercentWithCurrencyEffect = |
|
|
const dividendYieldPercentWithCurrencyEffect = |
|
|
getAnnualizedPerformancePercent({ |
|
|
getAnnualizedPerformancePercent({ |
|
|
daysInMarket, |
|
|
daysInMarket, |
|
|
netPerformancePercentage: totalAverageInvestmentWithCurrencyEffect.eq(0) |
|
|
netPerformancePercentage: |
|
|
|
|
|
hasDividendWithoutAverageInvestment || |
|
|
|
|
|
totalAverageInvestmentWithCurrencyEffect.eq(0) |
|
|
? new Big(0) |
|
|
? new Big(0) |
|
|
: totalDividendInBaseCurrency.div( |
|
|
: totalDividendInBaseCurrency.div( |
|
|
totalAverageInvestmentWithCurrencyEffect |
|
|
totalAverageInvestmentWithCurrencyEffect |
|
|
|