diff --git a/CHANGELOG.md b/CHANGELOG.md index a02baea1b..3d86f2c54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Added + +- Broken down the emergency fund by cash and assets + ## 1.290.0 - 2023-07-16 ### Added diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts index 2466e81af..cc3a97752 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts @@ -1,4 +1,4 @@ -import { DataSource, Type as TypeOfOrder } from '@prisma/client'; +import { DataSource, Tag, Type as TypeOfOrder } from '@prisma/client'; import Big from 'big.js'; export interface PortfolioOrder { @@ -9,6 +9,7 @@ export interface PortfolioOrder { name: string; quantity: Big; symbol: string; + tags?: Tag[]; type: TypeOfOrder; unitPrice: Big; } diff --git a/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts b/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts index cc199119e..5350adccc 100644 --- a/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts @@ -1,4 +1,4 @@ -import { DataSource } from '@prisma/client'; +import { DataSource, Tag } from '@prisma/client'; import Big from 'big.js'; export interface TransactionPointSymbol { @@ -9,5 +9,6 @@ export interface TransactionPointSymbol { investment: Big; quantity: Big; symbol: string; + tags?: Tag[]; transactionCount: number; } diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index 9addb29dd..cf6d1b156 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -114,6 +114,7 @@ export class PortfolioCalculator { firstBuyDate: oldAccumulatedSymbol.firstBuyDate, quantity: newQuantity, symbol: order.symbol, + tags: order.tags, transactionCount: oldAccumulatedSymbol.transactionCount + 1 }; } else { @@ -125,6 +126,7 @@ export class PortfolioCalculator { investment: unitPrice.mul(order.quantity).mul(factor), quantity: order.quantity.mul(factor), symbol: order.symbol, + tags: order.tags, transactionCount: 1 }; } @@ -492,6 +494,7 @@ export class PortfolioCalculator { : null, quantity: item.quantity, symbol: item.symbol, + tags: item.tags, transactionCount: item.transactionCount }); diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 0d9afea51..6a8102501 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -161,10 +161,12 @@ export class PortfolioController { 'emergencyFund', 'excludedAccountsAndActivities', 'fees', + 'fireWealth', 'items', 'liabilities', 'netWorth', 'totalBuy', + 'totalInvestment', 'totalSell' ]); } diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 4bc1c7b15..29cdbe66f 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -583,6 +583,7 @@ export class PortfolioService { quantity: item.quantity.toNumber(), sectors: symbolProfile.sectors, symbol: item.symbol, + tags: item.tags, transactionCount: item.transactionCount, url: symbolProfile.url, valueInBaseCurrency: value.toNumber() @@ -628,7 +629,7 @@ export class PortfolioService { const emergencyFundInCash = emergencyFund .minus( this.getEmergencyFundPositionsValueInBaseCurrency({ - activities: orders + holdings }) ) .toNumber(); @@ -656,7 +657,7 @@ export class PortfolioService { balanceInBaseCurrency: cashDetails.balanceInBaseCurrency, emergencyFundPositionsValueInBaseCurrency: this.getEmergencyFundPositionsValueInBaseCurrency({ - activities: orders + holdings }) }); @@ -742,6 +743,7 @@ export class PortfolioService { name: order.SymbolProfile?.name, quantity: new Big(order.quantity), symbol: order.SymbolProfile.symbol, + tags: order.tags, type: order.type, unitPrice: new Big(order.unitPrice) })); @@ -1392,13 +1394,13 @@ export class PortfolioService { } private getEmergencyFundPositionsValueInBaseCurrency({ - activities + holdings }: { - activities: Activity[]; + holdings: PortfolioDetails['holdings']; }) { - const emergencyFundOrders = activities.filter((activity) => { + const emergencyFundHoldings = Object.values(holdings).filter(({ tags }) => { return ( - activity.tags?.some(({ id }) => { + tags?.some(({ id }) => { return id === EMERGENCY_FUND_TAG_ID; }) ?? false ); @@ -1406,18 +1408,9 @@ export class PortfolioService { let valueInBaseCurrencyOfEmergencyFundPositions = new Big(0); - for (const order of emergencyFundOrders) { - if (order.type === 'BUY') { - valueInBaseCurrencyOfEmergencyFundPositions = - valueInBaseCurrencyOfEmergencyFundPositions.plus( - order.valueInBaseCurrency - ); - } else if (order.type === 'SELL') { - valueInBaseCurrencyOfEmergencyFundPositions = - valueInBaseCurrencyOfEmergencyFundPositions.minus( - order.valueInBaseCurrency - ); - } + for (const { value } of emergencyFundHoldings) { + valueInBaseCurrencyOfEmergencyFundPositions = + valueInBaseCurrencyOfEmergencyFundPositions.plus(value); } return valueInBaseCurrencyOfEmergencyFundPositions.toNumber(); @@ -1476,6 +1469,7 @@ export class PortfolioService { quantity: 0, sectors: [], symbol: currency, + tags: [], transactionCount: 0, valueInBaseCurrency: balance }; @@ -1687,7 +1681,16 @@ export class PortfolioService { totalBuy, totalSell, committedFunds: committedFunds.toNumber(), - emergencyFund: emergencyFund.toNumber(), + emergencyFund: { + assets: emergencyFundPositionsValueInBaseCurrency, + cash: emergencyFund + .minus(emergencyFundPositionsValueInBaseCurrency) + .toNumber(), + total: emergencyFund.toNumber() + }, + fireWealth: new Big(performanceInformation.performance.currentValue) + .minus(emergencyFundPositionsValueInBaseCurrency) + .toNumber(), ordersCount: activities.filter(({ type }) => { return type === 'BUY' || type === 'SELL'; }).length @@ -1739,6 +1742,7 @@ export class PortfolioService { name: order.SymbolProfile?.name, quantity: new Big(order.quantity), symbol: order.SymbolProfile.symbol, + tags: order.tags, type: order.type, unitPrice: new Big( this.exchangeRateDataService.toCurrency( 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 3ceadb048..81c25bf75 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 @@ -163,7 +163,33 @@ [isCurrency]="true" [locale]="locale" [unit]="baseCurrency" - [value]="isLoading ? undefined : summary?.emergencyFund" + [value]="isLoading ? undefined : summary?.emergencyFund?.total" + > + + +
+
Cash
+
+ +
+
+
+
Assets
+
+
diff --git a/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts b/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts index f5d796f54..ab632b2e8 100644 --- a/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts +++ b/apps/client/src/app/pages/portfolio/fire/fire-page.component.ts @@ -51,7 +51,7 @@ export class FirePageComponent implements OnDestroy, OnInit { return; } - this.fireWealth = new Big(summary.currentValue); + this.fireWealth = new Big(summary.fireWealth); this.withdrawalRatePerYear = this.fireWealth.mul(4).div(100); this.withdrawalRatePerMonth = this.withdrawalRatePerYear.div(12); diff --git a/libs/common/src/lib/interfaces/portfolio-position.interface.ts b/libs/common/src/lib/interfaces/portfolio-position.interface.ts index 81ac0b7ad..a398c8c90 100644 --- a/libs/common/src/lib/interfaces/portfolio-position.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-position.interface.ts @@ -1,4 +1,4 @@ -import { AssetClass, AssetSubClass, DataSource } from '@prisma/client'; +import { AssetClass, AssetSubClass, DataSource, Tag } from '@prisma/client'; import { Market, MarketState } from '../types'; import { Country } from './country.interface'; @@ -26,8 +26,9 @@ export interface PortfolioPosition { netPerformancePercent: number; quantity: number; sectors: Sector[]; - transactionCount: number; symbol: string; + tags?: Tag[]; + transactionCount: number; type?: string; url?: string; valueInBaseCurrency?: number; diff --git a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts index c520da9fb..95ce2958a 100644 --- a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts @@ -5,9 +5,14 @@ export interface PortfolioSummary extends PortfolioPerformance { cash: number; committedFunds: number; dividend: number; - emergencyFund: number; + emergencyFund: { + assets: number; + cash: number; + total: number; + }; excludedAccountsAndActivities: number; fees: number; + fireWealth: number; firstOrderDate: Date; items: number; liabilities: number; diff --git a/libs/common/src/lib/interfaces/timeline-position.interface.ts b/libs/common/src/lib/interfaces/timeline-position.interface.ts index beb13a352..de4c3ff19 100644 --- a/libs/common/src/lib/interfaces/timeline-position.interface.ts +++ b/libs/common/src/lib/interfaces/timeline-position.interface.ts @@ -1,4 +1,4 @@ -import { DataSource } from '@prisma/client'; +import { DataSource, Tag } from '@prisma/client'; import Big from 'big.js'; export interface TimelinePosition { @@ -15,5 +15,6 @@ export interface TimelinePosition { netPerformancePercentage: Big; quantity: Big; symbol: string; + tags?: Tag[]; transactionCount: number; }