Feature/introduce max number of symbols per data provider request (#1111)

* Introduce maximum number of symbols per request

* Set log level settings

* Update changelog
pull/1114/head
Thomas Kaul 2 years ago committed by GitHub
parent 44058b2d7a
commit 9f2a49a1c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,6 +5,13 @@ 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/), 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). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Changed
- Improved the performance of data provider requests by introducing a maximum number of symbols per request (chunk size)
- Changed the log level settings
## 1.175.0 - 29.07.2022 ## 1.175.0 - 29.07.2022
### Added ### Added

@ -5,7 +5,12 @@ import { AppModule } from './app/app.module';
import { environment } from './environments/environment'; import { environment } from './environments/environment';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule, {
logger:
process.env.NODE_ENV === 'production'
? ['error', 'log', 'warn']
: ['debug', 'error', 'log', 'verbose', 'warn']
});
app.enableCors(); app.enableCors();
app.enableVersioning({ app.enableVersioning({
defaultVersion: '1', defaultVersion: '1',

@ -168,6 +168,7 @@ export class DataProviderService {
const response: { const response: {
[symbol: string]: IDataProviderResponse; [symbol: string]: IDataProviderResponse;
} = {}; } = {};
const startTimeTotal = performance.now();
const itemsGroupedByDataSource = groupBy(items, (item) => item.dataSource); const itemsGroupedByDataSource = groupBy(items, (item) => item.dataSource);
@ -176,25 +177,59 @@ export class DataProviderService {
for (const [dataSource, dataGatheringItems] of Object.entries( for (const [dataSource, dataGatheringItems] of Object.entries(
itemsGroupedByDataSource itemsGroupedByDataSource
)) { )) {
const dataProvider = this.getDataProvider(DataSource[dataSource]);
const symbols = dataGatheringItems.map((dataGatheringItem) => { const symbols = dataGatheringItems.map((dataGatheringItem) => {
return dataGatheringItem.symbol; return dataGatheringItem.symbol;
}); });
const promise = Promise.resolve( const maximumNumberOfSymbolsPerRequest =
this.getDataProvider(DataSource[dataSource]).getQuotes(symbols) dataProvider.getMaxNumberOfSymbolsPerRequest?.() ??
); Number.MAX_SAFE_INTEGER;
for (
let i = 0;
i < symbols.length;
i += maximumNumberOfSymbolsPerRequest
) {
const startTimeDataSource = performance.now();
const symbolsChunk = symbols.slice(
i,
i + maximumNumberOfSymbolsPerRequest
);
promises.push( const promise = Promise.resolve(dataProvider.getQuotes(symbolsChunk));
promise.then((result) => {
for (const [symbol, dataProviderResponse] of Object.entries(result)) { promises.push(
response[symbol] = dataProviderResponse; promise.then((result) => {
} for (const [symbol, dataProviderResponse] of Object.entries(
}) result
); )) {
response[symbol] = dataProviderResponse;
}
Logger.debug(
`Fetched ${symbolsChunk.length} quotes from ${dataSource} in ${(
(performance.now() - startTimeDataSource) /
1000
).toFixed(3)} seconds`
);
})
);
}
} }
await Promise.all(promises); await Promise.all(promises);
Logger.debug('------------------------------------------------');
Logger.debug(
`Fetched ${items.length} quotes in ${(
(performance.now() - startTimeTotal) /
1000
).toFixed(3)} seconds`
);
Logger.debug('================================================');
return response; return response;
} }

@ -81,6 +81,12 @@ export class EodHistoricalDataService implements DataProviderInterface {
} }
} }
public getMaxNumberOfSymbolsPerRequest() {
// It is not recommended using more than 15-20 tickers per request
// https://eodhistoricaldata.com/financial-apis/live-realtime-stocks-api
return 20;
}
public getName(): DataSource { public getName(): DataSource {
return DataSource.EOD_HISTORICAL_DATA; return DataSource.EOD_HISTORICAL_DATA;
} }

@ -20,6 +20,8 @@ export interface DataProviderInterface {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}>; // TODO: Return only one symbol }>; // TODO: Return only one symbol
getMaxNumberOfSymbolsPerRequest?(): number;
getName(): DataSource; getName(): DataSource;
getQuotes( getQuotes(

@ -208,6 +208,10 @@ export class YahooFinanceService implements DataProviderInterface {
} }
} }
public getMaxNumberOfSymbolsPerRequest() {
return 50;
}
public getName(): DataSource { public getName(): DataSource {
return DataSource.YAHOO; return DataSource.YAHOO;
} }

Loading…
Cancel
Save