jenkins
2022-12-20 06:14:05 +00:00
parent 58407be459
commit 0205b185d0
485 changed files with 3253 additions and 1768 deletions

View File

@@ -30,16 +30,20 @@ const enum UpdateTimeouts {
General = 60 * 1000,
}
interface Timers {
fastTimer: number;
generalTimer: number;
}
export class QuotesPulseProvider {
private readonly _quotesProvider: IQuotesProvider;
private readonly _subscribers: QuoteSubscribers = {};
private _requestsPending: number = 0;
private _timers: Timers | null = null;
public constructor(quotesProvider: IQuotesProvider) {
this._quotesProvider = quotesProvider;
setInterval(this._updateQuotes.bind(this, SymbolsType.Fast), UpdateTimeouts.Fast);
setInterval(this._updateQuotes.bind(this, SymbolsType.General), UpdateTimeouts.General);
}
public subscribeQuotes(symbols: string[], fastSymbols: string[], onRealtimeCallback: QuotesCallback, listenerGuid: string): void {
@@ -48,15 +52,34 @@ export class QuotesPulseProvider {
fastSymbols: fastSymbols,
listener: onRealtimeCallback,
};
this._createTimersIfRequired();
logMessage(`QuotesPulseProvider: subscribed quotes with #${listenerGuid}`);
}
public unsubscribeQuotes(listenerGuid: string): void {
delete this._subscribers[listenerGuid];
if (Object.keys(this._subscribers).length === 0) {
this._destroyTimers();
}
logMessage(`QuotesPulseProvider: unsubscribed quotes with #${listenerGuid}`);
}
private _createTimersIfRequired(): void {
if (this._timers === null) {
const fastTimer = setInterval(this._updateQuotes.bind(this, SymbolsType.Fast), UpdateTimeouts.Fast);
const generalTimer = setInterval(this._updateQuotes.bind(this, SymbolsType.General), UpdateTimeouts.General);
this._timers = { fastTimer, generalTimer };
}
}
private _destroyTimers(): void {
if (this._timers !== null) {
clearInterval(this._timers.fastTimer);
clearInterval(this._timers.generalTimer);
this._timers = null;
}
}
private _updateQuotes(updateType: SymbolsType): void {
if (this._requestsPending > 0) {
return;

View File

@@ -18,6 +18,7 @@ import {
SubscribeBarsCallback,
TimescaleMark,
SymbolResolveExtension,
VisiblePlotsSet,
} from '../../../charting_library/datafeed-api';
import {
@@ -48,6 +49,32 @@ export interface UdfCompatibleConfiguration extends DatafeedConfiguration {
export interface ResolveSymbolResponse extends LibrarySymbolInfo {
s: undefined;
'exchange-listed': string;
'exchange-traded': string;
'currency-code': string;
'unit-id': string;
'original-currency-code': string;
'original-unit-id': string;
'unit-conversion-types': string[];
'has-intraday': boolean;
'has-no-volume': boolean;
'visible-plots-set'?: VisiblePlotsSet;
minmovement: number;
minmovement2?: number;
minmov2?: number;
'session-regular': string;
'session-holidays': string;
'supported-resolutions': ResolutionString[];
'has-daily': boolean;
'intraday-multipliers': string[];
'has-weekly-and-monthly'?: boolean;
'has-empty-bars'?: boolean;
'volume-precision'?: number;
}
// it is hack to let's TypeScript make code flow analysis
@@ -286,7 +313,40 @@ export class UDFCompatibleDatafeedBase implements IExternalDatafeed, IDatafeedQu
if (response.s !== undefined) {
onError('unknown_symbol');
} else {
onResultReady(response);
const symbol = response.name;
const listedExchange = response.listed_exchange ?? response['exchange-listed'];
const tradedExchange = response.exchange ?? response['exchange-traded'];
const fullName = response.full_name ?? `${tradedExchange}:${symbol}`;
const result: LibrarySymbolInfo = {
...response,
name: symbol,
base_name: [listedExchange + ':' + symbol],
full_name: fullName,
listed_exchange: listedExchange,
exchange: tradedExchange,
currency_code: response.currency_code ?? response['currency-code'],
original_currency_code: response.original_currency_code ?? response['original-currency-code'],
unit_id: response.unit_id ?? response['unit-id'],
original_unit_id: response.original_unit_id ?? response['original-unit-id'],
unit_conversion_types: response.unit_conversion_types ?? response['unit-conversion-types'],
has_intraday: response.has_intraday ?? response['has-intraday'] ?? false,
// tslint:disable-next-line: no-deprecation
has_no_volume: response.has_no_volume ?? response['has-no-volume'],
visible_plots_set: response.visible_plots_set ?? response['visible-plots-set'],
minmov: response.minmovement ?? response.minmov ?? 0,
minmove2: response.minmovement2 ?? response.minmove2 ?? response.minmov2,
session: response.session ?? response['session-regular'],
session_holidays: response.session_holidays ?? response['session-holidays'],
supported_resolutions: response.supported_resolutions ?? response['supported-resolutions'] ?? this._configuration.supported_resolutions ?? [],
has_daily: response.has_daily ?? response['has-daily'] ?? true,
intraday_multipliers: response.intraday_multipliers ?? response['intraday-multipliers'] ?? ['1', '5', '15', '30', '60'],
has_weekly_and_monthly: response.has_weekly_and_monthly ?? response['has-weekly-and-monthly'],
has_empty_bars: response.has_empty_bars ?? response['has-empty-bars'],
volume_precision: response.volume_precision ?? response['volume-precision'],
format: response.format ?? 'price',
};
onResultReady(result);
}
})
.catch((reason?: string | Error) => {