diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b3171dcd..0597a2e4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed the functionality to open an asset profile of a custom currency in the admin control panel +- Fixed the asset class parsing in the _Financial Modeling Prep_ service for exchange rates ## 2.152.1 - 2025-04-17 diff --git a/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts b/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts index 606e6b7fd..f9593f0d0 100644 --- a/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts +++ b/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts @@ -11,6 +11,7 @@ import { IDataProviderHistoricalResponse, IDataProviderResponse } from '@ghostfolio/api/services/interfaces/interfaces'; +import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { DataProviderInfo, @@ -72,7 +73,9 @@ export class AlphaVantageService implements DataProviderInterface { const historicalData: { [symbol: string]: IAlphaVantageHistoricalResponse[]; } = await this.alphaVantage.crypto.daily( - symbol.substring(0, symbol.length - 3).toLowerCase(), + symbol + .substring(0, symbol.length - DEFAULT_CURRENCY.length) + .toLowerCase(), 'usd' ); diff --git a/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts b/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts index d6eaec076..32aff4387 100644 --- a/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts +++ b/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts @@ -12,8 +12,11 @@ import { IDataProviderHistoricalResponse, IDataProviderResponse } from '@ghostfolio/api/services/interfaces/interfaces'; -import { REPLACE_NAME_PARTS } from '@ghostfolio/common/config'; -import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; +import { + DEFAULT_CURRENCY, + REPLACE_NAME_PARTS +} from '@ghostfolio/common/config'; +import { DATE_FORMAT, isCurrency, parseDate } from '@ghostfolio/common/helper'; import { DataProviderInfo, LookupItem, @@ -67,7 +70,15 @@ export class FinancialModelingPrepService implements DataProviderInterface { }; try { - if (this.cryptocurrencyService.isCryptocurrency(symbol)) { + if ( + isCurrency(symbol.substring(0, symbol.length - DEFAULT_CURRENCY.length)) + ) { + response.assetClass = AssetClass.LIQUIDITY; + response.assetSubClass = AssetSubClass.CASH; + response.currency = symbol.substring( + symbol.length - DEFAULT_CURRENCY.length + ); + } else if (this.cryptocurrencyService.isCryptocurrency(symbol)) { const [quote] = await fetch( `${this.URL}/quote/${symbol}?apikey=${this.apiKey}`, { @@ -77,7 +88,9 @@ export class FinancialModelingPrepService implements DataProviderInterface { response.assetClass = AssetClass.LIQUIDITY; response.assetSubClass = AssetSubClass.CRYPTOCURRENCY; - response.currency = symbol.substring(symbol.length - 3); + response.currency = symbol.substring( + symbol.length - DEFAULT_CURRENCY.length + ); response.name = quote.name; } else { const [assetProfile] = await fetch( @@ -472,15 +485,17 @@ export class FinancialModelingPrepService implements DataProviderInterface { let assetClass: AssetClass; let assetSubClass: AssetSubClass; - if (profile.isEtf) { - assetClass = AssetClass.EQUITY; - assetSubClass = AssetSubClass.ETF; - } else if (profile.isFund) { - assetClass = AssetClass.EQUITY; - assetSubClass = AssetSubClass.MUTUALFUND; - } else { - assetClass = AssetClass.EQUITY; - assetSubClass = AssetSubClass.STOCK; + if (profile) { + if (profile.isEtf) { + assetClass = AssetClass.EQUITY; + assetSubClass = AssetSubClass.ETF; + } else if (profile.isFund) { + assetClass = AssetClass.EQUITY; + assetSubClass = AssetSubClass.MUTUALFUND; + } else { + assetClass = AssetClass.EQUITY; + assetSubClass = AssetSubClass.STOCK; + } } return { assetClass, assetSubClass };