diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d682d9fd..f37a81129 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added the dividend yield (trailing twelve months) to the portfolio summary (experimental) + +### Changed + +- Refreshed the cryptocurrencies list +- Improved the language localization for Spanish (`es`) + +## 2.240.0 - 2026-02-18 + +### Added + +- Added a _No Activities_ preset to the historical market data table of the admin control panel - Added support for custom cryptocurrencies defined in the database - Added support for the cryptocurrency _Sky_ ### Changed +- Harmonized the validation for the create activity endpoint with the existing import activity logic - Upgraded `marked` from version `17.0.1` to `17.0.2` - Upgraded `ngx-markdown` from version `21.0.1` to `21.1.0` diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index 2cc8bbfb8..d77fde346 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -225,6 +225,10 @@ export class AdminService { presetId === 'ETF_WITHOUT_SECTORS' ) { filters = [{ id: 'ETF', type: 'ASSET_SUB_CLASS' }]; + } else if (presetId === 'NO_ACTIVITIES') { + where.activities = { + none: {} + }; } const searchQuery = filters.find(({ type }) => { diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index a787927b5..497b8a7e9 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -3,7 +3,6 @@ import { OrderService } from '@ghostfolio/api/app/order/order.service'; import { PlatformService } from '@ghostfolio/api/app/platform/platform.service'; import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; import { ApiService } from '@ghostfolio/api/services/api/api.service'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; @@ -33,7 +32,7 @@ import { } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; -import { DataSource, Prisma, SymbolProfile } from '@prisma/client'; +import { DataSource, Prisma } from '@prisma/client'; import { Big } from 'big.js'; import { endOfToday, isAfter, isSameSecond, parseISO } from 'date-fns'; import { omit, uniqBy } from 'lodash'; @@ -46,7 +45,6 @@ export class ImportService { public constructor( private readonly accountService: AccountService, private readonly apiService: ApiService, - private readonly configurationService: ConfigurationService, private readonly dataGatheringService: DataGatheringService, private readonly dataProviderService: DataProviderService, private readonly exchangeRateDataService: ExchangeRateDataService, @@ -395,7 +393,7 @@ export class ImportService { } } - const assetProfiles = await this.validateActivities({ + const assetProfiles = await this.dataProviderService.validateActivities({ activitiesDto, assetProfilesWithMarketDataDto, maxActivitiesToImport, @@ -729,132 +727,4 @@ export class ImportService { return uniqueAccountIds.size === 1; } - - private async validateActivities({ - activitiesDto, - assetProfilesWithMarketDataDto, - maxActivitiesToImport, - user - }: { - activitiesDto: Partial[]; - assetProfilesWithMarketDataDto: ImportDataDto['assetProfiles']; - maxActivitiesToImport: number; - user: UserWithSettings; - }) { - if (activitiesDto?.length > maxActivitiesToImport) { - throw new Error(`Too many activities (${maxActivitiesToImport} at most)`); - } - - const assetProfiles: { - [assetProfileIdentifier: string]: Partial; - } = {}; - const dataSources = await this.dataProviderService.getDataSources(); - - for (const [ - index, - { currency, dataSource, symbol, type } - ] of activitiesDto.entries()) { - if (!dataSources.includes(dataSource)) { - throw new Error( - `activities.${index}.dataSource ("${dataSource}") is not valid` - ); - } - - if ( - this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && - user.subscription.type === 'Basic' - ) { - const dataProvider = this.dataProviderService.getDataProvider( - DataSource[dataSource] - ); - - if (dataProvider.getDataProviderInfo().isPremium) { - throw new Error( - `activities.${index}.dataSource ("${dataSource}") is not valid` - ); - } - } - - if (!assetProfiles[getAssetProfileIdentifier({ dataSource, symbol })]) { - if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { - // Skip asset profile validation for FEE, INTEREST, and LIABILITY - // as these activity types don't require asset profiles - const assetProfileInImport = assetProfilesWithMarketDataDto?.find( - (profile) => { - return ( - profile.dataSource === dataSource && profile.symbol === symbol - ); - } - ); - - assetProfiles[getAssetProfileIdentifier({ dataSource, symbol })] = { - currency, - dataSource, - symbol, - name: assetProfileInImport?.name - }; - - continue; - } - - let assetProfile: Partial = { currency }; - - try { - assetProfile = ( - await this.dataProviderService.getAssetProfiles([ - { dataSource, symbol } - ]) - )?.[symbol]; - } catch {} - - if (!assetProfile?.name) { - const assetProfileInImport = assetProfilesWithMarketDataDto?.find( - (profile) => { - return ( - profile.dataSource === dataSource && profile.symbol === symbol - ); - } - ); - - if (assetProfileInImport) { - // Merge all fields of custom asset profiles into the validation object - Object.assign(assetProfile, { - assetClass: assetProfileInImport.assetClass, - assetSubClass: assetProfileInImport.assetSubClass, - comment: assetProfileInImport.comment, - countries: assetProfileInImport.countries, - currency: assetProfileInImport.currency, - cusip: assetProfileInImport.cusip, - dataSource: assetProfileInImport.dataSource, - figi: assetProfileInImport.figi, - figiComposite: assetProfileInImport.figiComposite, - figiShareClass: assetProfileInImport.figiShareClass, - holdings: assetProfileInImport.holdings, - isActive: assetProfileInImport.isActive, - isin: assetProfileInImport.isin, - name: assetProfileInImport.name, - scraperConfiguration: assetProfileInImport.scraperConfiguration, - sectors: assetProfileInImport.sectors, - symbol: assetProfileInImport.symbol, - symbolMapping: assetProfileInImport.symbolMapping, - url: assetProfileInImport.url - }); - } - } - - if (!['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { - if (!assetProfile?.name) { - throw new Error( - `activities.${index}.symbol ("${symbol}") is not valid for the specified data source ("${dataSource}")` - ); - } - } - - assetProfiles[getAssetProfileIdentifier({ dataSource, symbol })] = - assetProfile; - } - } - - return assetProfiles; - } } diff --git a/apps/api/src/app/order/order.controller.ts b/apps/api/src/app/order/order.controller.ts index 73c295f1b..c7021809e 100644 --- a/apps/api/src/app/order/order.controller.ts +++ b/apps/api/src/app/order/order.controller.ts @@ -4,6 +4,7 @@ import { RedactValuesInResponseInterceptor } from '@ghostfolio/api/interceptors/ import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor'; import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor'; import { ApiService } from '@ghostfolio/api/services/api/api.service'; +import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service'; import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service'; import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper'; @@ -46,6 +47,7 @@ import { OrderService } from './order.service'; export class OrderController { public constructor( private readonly apiService: ApiService, + private readonly dataProviderService: DataProviderService, private readonly dataGatheringService: DataGatheringService, private readonly impersonationService: ImpersonationService, private readonly orderService: OrderService, @@ -190,6 +192,29 @@ export class OrderController { @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(TransformDataSourceInRequestInterceptor) public async createOrder(@Body() data: CreateOrderDto): Promise { + try { + await this.dataProviderService.validateActivities({ + activitiesDto: [ + { + currency: data.currency, + dataSource: data.dataSource, + symbol: data.symbol, + type: data.type + } + ], + maxActivitiesToImport: 1, + user: this.request.user + }); + } catch (error) { + throw new HttpException( + { + error: getReasonPhrase(StatusCodes.BAD_REQUEST), + message: [error.message] + }, + StatusCodes.BAD_REQUEST + ); + } + const currency = data.currency; const customCurrency = data.customCurrency; const dataSource = data.dataSource; diff --git a/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json b/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json index e456f6f1d..d00ded6ef 100644 --- a/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json +++ b/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json @@ -421,6 +421,7 @@ "AGS": "Aegis", "AGT": "Alaya Governance Token", "AGURI": "Aguri-Chan", + "AGUSTO": "Agusto", "AGV": "Astra Guild Ventures", "AGVC": "AgaveCoin", "AGVE": "Agave", @@ -662,6 +663,7 @@ "ALN": "Aluna", "ALNV1": "Aluna v1", "ALOHA": "Aloha", + "ALOKA": "ALOKA", "ALON": "Alon", "ALOR": "The Algorix", "ALOT": "Dexalot", @@ -708,6 +710,7 @@ "AMADEUS": "AMADEUS", "AMAL": "AMAL", "AMAPT": "Amnis Finance", + "AMARA": "AMARA", "AMATEN": "Amaten", "AMATO": "AMATO", "AMAZINGTEAM": "AmazingTeamDAO", @@ -1344,6 +1347,7 @@ "AZIT": "Azit", "AZNX": "AstraZeneca xStock", "AZR": "Azure", + "AZTEC": "AZTEC", "AZU": "Azultec", "AZUKI": "Azuki", "AZUKI2": "AZUKI 2.0", @@ -1373,6 +1377,7 @@ "BABI": "Babylons", "BABL": "Babylon Finance", "BABY": "Babylon", + "BABY4": "Baby 4", "BABYANDY": "Baby Andy", "BABYASTER": "Baby Aster", "BABYB": "Baby Bali", @@ -2342,6 +2347,7 @@ "BNPL": "BNPL Pay", "BNR": "BiNeuro", "BNRTX": "BnrtxCoin", + "BNRY": "Binary Coin", "BNS": "BNS token", "BNSAI": "bonsAI Network", "BNSD": "BNSD Finance", @@ -2526,9 +2532,10 @@ "BOSSCOQ": "THE COQFATHER", "BOST": "BoostCoin", "BOSU": "Bosu Inu", - "BOT": "Bot Planet", + "BOT": "HyperBot", "BOTC": "BotChain", "BOTIFY": "BOTIFY", + "BOTPLANET": "Bot Planet", "BOTS": "ArkDAO", "BOTTO": "Botto", "BOTX": "BOTXCOIN", @@ -3201,6 +3208,7 @@ "CATCO": "CatCoin", "CATCOIN": "CatCoin", "CATCOINETH": "Catcoin", + "CATCOINIO": "Catcoin", "CATCOINOFSOL": "Cat Coin", "CATCOINV2": "CatCoin Cash", "CATDOG": "Cat-Dog", @@ -3583,6 +3591,7 @@ "CIC": "Crazy Internet Coin", "CICHAIN": "CIChain", "CIF": "Crypto Improvement Fund", + "CIFRON": "Cipher Mining (Ondo Tokenized)", "CIG": "cig", "CIM": "COINCOME", "CIN": "CinderCoin", @@ -3718,6 +3727,7 @@ "CMPT": "Spatial Computing", "CMPV2": "Caduceus Protocol", "CMQ": "Communique", + "CMR": "U.S Critical Mineral Reserve", "CMS": "COMSA", "CMSN": "The Commission", "CMT": "CyberMiles", @@ -4630,6 +4640,7 @@ "DEFIL": "DeFIL", "DEFILAB": "Defi", "DEFISCALE": "DeFiScale", + "DEFISSI": "DEFI.ssi", "DEFIT": "Digital Fitness", "DEFLA": "Defla", "DEFLCT": "Deflect", @@ -6323,7 +6334,7 @@ "FIFTY": "FIFTYONEFIFTY", "FIG": "FlowCom", "FIGH": "FIGHT FIGHT FIGHT", - "FIGHT": "Fight to MAGA", + "FIGHT2MAGA": "Fight to MAGA", "FIGHTMAGA": "FIGHT MAGA", "FIGHTPEPE": "FIGHT PEPE", "FIGHTRUMP": "FIGHT TRUMP", @@ -8039,6 +8050,7 @@ "HONOR": "HonorLand", "HONX": "Honeywell xStock", "HOODOG": "Hoodog", + "HOODON": "Robinhood Markets (Ondo Tokenized)", "HOODRAT": "Hoodrat Coin", "HOODX": "Robinhood xStock", "HOOF": "Metaderby Hoof", @@ -8395,6 +8407,7 @@ "IMS": "Independent Money System", "IMST": "Imsmart", "IMT": "Immortal Token", + "IMU": "Immunefi", "IMUSIFY": "imusify", "IMVR": "ImmVRse", "IMX": "Immutable X", @@ -8750,6 +8763,7 @@ "JFIVE": "Jonny Five", "JFOX": "JuniperFox AI", "JFP": "JUSTICE FOR PEANUT", + "JGGL": "JGGL Token", "JGLP": "Jones GLP", "JGN": "Juggernaut", "JHH": "Jen-Hsun Huang", @@ -9891,7 +9905,7 @@ "LRN": "Loopring [NEO]", "LRT": "LandRocker", "LSC": "LS Coin", - "LSD": "Pontem Liquidswap", + "LSD": "LSD", "LSDOGE": "LSDoge", "LSETH": "Liquid Staked ETH", "LSHARE": "LSHARE", @@ -10167,8 +10181,7 @@ "MANUSAI": "Manus AI Agent", "MANYU": "Manyu", "MANYUDOG": "MANYU", - "MAO": "MAO", - "MAOMEME": "Mao", + "MAO": "Mao", "MAOW": "MAOW", "MAP": "MAP Protocol", "MAPC": "MapCoin", @@ -10631,6 +10644,7 @@ "MICRO": "Micro GPT", "MICRODOGE": "MicroDoge", "MICROMINES": "Micromines", + "MICROVISION": "MicroVisionChain", "MIDAI": "Midway AI", "MIDAS": "Midas", "MIDASDOLLAR": "Midas Dollar Share", @@ -13146,6 +13160,7 @@ "PONKE": "Ponke", "PONKEBNB": "Ponke BNB", "PONKEI": "Chinese Ponkei the Original", + "PONTEM": "Pontem Liquidswap", "PONYO": "Ponyo Impact", "PONZI": "Ponzi", "PONZIO": "Ponzio The Cat", @@ -13573,6 +13588,7 @@ "QNX": "QueenDex Coin", "QOBI": "Qobit", "QOM": "Shiba Predator", + "QONE": "QONE", "QOOB": "QOOBER", "QORA": "QoraCoin", "QORPO": "QORPO WORLD", @@ -15153,6 +15169,7 @@ "SNAP": "SnapEx", "SNAPCAT": "Snapcat", "SNAPKERO": "SNAP", + "SNAPON": "Snap (Ondo Tokenized)", "SNB": "SynchroBitcoin", "SNC": "SunContract", "SNCT": "SnakeCity", @@ -15380,7 +15397,7 @@ "SP8DE": "Sp8de", "SPA": "Sperax", "SPAC": "SPACE DOGE", - "SPACE": "MicroVisionChain", + "SPACE": "Spacecoin", "SPACECOIN": "SpaceCoin", "SPACED": "SPACE DRAGON", "SPACEHAMSTER": "Space Hamster", @@ -15868,6 +15885,7 @@ "SUPERCYCLE": "Crypto SuperCycle", "SUPERDAPP": "SuperDapp", "SUPERF": "SUPER FLOKI", + "SUPERFL": "Superfluid", "SUPERGROK": "SuperGrok", "SUPEROETHB": "Super OETH", "SUPERT": "Super Trump", @@ -16790,6 +16808,7 @@ "TSLAON": "Tesla (Ondo Tokenized)", "TSLAX": "Tesla xStock", "TSLT": "Tamkin", + "TSMON": "Taiwan Semiconductor Manufacturing (Ondo Tokenized)", "TSN": "Tsunami Exchange Token", "TSO": "Thesirion", "TSOTCHKE": "tsotchke", @@ -17181,8 +17200,10 @@ "USDL": "Lift Dollar", "USDM": "USDM", "USDMA": "USD mars", - "USDN": "Neutral AI", + "USDN": "Ultimate Synthetic Delta Neutral", + "USDNEUTRAL": "Neutral AI", "USDO": "USD Open Dollar", + "USDON": "U.S. Dollar Tokenized Currency (Ondo)", "USDP": "Pax Dollar", "USDPLUS": "Overnight.fi USD+", "USDQ": "Quantoz USDQ", @@ -17456,6 +17477,7 @@ "VIDZ": "PureVidz", "VIEW": "Viewly", "VIG": "TheVig", + "VIGI": "Vigi", "VIK": "VIKTAMA", "VIKITA": "VIKITA", "VIKKY": "VikkyToken", @@ -17513,6 +17535,7 @@ "VLC": "Volcano Uni", "VLDY": "Validity", "VLK": "Vulkania", + "VLR": "Velora", "VLS": "Veles", "VLT": "Veltor", "VLTC": "Venus LTC", @@ -17733,6 +17756,7 @@ "WANUSDT": "wanUSDT", "WAP": "Wet Ass Pussy", "WAR": "WAR", + "WARD": "Warden", "WARP": "WarpCoin", "WARPED": "Warped Games", "WARPIE": "Warpie", @@ -18494,6 +18518,7 @@ "XP": "Xphere", "XPA": "XPA", "XPARTY": "X Party", + "XPASS": "XPASS Token", "XPAT": "Bitnation Pangea", "XPAY": "Wallet Pay", "XPB": "Pebble Coin", @@ -18869,8 +18894,7 @@ "ZEBU": "ZEBU", "ZEC": "ZCash", "ZECD": "ZCashDarkCoin", - "ZED": "ZED Token", - "ZEDCOIN": "ZedCoin", + "ZED": "ZedCoins", "ZEDD": "ZedDex", "ZEDTOKEN": "Zed Token", "ZEDX": "ZEDX Сoin", @@ -19108,6 +19132,7 @@ "币安人生": "币安人生", "恶俗企鹅": "恶俗企鹅", "我踏马来了": "我踏马来了", + "狗屎": "狗屎", "老子": "老子", "雪球": "雪球", "黑马": "黑马" diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index 5a088c0e4..eb9816c67 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -1,3 +1,4 @@ +import { ImportDataDto } from '@ghostfolio/api/app/import/import-data.dto'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; @@ -10,8 +11,10 @@ import { PROPERTY_API_KEY_GHOSTFOLIO, PROPERTY_DATA_SOURCE_MAPPING } from '@ghostfolio/common/config'; +import { CreateOrderDto } from '@ghostfolio/common/dtos'; import { DATE_FORMAT, + getAssetProfileIdentifier, getCurrencyFromSymbol, getStartOfUtcDate, isCurrency, @@ -185,6 +188,121 @@ export class DataProviderService implements OnModuleInit { return dataSources.sort(); } + public async validateActivities({ + activitiesDto, + assetProfilesWithMarketDataDto, + maxActivitiesToImport, + user + }: { + activitiesDto: Pick< + Partial, + 'currency' | 'dataSource' | 'symbol' | 'type' + >[]; + assetProfilesWithMarketDataDto?: ImportDataDto['assetProfiles']; + maxActivitiesToImport: number; + user: UserWithSettings; + }) { + if (activitiesDto?.length > maxActivitiesToImport) { + throw new Error(`Too many activities (${maxActivitiesToImport} at most)`); + } + + const assetProfiles: { + [assetProfileIdentifier: string]: Partial; + } = {}; + + const dataSources = await this.getDataSources(); + + for (const [ + index, + { currency, dataSource, symbol, type } + ] of activitiesDto.entries()) { + const activityPath = + maxActivitiesToImport === 1 ? 'activity' : `activities.${index}`; + + if (!dataSources.includes(dataSource)) { + throw new Error( + `${activityPath}.dataSource ("${dataSource}") is not valid` + ); + } + + if ( + this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && + user.subscription.type === 'Basic' + ) { + const dataProvider = this.getDataProvider(DataSource[dataSource]); + + if (dataProvider.getDataProviderInfo().isPremium) { + throw new Error( + `${activityPath}.dataSource ("${dataSource}") is not valid` + ); + } + } + + const assetProfileIdentifier = getAssetProfileIdentifier({ + dataSource, + symbol + }); + + if (!assetProfiles[assetProfileIdentifier]) { + if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { + const assetProfileInImport = assetProfilesWithMarketDataDto?.find( + (profile) => { + return ( + profile.dataSource === dataSource && profile.symbol === symbol + ); + } + ); + + assetProfiles[assetProfileIdentifier] = { + currency, + dataSource, + symbol, + name: assetProfileInImport?.name + }; + + continue; + } + + let assetProfile: Partial = { currency }; + + try { + assetProfile = ( + await this.getAssetProfiles([ + { + dataSource, + symbol + } + ]) + )?.[symbol]; + } catch {} + + if (!assetProfile?.name) { + const assetProfileInImport = assetProfilesWithMarketDataDto?.find( + (profile) => { + return ( + profile.dataSource === dataSource && profile.symbol === symbol + ); + } + ); + + if (assetProfileInImport) { + Object.assign(assetProfile, assetProfileInImport); + } + } + + if (!assetProfile?.name) { + throw new Error( + `activities.${index}.symbol ("${symbol}") is not valid for the specified data source ("${dataSource}")` + ); + } + + assetProfiles[assetProfileIdentifier] = assetProfile; + } + } + + return assetProfiles; + } + public async getDividends({ dataSource, from, diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts index 8f956b782..6a079c20a 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts @@ -140,6 +140,11 @@ export class GfAdminMarketDataComponent id: 'ETF_WITHOUT_SECTORS', label: $localize`ETFs without Sectors`, type: 'PRESET_ID' as Filter['type'] + }, + { + id: 'NO_ACTIVITIES', + label: $localize`No Activities`, + type: 'PRESET_ID' as Filter['type'] } ]; public benchmarks: Partial[]; diff --git a/apps/client/src/locales/messages.ca.xlf b/apps/client/src/locales/messages.ca.xlf index 6400807bd..585a3d779 100644 --- a/apps/client/src/locales/messages.ca.xlf +++ b/apps/client/src/locales/messages.ca.xlf @@ -895,7 +895,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -935,7 +935,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -1003,7 +1003,7 @@ Oooh! No s’han pogut recopilar les dades históriques. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -1035,7 +1035,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -5924,6 +5924,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Provisió de jubilació @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 2be7713eb..38f0b4c66 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -506,7 +506,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2630,7 +2630,7 @@ Filtern nach... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -3234,7 +3234,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3357,6 +3357,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Altersvorsorge @@ -5716,7 +5724,7 @@ Ups! Die historischen Daten konnten nicht geparsed werden. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6781,7 +6789,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7359,7 +7367,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 096c42162..770b4840a 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -507,7 +507,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2615,7 +2615,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -3219,7 +3219,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3342,6 +3342,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Provisión de jubilación @@ -5693,7 +5701,7 @@ ¡Ups! No se pudieron analizar los datos históricos. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6758,7 +6766,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7336,7 +7344,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 @@ -7883,7 +7891,7 @@ Fee Ratio (legacy) - Relación de tarifas + Relación de tarifas (heredado) apps/client/src/app/pages/i18n/i18n-page.html 152 @@ -7907,7 +7915,7 @@ Fee Ratio - Fee Ratio + Relación de tarifas apps/client/src/app/pages/i18n/i18n-page.html 161 @@ -7915,7 +7923,7 @@ The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) - The fees do exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + Las tarifas superan el ${thresholdMax}% de su volumen total de inversión (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html 163 @@ -7923,7 +7931,7 @@ The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) - The fees do not exceed ${thresholdMax}% of your total investment volume (${feeRatio}%) + Las tarifas no superan el ${thresholdMax}% de su volumen total de inversión (${feeRatio}%) apps/client/src/app/pages/i18n/i18n-page.html 167 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 8cb2b2f48..f3a8d4942 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -530,7 +530,7 @@ Filtrer par... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -570,7 +570,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2222,7 +2222,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3341,6 +3341,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Réserve pour retraite @@ -5692,7 +5700,7 @@ Oops! Echec du parsing des données historiques. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 61b08b673..f021dae49 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -507,7 +507,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2615,7 +2615,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -3219,7 +3219,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3342,6 +3342,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Fondo pensione @@ -5693,7 +5701,7 @@ Ops! Impossibile elaborare i dati storici. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6758,7 +6766,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7336,7 +7344,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.ko.xlf b/apps/client/src/locales/messages.ko.xlf index 22c06b596..f188d4924 100644 --- a/apps/client/src/locales/messages.ko.xlf +++ b/apps/client/src/locales/messages.ko.xlf @@ -792,7 +792,7 @@ 다음 기준으로 필터... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -832,7 +832,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -884,7 +884,7 @@ 이런! 과거 데이터를 파싱할 수 없습니다. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -916,7 +916,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -5376,6 +5376,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision 퇴직금 @@ -6742,7 +6750,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7360,7 +7368,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index c79ecc1d3..76a74e6fd 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -506,7 +506,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2614,7 +2614,7 @@ Filter op... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -3218,7 +3218,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3341,6 +3341,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Pensioen @@ -5692,7 +5700,7 @@ Oeps! Ophalen van historische data is mislukt. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index a7c72f3ca..fdc528254 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -783,7 +783,7 @@ Filtruj według... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -823,7 +823,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -859,7 +859,7 @@ Ups! Nie udało się sparsować danych historycznych. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -883,7 +883,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -5307,6 +5307,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Świadczenia Emerytalne @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 55d622ed9..194922435 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -530,7 +530,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -570,7 +570,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -3174,7 +3174,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -3341,6 +3341,14 @@ 22 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Provisão de Reforma @@ -5692,7 +5700,7 @@ Ops! Não foi possível analisar os dados históricos. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 841da4721..a7b86f624 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -739,7 +739,7 @@ Filtrele... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -779,7 +779,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -3371,7 +3371,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -5003,6 +5003,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Yaşlılık Provizyonu @@ -5692,7 +5700,7 @@ Hay Allah! Geçmiş veriler ayrıştırılamadı. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6757,7 +6765,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7335,7 +7343,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.uk.xlf b/apps/client/src/locales/messages.uk.xlf index 27c55d792..61cebd47a 100644 --- a/apps/client/src/locales/messages.uk.xlf +++ b/apps/client/src/locales/messages.uk.xlf @@ -875,7 +875,7 @@ Фільтрувати за... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -931,7 +931,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -2323,7 +2323,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 @@ -4576,7 +4576,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -6419,7 +6419,7 @@ Упс! Не вдалося отримати історичні дані. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -6595,7 +6595,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -6774,6 +6774,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision Пенсійне накопичення diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index d15b93002..03644820a 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -740,7 +740,7 @@ Filter by... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -777,7 +777,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -823,7 +823,7 @@ Oops! Could not parse historical data. libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -852,7 +852,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -4907,6 +4907,13 @@ 27 + + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision @@ -6126,7 +6133,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -6685,7 +6692,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 08d4f3d43..9feb0e546 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -792,7 +792,7 @@ 过滤... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 385 + 390 @@ -832,7 +832,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 44 + 40 @@ -868,7 +868,7 @@ 哎呀!无法解析历史数据。 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.ts - 262 + 284 @@ -892,7 +892,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html - 71 + 67 @@ -5360,6 +5360,14 @@ 27 + + No Activities + No Activities + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 146 + + Retirement Provision 退休金 @@ -6758,7 +6766,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 46 + 47 libs/ui/src/lib/i18n.ts @@ -7336,7 +7344,7 @@ libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html - 48 + 49 diff --git a/libs/common/src/lib/types/market-data-preset.type.ts b/libs/common/src/lib/types/market-data-preset.type.ts index 0dbf914fa..2622feac3 100644 --- a/libs/common/src/lib/types/market-data-preset.type.ts +++ b/libs/common/src/lib/types/market-data-preset.type.ts @@ -2,4 +2,5 @@ export type MarketDataPreset = | 'BENCHMARKS' | 'CURRENCIES' | 'ETF_WITHOUT_COUNTRIES' - | 'ETF_WITHOUT_SECTORS'; + | 'ETF_WITHOUT_SECTORS' + | 'NO_ACTIVITIES'; diff --git a/libs/ui/src/lib/account-balances/account-balances.component.html b/libs/ui/src/lib/account-balances/account-balances.component.html index caef922ed..29037a985 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.html +++ b/libs/ui/src/lib/account-balances/account-balances.component.html @@ -12,7 +12,7 @@ Date - + @@ -37,7 +37,7 @@
@@ -48,7 +48,7 @@
- {{ accountCurrency }} + {{ accountCurrency() }}
@@ -58,7 +58,7 @@ - @if (showActions) { + @if (showActions()) {