diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index 2aac43a18..7df4498d7 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -416,7 +416,7 @@ export class AdminService { dataSource, marketDataItemCount, symbol, - assetClass: 'CASH', + assetClass: AssetClass.LIQUIDITY, countriesCount: 0, currency: symbol.replace(DEFAULT_CURRENCY, ''), id: undefined, diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 81d0c3df9..0828fb3e4 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -47,6 +47,7 @@ import { } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; +import { AssetClass, AssetSubClass } from '@prisma/client'; import { Big } from 'big.js'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; @@ -128,14 +129,19 @@ export class PortfolioController { const totalValue = Object.values(holdings) .filter(({ assetClass, assetSubClass }) => { - return assetClass !== 'CASH' && assetSubClass !== 'CASH'; + return ( + assetClass !== AssetClass.LIQUIDITY && + assetSubClass !== AssetSubClass.CASH + ); }) .map(({ valueInBaseCurrency }) => { return valueInBaseCurrency; }) - .reduce((a, b) => a + b, 0); + .reduce((a, b) => { + return a + b; + }, 0); - for (const [symbol, portfolioPosition] of Object.entries(holdings)) { + for (const [, portfolioPosition] of Object.entries(holdings)) { portfolioPosition.investment = portfolioPosition.investment / totalInvestment; portfolioPosition.valueInPercentage = @@ -185,11 +191,11 @@ export class PortfolioController { holdings[symbol] = { ...portfolioPosition, assetClass: - hasDetails || portfolioPosition.assetClass === 'CASH' + hasDetails || portfolioPosition.assetClass === AssetClass.LIQUIDITY ? portfolioPosition.assetClass : undefined, assetSubClass: - hasDetails || portfolioPosition.assetSubClass === 'CASH' + hasDetails || portfolioPosition.assetSubClass === AssetSubClass.CASH ? portfolioPosition.assetSubClass : undefined, countries: hasDetails ? portfolioPosition.countries : [], diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index cf7a47f52..4e56f844b 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -54,6 +54,7 @@ import { Account, Type as ActivityType, AssetClass, + AssetSubClass, DataSource, Order, Platform, @@ -376,7 +377,7 @@ export class PortfolioService { }) ?? false; const isFilteredByCash = filters?.some(({ id, type }) => { - return id === 'CASH' && type === 'ASSET_CLASS'; + return id === AssetClass.LIQUIDITY && type === 'ASSET_CLASS'; }); const isFilteredByClosedHoldings = @@ -391,8 +392,8 @@ export class PortfolioService { if ( filters?.length === 0 || (filters?.length === 1 && - filters[0].type === 'ASSET_CLASS' && - filters[0].id === 'CASH') + filters[0].id === AssetClass.LIQUIDITY && + filters[0].type === 'ASSET_CLASS') ) { filteredValueInBaseCurrency = filteredValueInBaseCurrency.plus( cashDetails.balanceInBaseCurrency @@ -1425,8 +1426,8 @@ export class PortfolioService { return { currency, allocationInPercentage: 0, - assetClass: AssetClass.CASH, - assetSubClass: AssetClass.CASH, + assetClass: AssetClass.LIQUIDITY, + assetSubClass: AssetSubClass.CASH, countries: [], dataSource: undefined, dateOfFirstActivity: undefined, diff --git a/apps/api/src/services/data-provider/coingecko/coingecko.service.ts b/apps/api/src/services/data-provider/coingecko/coingecko.service.ts index d17ba4b7e..d673dd7aa 100644 --- a/apps/api/src/services/data-provider/coingecko/coingecko.service.ts +++ b/apps/api/src/services/data-provider/coingecko/coingecko.service.ts @@ -59,7 +59,7 @@ export class CoinGeckoService implements DataProviderInterface { }): Promise> { const response: Partial = { symbol, - assetClass: AssetClass.CASH, + assetClass: AssetClass.LIQUIDITY, assetSubClass: AssetSubClass.CRYPTOCURRENCY, currency: DEFAULT_CURRENCY, dataSource: this.getName() @@ -243,7 +243,7 @@ export class CoinGeckoService implements DataProviderInterface { return { name, symbol, - assetClass: AssetClass.CASH, + assetClass: AssetClass.LIQUIDITY, assetSubClass: AssetSubClass.CRYPTOCURRENCY, currency: DEFAULT_CURRENCY, dataProviderInfo: this.getDataProviderInfo(), diff --git a/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts b/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts index c6edef0ca..35fa9604a 100644 --- a/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts +++ b/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts @@ -266,7 +266,7 @@ export class YahooFinanceDataEnhancerService implements DataEnhancerInterface { switch (quoteType?.toLowerCase()) { case 'cryptocurrency': - assetClass = AssetClass.CASH; + assetClass = AssetClass.LIQUIDITY; assetSubClass = AssetSubClass.CRYPTOCURRENCY; break; case 'equity': diff --git a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts index 99104a78d..1b6abd585 100644 --- a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts +++ b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts @@ -468,7 +468,7 @@ export class EodHistoricalDataService implements DataProviderInterface { assetSubClass = AssetSubClass.STOCK; break; case 'currency': - assetClass = AssetClass.CASH; + assetClass = AssetClass.LIQUIDITY; if (Exchange?.toLowerCase() === 'cc') { assetSubClass = AssetSubClass.CRYPTOCURRENCY; diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts index 0dba81d1e..6d3aed4d3 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts @@ -348,8 +348,8 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { name: position.name }; - if (position.assetClass !== AssetClass.CASH) { - // Prepare analysis data by continents, countries and sectors except for cash + if (position.assetClass !== AssetClass.LIQUIDITY) { + // Prepare analysis data by continents, countries and sectors except for liquidity if (position.countries.length > 0) { this.markets.developedMarkets.value += diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index 5e1366ce2..9e438c0f5 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -4,7 +4,6 @@ import ms from 'ms'; export const ghostfolioPrefix = 'GF'; export const ghostfolioScraperApiSymbolPrefix = `_${ghostfolioPrefix}_`; -export const ghostfolioCashSymbol = `${ghostfolioScraperApiSymbolPrefix}CASH`; export const ghostfolioFearAndGreedIndexDataSource = DataSource.RAPID_API; export const ghostfolioFearAndGreedIndexSymbol = `${ghostfolioScraperApiSymbolPrefix}FEAR_AND_GREED_INDEX`; diff --git a/libs/common/src/lib/interfaces/portfolio-position.interface.ts b/libs/common/src/lib/interfaces/portfolio-position.interface.ts index 2e5772ef7..a47a1ebc7 100644 --- a/libs/common/src/lib/interfaces/portfolio-position.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-position.interface.ts @@ -8,7 +8,7 @@ export interface PortfolioPosition { allocationInPercentage: number; assetClass?: AssetClass; assetClassLabel?: string; - assetSubClass?: AssetSubClass | 'CASH'; + assetSubClass?: AssetSubClass; assetSubClassLabel?: string; countries: Country[]; currency: string; diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.ts b/libs/ui/src/lib/holdings-table/holdings-table.component.ts index 9d568abf7..93ac5b6fe 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.ts +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.ts @@ -23,7 +23,7 @@ import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; import { MatSort, MatSortModule } from '@angular/material/sort'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { Router, RouterModule } from '@angular/router'; -import { AssetClass } from '@prisma/client'; +import { AssetClass, AssetSubClass } from '@prisma/client'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { Subject, Subscription } from 'rxjs'; @@ -66,7 +66,7 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy, OnInit { public dataSource: MatTableDataSource = new MatTableDataSource(); public displayedColumns = []; - public ignoreAssetSubClasses = [AssetClass.CASH]; + public ignoreAssetSubClasses = [AssetSubClass.CASH]; public isLoading = true; public routeQueryParams: Subscription; diff --git a/libs/ui/src/lib/i18n.ts b/libs/ui/src/lib/i18n.ts index 9687f461c..e1266baa3 100644 --- a/libs/ui/src/lib/i18n.ts +++ b/libs/ui/src/lib/i18n.ts @@ -40,6 +40,7 @@ const locales = { COMMODITY: $localize`Commodity`, EQUITY: $localize`Equity`, FIXED_INCOME: $localize`Fixed Income`, + LIQUIDITY: $localize`Liquidity`, REAL_ESTATE: $localize`Real Estate`, // AssetSubClass (enum) diff --git a/prisma/migrations/20240422181320_added_liquidity_to_asset_class/migration.sql b/prisma/migrations/20240422181320_added_liquidity_to_asset_class/migration.sql new file mode 100644 index 000000000..685cae6bb --- /dev/null +++ b/prisma/migrations/20240422181320_added_liquidity_to_asset_class/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "AssetClass" ADD VALUE 'LIQUIDITY'; diff --git a/prisma/migrations/20240422181356_added_cash_to_asset_sub_class/migration.sql b/prisma/migrations/20240422181356_added_cash_to_asset_sub_class/migration.sql new file mode 100644 index 000000000..7aeaf5abd --- /dev/null +++ b/prisma/migrations/20240422181356_added_cash_to_asset_sub_class/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "AssetSubClass" ADD VALUE 'CASH'; diff --git a/prisma/migrations/20240422181835_changed_cash_to_liquidity_in_asset_sub_class/migration.sql b/prisma/migrations/20240422181835_changed_cash_to_liquidity_in_asset_sub_class/migration.sql new file mode 100644 index 000000000..f0b260a09 --- /dev/null +++ b/prisma/migrations/20240422181835_changed_cash_to_liquidity_in_asset_sub_class/migration.sql @@ -0,0 +1,7 @@ +UPDATE "SymbolProfile" +SET "assetClass" = 'LIQUIDITY' +WHERE "assetClass" = 'CASH'; + +UPDATE "SymbolProfileOverrides" +SET "assetClass" = 'LIQUIDITY' +WHERE "assetClass" = 'CASH'; diff --git a/prisma/migrations/20240422182643_removed_cash_from_asset_class/migration.sql b/prisma/migrations/20240422182643_removed_cash_from_asset_class/migration.sql new file mode 100644 index 000000000..6a08aee78 --- /dev/null +++ b/prisma/migrations/20240422182643_removed_cash_from_asset_class/migration.sql @@ -0,0 +1,9 @@ +-- AlterEnum +BEGIN; +CREATE TYPE "AssetClass_new" AS ENUM ('COMMODITY', 'EQUITY', 'FIXED_INCOME', 'LIQUIDITY', 'REAL_ESTATE'); +ALTER TABLE "SymbolProfile" ALTER COLUMN "assetClass" TYPE "AssetClass_new" USING ("assetClass"::text::"AssetClass_new"); +ALTER TABLE "SymbolProfileOverrides" ALTER COLUMN "assetClass" TYPE "AssetClass_new" USING ("assetClass"::text::"AssetClass_new"); +ALTER TYPE "AssetClass" RENAME TO "AssetClass_old"; +ALTER TYPE "AssetClass_new" RENAME TO "AssetClass"; +DROP TYPE "AssetClass_old"; +COMMIT; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index af7ad1845..43052de11 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -248,15 +248,16 @@ enum AccessPermission { } enum AssetClass { - CASH COMMODITY EQUITY FIXED_INCOME + LIQUIDITY REAL_ESTATE } enum AssetSubClass { BOND + CASH COMMODITY CRYPTOCURRENCY ETF