diff --git a/CHANGELOG.md b/CHANGELOG.md index a02baea1..3d86f2c5 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 2466e81a..cc3a9775 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 cc199119..5350adcc 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 9addb29d..cf6d1b15 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 0d9afea5..6a810250 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 4bc1c7b1..29cdbe66 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 3ceadb04..81c25bf7 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" + > + + +