Feature/remove emergency fund as asset class (#1615)

* Remove emergency fund as asset class

* Update changelog
pull/1616/head
Thomas Kaul 2 years ago committed by GitHub
parent f47e4d3b04
commit 7fa6eda45d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improved the date formatting in the tooltip of the dividend timeline grouped by month / year - Improved the date formatting in the tooltip of the dividend timeline grouped by month / year
- Improved the date formatting in the tooltip of the investment timeline grouped by month / year - Improved the date formatting in the tooltip of the investment timeline grouped by month / year
- Reduced the execution interval of the data gathering to every 4 hours - Reduced the execution interval of the data gathering to every 4 hours
- Removed emergency fund as an asset class
## 1.227.1 - 2023-01-14 ## 1.227.1 - 2023-01-14

@ -20,7 +20,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { ImpersonationService } from '@ghostfolio/api/services/impersonation.service'; import { ImpersonationService } from '@ghostfolio/api/services/impersonation.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
import { import {
ASSET_SUB_CLASS_EMERGENCY_FUND, EMERGENCY_FUND_TAG_ID,
MAX_CHART_ITEMS, MAX_CHART_ITEMS,
UNKNOWN_KEY UNKNOWN_KEY
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
@ -575,7 +575,6 @@ export class PortfolioService {
) { ) {
const cashPositions = await this.getCashPositions({ const cashPositions = await this.getCashPositions({
cashDetails, cashDetails,
emergencyFund,
userCurrency, userCurrency,
investment: totalInvestmentInBaseCurrency, investment: totalInvestmentInBaseCurrency,
value: filteredValueInBaseCurrency value: filteredValueInBaseCurrency
@ -595,6 +594,41 @@ export class PortfolioService {
withExcludedAccounts withExcludedAccounts
}); });
if (
filters?.length === 1 &&
filters[0].id === 'EMERGENCY_FUND_TAG_ID' &&
filters[0].type === 'TAG'
) {
const cashPositions = await this.getCashPositions({
cashDetails,
userCurrency,
investment: totalInvestmentInBaseCurrency,
value: filteredValueInBaseCurrency
});
const emergencyFundInCash = emergencyFund
.minus(
this.getEmergencyFundPositionsValueInBaseCurrency({
activities: orders
})
)
.toNumber();
accounts[UNKNOWN_KEY] = {
balance: 0,
currency: userCurrency,
current: emergencyFundInCash,
name: UNKNOWN_KEY,
original: emergencyFundInCash
};
holdings[userCurrency] = {
...cashPositions[userCurrency],
investment: emergencyFundInCash,
value: emergencyFundInCash
};
}
const summary = await this.getSummary({ const summary = await this.getSummary({
impersonationId, impersonationId,
userCurrency, userCurrency,
@ -1184,16 +1218,14 @@ export class PortfolioService {
private async getCashPositions({ private async getCashPositions({
cashDetails, cashDetails,
emergencyFund,
investment, investment,
userCurrency, userCurrency,
value value
}: { }: {
cashDetails: CashDetails; cashDetails: CashDetails;
emergencyFund: Big;
investment: Big; investment: Big;
value: Big;
userCurrency: string; userCurrency: string;
value: Big;
}) { }) {
const cashPositions: PortfolioDetails['holdings'] = { const cashPositions: PortfolioDetails['holdings'] = {
[userCurrency]: this.getInitialCashPosition({ [userCurrency]: this.getInitialCashPosition({
@ -1224,28 +1256,6 @@ export class PortfolioService {
} }
} }
if (emergencyFund.gt(0)) {
cashPositions[ASSET_SUB_CLASS_EMERGENCY_FUND] = {
...cashPositions[userCurrency],
assetSubClass: ASSET_SUB_CLASS_EMERGENCY_FUND,
investment: emergencyFund.toNumber(),
name: ASSET_SUB_CLASS_EMERGENCY_FUND,
symbol: ASSET_SUB_CLASS_EMERGENCY_FUND,
value: emergencyFund.toNumber()
};
cashPositions[userCurrency].investment = new Big(
cashPositions[userCurrency].investment
)
.minus(emergencyFund)
.toNumber();
cashPositions[userCurrency].value = new Big(
cashPositions[userCurrency].value
)
.minus(emergencyFund)
.toNumber();
}
for (const symbol of Object.keys(cashPositions)) { for (const symbol of Object.keys(cashPositions)) {
// Calculate allocations for each currency // Calculate allocations for each currency
cashPositions[symbol].allocationCurrent = value.gt(0) cashPositions[symbol].allocationCurrent = value.gt(0)
@ -1359,8 +1369,8 @@ export class PortfolioService {
}) { }) {
const emergencyFundOrders = activities.filter((activity) => { const emergencyFundOrders = activities.filter((activity) => {
return ( return (
activity.tags?.some(({ name }) => { activity.tags?.some(({ id }) => {
return name === 'EMERGENCY_FUND'; return id === EMERGENCY_FUND_TAG_ID;
}) ?? false }) ?? false
); );
}); });

@ -33,8 +33,6 @@ export const warnColorRgb = {
b: 69 b: 69
}; };
export const ASSET_SUB_CLASS_EMERGENCY_FUND = 'EMERGENCY_FUND';
export const DATA_GATHERING_QUEUE = 'DATA_GATHERING_QUEUE'; export const DATA_GATHERING_QUEUE = 'DATA_GATHERING_QUEUE';
export const DATA_GATHERING_QUEUE_PRIORITY_LOW = Number.MAX_SAFE_INTEGER; export const DATA_GATHERING_QUEUE_PRIORITY_LOW = Number.MAX_SAFE_INTEGER;
export const DATA_GATHERING_QUEUE_PRIORITY_HIGH = 1; export const DATA_GATHERING_QUEUE_PRIORITY_HIGH = 1;
@ -43,6 +41,8 @@ export const DEFAULT_DATE_FORMAT_MONTH_YEAR = 'MMM yyyy';
export const DEFAULT_LANGUAGE_CODE = 'en'; export const DEFAULT_LANGUAGE_CODE = 'en';
export const DEFAULT_PAGE_SIZE = 50; export const DEFAULT_PAGE_SIZE = 50;
export const EMERGENCY_FUND_TAG_ID = '4452656d-9fa4-4bd0-ba38-70492e31d180';
export const GATHER_ASSET_PROFILE_PROCESS = 'GATHER_ASSET_PROFILE'; export const GATHER_ASSET_PROFILE_PROCESS = 'GATHER_ASSET_PROFILE';
export const GATHER_ASSET_PROFILE_PROCESS_OPTIONS: JobOptions = { export const GATHER_ASSET_PROFILE_PROCESS_OPTIONS: JobOptions = {
attempts: 10, attempts: 10,

@ -8,7 +8,7 @@ export interface PortfolioPosition {
allocationCurrent: number; allocationCurrent: number;
allocationInvestment: number; allocationInvestment: number;
assetClass?: AssetClass; assetClass?: AssetClass;
assetSubClass?: AssetSubClass | 'CASH' | 'EMERGENCY_FUND'; assetSubClass?: AssetSubClass | 'CASH';
countries: Country[]; countries: Country[];
currency: string; currency: string;
dataSource: DataSource; dataSource: DataSource;

@ -13,7 +13,6 @@ import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table'; import { MatTableDataSource } from '@angular/material/table';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { ASSET_SUB_CLASS_EMERGENCY_FUND } from '@ghostfolio/common/config';
import { PortfolioPosition, UniqueAsset } from '@ghostfolio/common/interfaces'; import { PortfolioPosition, UniqueAsset } from '@ghostfolio/common/interfaces';
import { AssetClass, Order as OrderModel } from '@prisma/client'; import { AssetClass, Order as OrderModel } from '@prisma/client';
import { Subject, Subscription } from 'rxjs'; import { Subject, Subscription } from 'rxjs';
@ -42,10 +41,7 @@ export class HoldingsTableComponent implements OnChanges, OnDestroy, OnInit {
public dataSource: MatTableDataSource<PortfolioPosition> = public dataSource: MatTableDataSource<PortfolioPosition> =
new MatTableDataSource(); new MatTableDataSource();
public displayedColumns = []; public displayedColumns = [];
public ignoreAssetSubClasses = [ public ignoreAssetSubClasses = [AssetClass.CASH.toString()];
AssetClass.CASH.toString(),
ASSET_SUB_CLASS_EMERGENCY_FUND
];
public isLoading = true; public isLoading = true;
public routeQueryParams: Subscription; public routeQueryParams: Subscription;

Loading…
Cancel
Save