Browse Source

Task/improve ISIN search in FMP service (#8191)

* Improve search by ISIN

* Update changelog
pull/8178/head^2
Thomas Kaul 11 hours ago
committed by GitHub
parent
commit
c199277b1e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 6
      CHANGELOG.md
  2. 64
      apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts

6
CHANGELOG.md

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Changed
- Improved the search by ISIN number in the _Financial Modeling Prep_ service
## 3.87.0 - 2026-10-17
### Added

64
apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts

@ -132,19 +132,7 @@ export class FinancialModelingPrepService
);
response.name = quote.name;
} else {
const queryParams = new URLSearchParams({
symbol,
apikey: this.apiKey
});
const [assetProfile] = await this.fetchService
.fetch(
`${this.getUrl({ version: 'stable' })}/profile?${queryParams.toString()}`,
{
signal: AbortSignal.timeout(requestTimeout)
}
)
.then((res) => res.json());
const assetProfile = await this.getProfile({ requestTimeout, symbol });
if (!assetProfile) {
const indexProfile = await this.getIndexProfile({
@ -549,6 +537,10 @@ export class FinancialModelingPrepService
return 'AAPL';
}
/**
* Financial Modeling Prep has no currency and no asset class in the search
* by ISIN, thus they are taken from the profile of the symbol.
*/
public async search({
includeIndices = false,
query,
@ -578,18 +570,30 @@ export class FinancialModelingPrepService
await Promise.all(
result.map(({ symbol }) => {
return this.getAssetProfile({ symbol }).then((assetProfile) => {
assetProfileBySymbolMap[symbol] = assetProfile;
});
return this.getProfile({ requestTimeout, symbol })
.then((profile) => {
assetProfileBySymbolMap[symbol] = {
...this.parseAssetClass(profile),
currency: profile?.currency
};
})
.catch((error) => {
this.logger.error(
`Could not get the profile of ${symbol} (${this.getName()}): [${error?.name}] ${error?.message}`
);
});
})
);
items = result.map(({ assetClass, assetSubClass, name, symbol }) => {
items = result.map(({ name, symbol }) => {
const { assetClass, assetSubClass, currency } =
assetProfileBySymbolMap[symbol] ?? {};
return {
assetClass,
assetSubClass,
currency,
symbol,
currency: assetProfileBySymbolMap[symbol]?.currency,
dataProviderInfo: this.getDataProviderInfo(),
dataSource: this.getName(),
name: this.formatName({ name })
@ -696,6 +700,30 @@ export class FinancialModelingPrepService
};
}
private async getProfile({
requestTimeout,
symbol
}: {
requestTimeout: number;
symbol: string;
}) {
const queryParams = new URLSearchParams({
symbol,
apikey: this.apiKey
});
const [profile] = await this.fetchService
.fetch(
`${this.getUrl({ version: 'stable' })}/profile?${queryParams.toString()}`,
{
signal: AbortSignal.timeout(requestTimeout)
}
)
.then((res) => res.json());
return profile;
}
private async getSearchResults({
endpoint,
query,

Loading…
Cancel
Save