Feature/remove emergency fund as asset class (#1615)
* Remove emergency fund as asset class * Update changelog
This commit is contained in:
parent
f47e4d3b04
commit
7fa6eda45d
@ -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…
x
Reference in New Issue
Block a user