diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 87a0cab3c..b70bb67f5 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -138,6 +138,7 @@ export abstract class PortfolioCalculator { netPerformanceWithCurrencyEffect: new Big(0), positions: [], totalFeesWithCurrencyEffect: new Big(0), + totalInterestWithCurrencyEffect: new Big(0), totalInvestment: new Big(0), totalInvestmentWithCurrencyEffect: new Big(0) }; @@ -260,7 +261,6 @@ export abstract class PortfolioCalculator { ); const { - feesWithCurrencyEffect, grossPerformance, grossPerformancePercentage, grossPerformancePercentageWithCurrencyEffect, @@ -350,7 +350,8 @@ export abstract class PortfolioCalculator { ...overall, errors, positions, - hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors + hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors, + totalInterestWithCurrencyEffect: lastTransactionPoint.interest }; } @@ -668,6 +669,12 @@ export abstract class PortfolioCalculator { return this.snapshot.totalFeesWithCurrencyEffect; } + public async getInterestInBaseCurrency() { + await this.snapshotPromise; + + return this.snapshot.totalInterestWithCurrencyEffect; + } + public getInvestments(): { date: string; investment: Big }[] { if (this.transactionPoints.length === 0) { return []; @@ -761,7 +768,7 @@ export abstract class PortfolioCalculator { unitPrice } of this.orders) { if ( - [/*'DIVIDEND', 'FEE',*/ 'INTEREST', 'ITEM', 'LIABILITY'].includes(type) + [/*'DIVIDEND', 'FEE', 'INTEREST',*/ 'ITEM', 'LIABILITY'].includes(type) ) { continue; } @@ -844,16 +851,25 @@ export abstract class PortfolioCalculator { fees = fee; } + let interest = new Big(0); + + if (type === 'INTEREST') { + interest = quantity.mul(unitPrice); + } + if (lastDate !== date || lastTransactionPoint === null) { lastTransactionPoint = { date, fees, + interest, items: newItems }; this.transactionPoints.push(lastTransactionPoint); } else { lastTransactionPoint.fees = lastTransactionPoint.fees.plus(fees); + lastTransactionPoint.interest = + lastTransactionPoint.interest.plus(interest); lastTransactionPoint.items = newItems; } diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index 35f7fbcc5..8ddae9df6 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -174,6 +174,7 @@ describe('PortfolioCalculator', () => { } ], totalFeesWithCurrencyEffect: new Big('3.2'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), totalInvestmentWithCurrencyEffect: new Big('0') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts index 95fe27347..febd1769d 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -157,6 +157,7 @@ describe('PortfolioCalculator', () => { } ], totalFeesWithCurrencyEffect: new Big('3.2'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), totalInvestmentWithCurrencyEffect: new Big('0') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts index efb53100f..2b9fd06f0 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts @@ -142,6 +142,7 @@ describe('PortfolioCalculator', () => { } ], totalFeesWithCurrencyEffect: new Big('1.55'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('273.2'), totalInvestmentWithCurrencyEffect: new Big('273.2') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index 4a9887e4e..ceff92449 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -176,6 +176,7 @@ describe('PortfolioCalculator', () => { } ], totalFeesWithCurrencyEffect: new Big('0'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('320.43'), totalInvestmentWithCurrencyEffect: new Big('318.542667299999967957') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts index b4a108381..b689a0c30 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts @@ -123,6 +123,7 @@ describe('PortfolioCalculator', () => { } ], totalFeesWithCurrencyEffect: new Big('49'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), totalInvestmentWithCurrencyEffect: new Big('0') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts index ffcf85b95..911167f7a 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts @@ -155,6 +155,7 @@ describe('PortfolioCalculator', () => { } ], totalFeesWithCurrencyEffect: new Big('1'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('89.12'), totalInvestmentWithCurrencyEffect: new Big('82.329056') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts index c05af223b..6dc489c5d 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -131,6 +131,7 @@ describe('PortfolioCalculator', () => { } ], totalFeesWithCurrencyEffect: new Big('19'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('298.58'), totalInvestmentWithCurrencyEffect: new Big('298.58') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts index e165e8aac..ece39c87b 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts @@ -81,6 +81,7 @@ describe('PortfolioCalculator', () => { netPerformanceWithCurrencyEffect: new Big(0), positions: [], totalFeesWithCurrencyEffect: new Big('0'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big(0), totalInvestmentWithCurrencyEffect: new Big(0) }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index 878e856f2..a3c12829a 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -159,6 +159,7 @@ describe('PortfolioCalculator', () => { } ], totalFeesWithCurrencyEffect: new Big('4.25'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('75.80'), totalInvestmentWithCurrencyEffect: new Big('75.80') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index 0efec77c0..f1bf56f11 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -183,6 +183,7 @@ describe('PortfolioCalculator', () => { } ], totalFeesWithCurrencyEffect: new Big('0'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), totalInvestmentWithCurrencyEffect: new Big('0') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 30b15b98d..b9b7fd900 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -31,6 +31,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { let netPerformance = new Big(0); let netPerformanceWithCurrencyEffect = new Big(0); let totalFeesWithCurrencyEffect = new Big(0); + let totalInterestWithCurrencyEffect = new Big(0); let totalInvestment = new Big(0); let totalInvestmentWithCurrencyEffect = new Big(0); let totalTimeWeightedInvestment = new Big(0); @@ -109,6 +110,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { netPerformance, netPerformanceWithCurrencyEffect, totalFeesWithCurrencyEffect, + totalInterestWithCurrencyEffect, totalInvestment, totalInvestmentWithCurrencyEffect, netPerformancePercentage: totalTimeWeightedInvestment.eq(0) @@ -186,6 +188,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { let totalDividend = new Big(0); let totalDividendInBaseCurrency = new Big(0); + let totalInterest = new Big(0); + let totalInterestInBaseCurrency = new Big(0); let totalInvestment = new Big(0); let totalInvestmentFromBuyTransactions = new Big(0); let totalInvestmentFromBuyTransactionsWithCurrencyEffect = new Big(0); @@ -229,6 +233,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { timeWeightedInvestmentWithCurrencyEffect: 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) }; @@ -272,6 +278,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { timeWeightedInvestmentWithCurrencyEffect: 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) }; @@ -521,6 +529,13 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { 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) + ); } const valueOfInvestment = totalUnits.mul(order.unitPriceInBaseCurrency); @@ -834,6 +849,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { timeWeightedInvestmentValuesWithCurrencyEffect, totalDividend, totalDividendInBaseCurrency, + totalInterest, + totalInterestInBaseCurrency, totalInvestment, totalInvestmentWithCurrencyEffect, grossPerformance: totalGrossPerformance, diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts index 37573e3bb..b8cc904fa 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts @@ -16,6 +16,7 @@ export interface PortfolioSnapshot extends ResponseError { netPerformancePercentageWithCurrencyEffect: Big; positions: TimelinePosition[]; totalFeesWithCurrencyEffect: Big; + totalInterestWithCurrencyEffect: Big; totalInvestment: Big; totalInvestmentWithCurrencyEffect: Big; } diff --git a/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts b/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts index f2645fbfd..2f5218405 100644 --- a/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts @@ -5,5 +5,6 @@ import { TransactionPointSymbol } from './transaction-point-symbol.interface'; export interface TransactionPoint { date: string; fees: Big; + interest: Big; items: TransactionPointSymbol[]; } diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 6353b033e..7839e1bfa 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1621,14 +1621,7 @@ export class PortfolioService { const firstOrderDate = portfolioCalculator.getStartDate(); - // TODO - const interest = this.getSumOfActivityType({ - activities, - userCurrency, - activityType: 'INTEREST' - }).toNumber(); - - console.log(interest); + const interest = await portfolioCalculator.getInterestInBaseCurrency(); // TODO const items = getSum( @@ -1737,7 +1730,6 @@ export class PortfolioService { cash, excludedAccountsAndActivities, firstOrderDate, - interest, items, liabilities, totalBuy, @@ -1759,6 +1751,7 @@ export class PortfolioService { fireWealth: new Big(performanceInformation.performance.currentValue) .minus(emergencyFundPositionsValueInBaseCurrency) .toNumber(), + interest: interest.toNumber(), ordersCount: activities.filter(({ type }) => { return type === 'BUY' || type === 'SELL'; }).length, diff --git a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts index efe757bf9..99a1b3467 100644 --- a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts +++ b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts @@ -42,6 +42,8 @@ export interface SymbolMetrics { timeWeightedInvestmentWithCurrencyEffect: Big; totalDividend: Big; totalDividendInBaseCurrency: Big; + totalInterest: Big; + totalInterestInBaseCurrency: Big; totalInvestment: Big; totalInvestmentWithCurrencyEffect: Big; }