|
|
|
@ -2,7 +2,7 @@ import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/po |
|
|
|
import { PortfolioOrderItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order-item.interface'; |
|
|
|
import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; |
|
|
|
import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper'; |
|
|
|
import { DATE_FORMAT } from '@ghostfolio/common/helper'; |
|
|
|
import { DATE_FORMAT, getSum } from '@ghostfolio/common/helper'; |
|
|
|
import { |
|
|
|
AssetProfileIdentifier, |
|
|
|
SymbolMetrics |
|
|
|
@ -236,6 +236,36 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
// The dividends, the interest and the liabilities are derived from the
|
|
|
|
// activities only. Accumulate them upfront so that they survive the bail
|
|
|
|
// out for symbols without a market price below.
|
|
|
|
for (const order of orders) { |
|
|
|
const exchangeRateAtOrderDate = exchangeRates[order.date]; |
|
|
|
|
|
|
|
if (order.type === 'DIVIDEND') { |
|
|
|
const dividend = order.quantity.mul(order.unitPrice); |
|
|
|
|
|
|
|
totalDividend = totalDividend.plus(dividend); |
|
|
|
totalDividendInBaseCurrency = totalDividendInBaseCurrency.plus( |
|
|
|
dividend.mul(exchangeRateAtOrderDate ?? 1) |
|
|
|
); |
|
|
|
} else if (order.type === 'INTEREST') { |
|
|
|
const interest = order.quantity.mul(order.unitPrice); |
|
|
|
|
|
|
|
totalInterest = totalInterest.plus(interest); |
|
|
|
totalInterestInBaseCurrency = totalInterestInBaseCurrency.plus( |
|
|
|
interest.mul(exchangeRateAtOrderDate ?? 1) |
|
|
|
); |
|
|
|
} else if (order.type === 'LIABILITY') { |
|
|
|
const liabilities = order.quantity.mul(order.unitPrice); |
|
|
|
|
|
|
|
totalLiabilities = totalLiabilities.plus(liabilities); |
|
|
|
totalLiabilitiesInBaseCurrency = totalLiabilitiesInBaseCurrency.plus( |
|
|
|
liabilities.mul(exchangeRateAtOrderDate ?? 1) |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const dateOfFirstTransaction = new Date(orders[0].date); |
|
|
|
|
|
|
|
const endDateString = format(end, DATE_FORMAT); |
|
|
|
@ -263,7 +293,22 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
|
!unitPriceAtEndDate || |
|
|
|
(!unitPriceAtStartDate && isBefore(dateOfFirstTransaction, start)) |
|
|
|
) { |
|
|
|
// A missing market price can only affect the units which are held. The
|
|
|
|
// dividends, the interest and the liabilities do not hold any units and
|
|
|
|
// are therefore not in error.
|
|
|
|
const totalUnitsOfActivities = getSum( |
|
|
|
orders.map(({ quantity, type }) => { |
|
|
|
return quantity.mul(getFactor(type)); |
|
|
|
}) |
|
|
|
); |
|
|
|
|
|
|
|
return { |
|
|
|
totalDividend, |
|
|
|
totalDividendInBaseCurrency, |
|
|
|
totalInterest, |
|
|
|
totalInterestInBaseCurrency, |
|
|
|
totalLiabilities, |
|
|
|
totalLiabilitiesInBaseCurrency, |
|
|
|
currentValues: {}, |
|
|
|
currentValuesWithCurrencyEffect: {}, |
|
|
|
feesWithCurrencyEffect: new Big(0), |
|
|
|
@ -271,7 +316,7 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
|
grossPerformancePercentage: new Big(0), |
|
|
|
grossPerformancePercentageWithCurrencyEffect: new Big(0), |
|
|
|
grossPerformanceWithCurrencyEffect: new Big(0), |
|
|
|
hasErrors: true, |
|
|
|
hasErrors: totalUnitsOfActivities.gt(0), |
|
|
|
initialValue: new Big(0), |
|
|
|
initialValueWithCurrencyEffect: new Big(0), |
|
|
|
investmentValuesAccumulated: {}, |
|
|
|
@ -288,14 +333,8 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
|
timeWeightedInvestmentValuesWithCurrencyEffect: {}, |
|
|
|
timeWeightedInvestmentWithCurrencyEffect: new Big(0), |
|
|
|
totalAccountBalanceInBaseCurrency: new Big(0), |
|
|
|
totalDividend: new Big(0), |
|
|
|
totalDividendInBaseCurrency: new Big(0), |
|
|
|
totalInterest: new Big(0), |
|
|
|
totalInterestInBaseCurrency: new Big(0), |
|
|
|
totalInvestment: new Big(0), |
|
|
|
totalInvestmentWithCurrencyEffect: new Big(0), |
|
|
|
totalLiabilities: new Big(0), |
|
|
|
totalLiabilitiesInBaseCurrency: new Big(0) |
|
|
|
totalInvestmentWithCurrencyEffect: new Big(0) |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
@ -415,29 +454,6 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { |
|
|
|
|
|
|
|
const exchangeRateAtOrderDate = exchangeRates[order.date]; |
|
|
|
|
|
|
|
if (order.type === 'DIVIDEND') { |
|
|
|
const dividend = order.quantity.mul(order.unitPrice); |
|
|
|
|
|
|
|
totalDividend = totalDividend.plus(dividend); |
|
|
|
totalDividendInBaseCurrency = totalDividendInBaseCurrency.plus( |
|
|
|
dividend.mul(exchangeRateAtOrderDate ?? 1) |
|
|
|
); |
|
|
|
} else if (order.type === 'INTEREST') { |
|
|
|
const interest = order.quantity.mul(order.unitPrice); |
|
|
|
|
|
|
|
totalInterest = totalInterest.plus(interest); |
|
|
|
totalInterestInBaseCurrency = totalInterestInBaseCurrency.plus( |
|
|
|
interest.mul(exchangeRateAtOrderDate ?? 1) |
|
|
|
); |
|
|
|
} else if (order.type === 'LIABILITY') { |
|
|
|
const liabilities = order.quantity.mul(order.unitPrice); |
|
|
|
|
|
|
|
totalLiabilities = totalLiabilities.plus(liabilities); |
|
|
|
totalLiabilitiesInBaseCurrency = totalLiabilitiesInBaseCurrency.plus( |
|
|
|
liabilities.mul(exchangeRateAtOrderDate ?? 1) |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
if (order.itemType === 'start') { |
|
|
|
// Take the unit price of the order as the market price if there are no
|
|
|
|
// orders of this symbol before the start date
|
|
|
|
|