Browse Source

Feature/extend search by isin in financial modeling prep service (#4204)

* Extend search by ISIN

* Update changelog
pull/4207/head
Thomas Kaul 19 hours ago
committed by GitHub
parent
commit
40b628e0e7
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 2
      apps/api/src/app/symbol/symbol.controller.ts
  3. 69
      apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts

1
CHANGELOG.md

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Extended the search by `isin` in the _Financial Modeling Prep_ service
- Switched to _ESLint_’s flat config format - Switched to _ESLint_’s flat config format
- Upgraded `eslint` dependencies - Upgraded `eslint` dependencies

2
apps/api/src/app/symbol/symbol.controller.ts

@ -47,7 +47,7 @@ export class SymbolController {
try { try {
return this.symbolService.lookup({ return this.symbolService.lookup({
includeIndices, includeIndices,
query: query.toLowerCase(), query,
user: this.request.user user: this.request.user
}); });
} catch { } catch {

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

@ -20,12 +20,13 @@ import {
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client'; import { DataSource, SymbolProfile } from '@prisma/client';
import { isISIN } from 'class-validator';
import { format, isAfter, isBefore, isSameDay } from 'date-fns'; import { format, isAfter, isBefore, isSameDay } from 'date-fns';
@Injectable() @Injectable()
export class FinancialModelingPrepService implements DataProviderInterface { export class FinancialModelingPrepService implements DataProviderInterface {
private apiKey: string; private apiKey: string;
private readonly URL = 'https://financialmodelingprep.com/api/v3'; private readonly URL = this.getUrl({ version: 3 });
public constructor( public constructor(
private readonly configurationService: ConfigurationService private readonly configurationService: ConfigurationService
@ -161,25 +162,49 @@ export class FinancialModelingPrepService implements DataProviderInterface {
let items: LookupItem[] = []; let items: LookupItem[] = [];
try { try {
const result = await fetch( if (isISIN(query)) {
`${this.URL}/search?query=${query}&apikey=${this.apiKey}`, const result = await fetch(
{ `${this.getUrl({ version: 4 })}/search/isin?isin=${query}&apikey=${this.apiKey}`,
signal: AbortSignal.timeout( {
this.configurationService.get('REQUEST_TIMEOUT') signal: AbortSignal.timeout(
) this.configurationService.get('REQUEST_TIMEOUT')
} )
).then((res) => res.json()); }
).then((res) => res.json());
items = result.map(({ currency, name, symbol }) => {
return { items = result.map(({ companyName, currency, symbol }) => {
// TODO: Add assetClass return {
// TODO: Add assetSubClass currency,
currency, symbol,
name, assetClass: undefined, // TODO
symbol, assetSubClass: undefined, // TODO
dataSource: this.getName() dataProviderInfo: this.getDataProviderInfo(),
}; dataSource: this.getName(),
}); name: companyName
};
});
} else {
const result = await fetch(
`${this.URL}/search?query=${query}&apikey=${this.apiKey}`,
{
signal: AbortSignal.timeout(
this.configurationService.get('REQUEST_TIMEOUT')
)
}
).then((res) => res.json());
items = result.map(({ currency, name, symbol }) => {
return {
currency,
name,
symbol,
assetClass: undefined, // TODO
assetSubClass: undefined, // TODO
dataProviderInfo: this.getDataProviderInfo(),
dataSource: this.getName()
};
});
}
} catch (error) { } catch (error) {
let message = error; let message = error;
@ -194,4 +219,8 @@ export class FinancialModelingPrepService implements DataProviderInterface {
return { items }; return { items };
} }
private getUrl({ version }: { version: number }) {
return `https://financialmodelingprep.com/api/v${version}`;
}
} }

Loading…
Cancel
Save