@xbbg/core 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js ADDED
@@ -0,0 +1,1427 @@
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+ const packageJson = require('./package.json');
4
+ const { tableFromIPC } = require('apache-arrow');
5
+ const { resolveNativeAddon } = require('./lib/resolve-native');
6
+ const {
7
+ wrapError,
8
+ BlpError,
9
+ BlpSessionError,
10
+ BlpRequestError,
11
+ BlpValidationError,
12
+ BlpTimeoutError,
13
+ BlpInternalError,
14
+ } = require('./errors');
15
+
16
+ function containsBlpapiRuntime(dir) {
17
+ if (!dir || !fs.existsSync(dir)) {
18
+ return false;
19
+ }
20
+ return [
21
+ 'blpapi3_64.dll',
22
+ 'blpapi3_32.dll',
23
+ 'libblpapi3.dylib',
24
+ 'libblpapi3_64.so',
25
+ 'libblpapi3.so',
26
+ ].some((name) => fs.existsSync(path.join(dir, name)));
27
+ }
28
+
29
+ function configureRuntimeSearchPath() {
30
+ if (process.platform !== 'win32') {
31
+ return;
32
+ }
33
+
34
+ const candidates = [];
35
+ if (process.env.BLPAPI_LIB_DIR) {
36
+ candidates.push(path.resolve(process.env.BLPAPI_LIB_DIR));
37
+ }
38
+ if (process.env.BLPAPI_ROOT) {
39
+ const root = path.resolve(process.env.BLPAPI_ROOT);
40
+ candidates.push(root, path.join(root, 'bin'), path.join(root, 'lib'));
41
+ }
42
+
43
+ for (const candidate of candidates) {
44
+ if (!containsBlpapiRuntime(candidate)) {
45
+ continue;
46
+ }
47
+ const currentPath = process.env.PATH || '';
48
+ const parts = currentPath.split(';').filter(Boolean);
49
+ if (!parts.includes(candidate)) {
50
+ process.env.PATH = currentPath
51
+ ? `${candidate};${currentPath}`
52
+ : candidate;
53
+ }
54
+ break;
55
+ }
56
+ }
57
+
58
+ configureRuntimeSearchPath();
59
+
60
+ function loadNative() {
61
+ const root = path.resolve(__dirname, '..');
62
+
63
+ const candidates = [
64
+ path.join(__dirname, 'napi_xbbg.node'),
65
+ path.join(__dirname, 'napi-xbbg.node'),
66
+ ];
67
+
68
+ for (const candidate of candidates) {
69
+ if (fs.existsSync(candidate)) {
70
+ return require(candidate);
71
+ }
72
+ }
73
+
74
+ const { key, packageName, binaryPath } = resolveNativeAddon(root);
75
+ if (binaryPath) {
76
+ return require(binaryPath);
77
+ }
78
+ if (!packageName) {
79
+ throw new Error(
80
+ `No packaged @xbbg/core native addon is available for ${key}. Build it locally with "npm run build" from js-xbbg.`,
81
+ );
82
+ }
83
+
84
+ throw new Error(
85
+ `Unable to load native napi-xbbg module for ${key}. Install ${packageName} via Bun/npm, or build it locally with "npm run build" from js-xbbg.`,
86
+ );
87
+ }
88
+
89
+ const native = loadNative();
90
+
91
+ const Backend = Object.freeze({
92
+ ARROW: 'arrow',
93
+ JSON: 'json',
94
+ POLARS: 'polars',
95
+ });
96
+
97
+ const Format = Object.freeze({
98
+ LONG: 'long',
99
+ LONG_TYPED: 'long_typed',
100
+ LONG_WITH_METADATA: 'long_with_metadata',
101
+ SEMI_LONG: 'semi_long',
102
+ });
103
+
104
+ function toArrowTable(ipcBuffer) {
105
+ return tableFromIPC(ipcBuffer);
106
+ }
107
+
108
+ function mapObjectToPairs(obj) {
109
+ if (!obj) {
110
+ return undefined;
111
+ }
112
+ return Object.entries(obj).map(([key, value]) => ({
113
+ key: String(key),
114
+ value: String(value),
115
+ }));
116
+ }
117
+
118
+ const CDX_INFO_FIELDS = Object.freeze([
119
+ 'ROLLING_SERIES',
120
+ 'VERSION',
121
+ 'ON_THE_RUN_CURRENT_BD_INDICATOR',
122
+ 'CDS_FIRST_ACCRUAL_START_DATE',
123
+ 'NAME',
124
+ 'NUM_CURRENT_COMPANIES_CCY_TKR',
125
+ 'NUM_ORIG_COMPANIES_CRNCY_TKR',
126
+ 'PX_LAST',
127
+ ]);
128
+
129
+ const CDX_PRICING_FIELDS = Object.freeze([
130
+ 'PX_LAST',
131
+ 'PX_BID',
132
+ 'PX_ASK',
133
+ 'UPFRONT_LAST',
134
+ 'UPFRONT_BID',
135
+ 'UPFRONT_ASK',
136
+ 'CDS_FLAT_SPREAD',
137
+ 'UPFRONT_FEE',
138
+ 'PV_CDS_PREMIUM_LEG',
139
+ 'PV_CDS_DEFAULT_LEG',
140
+ ]);
141
+
142
+ const CDX_RISK_FIELDS = Object.freeze([
143
+ 'SW_CNV_BPV',
144
+ 'SW_EQV_BPV',
145
+ 'CDS_SPREAD_MID_MODIFIED_DURATION',
146
+ 'CDS_SPREAD_MID_CONVEXITY',
147
+ 'RECOVERY_RATE_SEN',
148
+ 'CDS_RECOVERY_RT',
149
+ ]);
150
+
151
+ function isPlainObject(value) {
152
+ return value != null && typeof value === 'object' && !Array.isArray(value);
153
+ }
154
+
155
+ function toStringArray(value) {
156
+ if (Array.isArray(value)) {
157
+ return value.map((item) => String(item));
158
+ }
159
+ if (value == null) {
160
+ return [];
161
+ }
162
+ return [String(value)];
163
+ }
164
+
165
+ function normalizeConfigureArgs(configOrHost = undefined, port = undefined) {
166
+ if (configOrHost == null) {
167
+ return undefined;
168
+ }
169
+ if (typeof configOrHost === 'string' || port !== undefined) {
170
+ const config = {};
171
+ if (configOrHost != null) {
172
+ config.host = String(configOrHost);
173
+ }
174
+ if (port != null) {
175
+ config.port = Number(port);
176
+ }
177
+ return config;
178
+ }
179
+ if (isPlainObject(configOrHost)) {
180
+ return { ...configOrHost };
181
+ }
182
+ throw new TypeError(
183
+ 'configure expects either a config object or host/port arguments',
184
+ );
185
+ }
186
+
187
+ function normalizeRecoveryOptions(options = {}) {
188
+ const normalized = { ...options };
189
+ const recoveryRate = normalized.recoveryRate ?? normalized.recovery_rate;
190
+ delete normalized.recoveryRate;
191
+ delete normalized.recovery_rate;
192
+ if (recoveryRate != null) {
193
+ normalized.overrides = {
194
+ ...(normalized.overrides || {}),
195
+ CDS_RR: String(recoveryRate),
196
+ };
197
+ }
198
+ return normalized;
199
+ }
200
+
201
+ function fullDayRange(dt) {
202
+ const normalized = String(dt).trim().replace(' ', 'T');
203
+ const day = normalized.split('T')[0];
204
+ if (!day) {
205
+ throw new TypeError('dt must be a non-empty ISO date string');
206
+ }
207
+ return {
208
+ start: `${day}T00:00:00`,
209
+ end: `${day}T23:59:59`,
210
+ };
211
+ }
212
+
213
+ let configuredEngineConfig;
214
+ let configuredEnginePromise;
215
+
216
+ function clearConfiguredEngine() {
217
+ const existing = configuredEnginePromise;
218
+ configuredEnginePromise = undefined;
219
+ if (existing) {
220
+ existing.then((engine) => engine.signalShutdown()).catch(() => {});
221
+ }
222
+ }
223
+
224
+ async function getConfiguredEngine() {
225
+ if (!configuredEnginePromise) {
226
+ const pending = connect(configuredEngineConfig);
227
+ pending.catch(() => {
228
+ if (configuredEnginePromise === pending) {
229
+ configuredEnginePromise = undefined;
230
+ }
231
+ });
232
+ configuredEnginePromise = pending;
233
+ }
234
+ return configuredEnginePromise;
235
+ }
236
+
237
+ const TA_STUDIES = Object.freeze({
238
+ smavg: 'smavgStudyAttributes',
239
+ sma: 'smavgStudyAttributes',
240
+ emavg: 'emavgStudyAttributes',
241
+ ema: 'emavgStudyAttributes',
242
+ wmavg: 'wmavgStudyAttributes',
243
+ wma: 'wmavgStudyAttributes',
244
+ vmavg: 'vmavgStudyAttributes',
245
+ vma: 'vmavgStudyAttributes',
246
+ tmavg: 'tmavgStudyAttributes',
247
+ tma: 'tmavgStudyAttributes',
248
+ ipmavg: 'ipmavgStudyAttributes',
249
+ rsi: 'rsiStudyAttributes',
250
+ macd: 'macdStudyAttributes',
251
+ mao: 'maoStudyAttributes',
252
+ momentum: 'momentumStudyAttributes',
253
+ mom: 'momentumStudyAttributes',
254
+ roc: 'rocStudyAttributes',
255
+ boll: 'bollStudyAttributes',
256
+ bb: 'bollStudyAttributes',
257
+ kltn: 'kltnStudyAttributes',
258
+ keltner: 'kltnStudyAttributes',
259
+ mae: 'maeStudyAttributes',
260
+ te: 'teStudyAttributes',
261
+ al: 'alStudyAttributes',
262
+ dmi: 'dmiStudyAttributes',
263
+ adx: 'dmiStudyAttributes',
264
+ tas: 'tasStudyAttributes',
265
+ stoch: 'tasStudyAttributes',
266
+ trender: 'trenderStudyAttributes',
267
+ ptps: 'ptpsStudyAttributes',
268
+ parabolic: 'ptpsStudyAttributes',
269
+ sar: 'ptpsStudyAttributes',
270
+ chko: 'chkoStudyAttributes',
271
+ ado: 'adoStudyAttributes',
272
+ vat: 'vatStudyAttributes',
273
+ tvat: 'tvatStudyAttributes',
274
+ atr: 'atrStudyAttributes',
275
+ hurst: 'hurstStudyAttributes',
276
+ fg: 'fgStudyAttributes',
277
+ fear_greed: 'fgStudyAttributes',
278
+ goc: 'gocStudyAttributes',
279
+ ichimoku: 'gocStudyAttributes',
280
+ cmci: 'cmciStudyAttributes',
281
+ wlpr: 'wlprStudyAttributes',
282
+ williams: 'wlprStudyAttributes',
283
+ maxmin: 'maxminStudyAttributes',
284
+ rex: 'rexStudyAttributes',
285
+ etd: 'etdStudyAttributes',
286
+ pd: 'pdStudyAttributes',
287
+ rv: 'rvStudyAttributes',
288
+ pivot: 'pivotStudyAttributes',
289
+ or: 'orStudyAttributes',
290
+ pcr: 'pcrStudyAttributes',
291
+ bs: 'bsStudyAttributes',
292
+ });
293
+
294
+ const TA_DEFAULTS = Object.freeze({
295
+ smavgStudyAttributes: Object.freeze({
296
+ period: 20,
297
+ priceSourceClose: 'PX_LAST',
298
+ }),
299
+ emavgStudyAttributes: Object.freeze({
300
+ period: 20,
301
+ priceSourceClose: 'PX_LAST',
302
+ }),
303
+ wmavgStudyAttributes: Object.freeze({
304
+ period: 20,
305
+ priceSourceClose: 'PX_LAST',
306
+ }),
307
+ vmavgStudyAttributes: Object.freeze({
308
+ period: 20,
309
+ priceSourceClose: 'PX_LAST',
310
+ }),
311
+ tmavgStudyAttributes: Object.freeze({
312
+ period: 20,
313
+ priceSourceClose: 'PX_LAST',
314
+ }),
315
+ rsiStudyAttributes: Object.freeze({
316
+ period: 14,
317
+ priceSourceClose: 'PX_LAST',
318
+ }),
319
+ macdStudyAttributes: Object.freeze({
320
+ maPeriod1: 12,
321
+ maPeriod2: 26,
322
+ sigPeriod: 9,
323
+ priceSourceClose: 'PX_LAST',
324
+ }),
325
+ bollStudyAttributes: Object.freeze({
326
+ period: 20,
327
+ upperBand: 2.0,
328
+ lowerBand: 2.0,
329
+ priceSourceClose: 'PX_LAST',
330
+ }),
331
+ dmiStudyAttributes: Object.freeze({
332
+ period: 14,
333
+ priceSourceHigh: 'PX_HIGH',
334
+ priceSourceLow: 'PX_LOW',
335
+ priceSourceClose: 'PX_LAST',
336
+ }),
337
+ atrStudyAttributes: Object.freeze({
338
+ maType: 'Simple',
339
+ period: 14,
340
+ priceSourceHigh: 'PX_HIGH',
341
+ priceSourceLow: 'PX_LOW',
342
+ priceSourceClose: 'PX_LAST',
343
+ }),
344
+ tasStudyAttributes: Object.freeze({
345
+ periodK: 14,
346
+ periodD: 3,
347
+ periodDS: 3,
348
+ periodDSS: 3,
349
+ priceSourceHigh: 'PX_HIGH',
350
+ priceSourceLow: 'PX_LOW',
351
+ priceSourceClose: 'PX_LAST',
352
+ }),
353
+ });
354
+
355
+ function normalizeDate(value) {
356
+ return value == null ? undefined : String(value).replace(/[-/]/g, '');
357
+ }
358
+
359
+ function getStudyAttrName(study) {
360
+ const normalized = String(study)
361
+ .toLowerCase()
362
+ .replace(/-/g, '_')
363
+ .replace(/ /g, '_');
364
+ if (TA_STUDIES[normalized]) {
365
+ return TA_STUDIES[normalized];
366
+ }
367
+ if (normalized.endsWith('studyattributes')) {
368
+ return normalized;
369
+ }
370
+ return `${normalized}StudyAttributes`;
371
+ }
372
+
373
+ function buildTaRequest(ticker, study, options = {}) {
374
+ const rawStudy =
375
+ typeof study === 'string' ? { studyType: study } : { ...study };
376
+ const studyType = rawStudy.studyType || rawStudy.study || study;
377
+ const attrName = getStudyAttrName(studyType);
378
+
379
+ const kwargs = { ...(options.kwargs || {}) };
380
+ const startDate = normalizeDate(
381
+ kwargs.startDate ||
382
+ kwargs.start_date ||
383
+ options.startDate ||
384
+ options.start_date,
385
+ );
386
+ const endDate = normalizeDate(
387
+ kwargs.endDate || kwargs.end_date || options.endDate || options.end_date,
388
+ );
389
+ const periodicity = String(
390
+ kwargs.periodicitySelection ||
391
+ kwargs.periodicity ||
392
+ rawStudy.calcInterval ||
393
+ options.periodicity ||
394
+ 'DAILY',
395
+ ).toUpperCase();
396
+ const interval = kwargs.interval || rawStudy.interval || options.interval;
397
+
398
+ delete kwargs.startDate;
399
+ delete kwargs.start_date;
400
+ delete kwargs.endDate;
401
+ delete kwargs.end_date;
402
+ delete kwargs.periodicitySelection;
403
+ delete kwargs.periodicity;
404
+ delete rawStudy.studyType;
405
+ delete rawStudy.study;
406
+ delete rawStudy.calcInterval;
407
+
408
+ if (rawStudy.length != null && rawStudy.period == null) {
409
+ rawStudy.period = rawStudy.length;
410
+ }
411
+ delete rawStudy.length;
412
+
413
+ const params = {
414
+ ...(TA_DEFAULTS[attrName] || {}),
415
+ ...(options.studyParams || {}),
416
+ ...rawStudy,
417
+ };
418
+
419
+ if (params.length != null && params.period == null) {
420
+ params.period = params.length;
421
+ }
422
+ delete params.length;
423
+ delete params.calcInterval;
424
+
425
+ const elements = [{ key: 'priceSource.securityName', value: String(ticker) }];
426
+
427
+ if (periodicity === 'INTRADAY') {
428
+ const prefix = 'priceSource.dataRange.intraday';
429
+ if (startDate)
430
+ elements.push({ key: `${prefix}.startDate`, value: startDate });
431
+ if (endDate) elements.push({ key: `${prefix}.endDate`, value: endDate });
432
+ elements.push({ key: `${prefix}.eventType`, value: 'TRADE' });
433
+ if (interval != null) {
434
+ elements.push({ key: `${prefix}.interval`, value: String(interval) });
435
+ }
436
+ } else {
437
+ const prefix = 'priceSource.dataRange.historical';
438
+ if (startDate)
439
+ elements.push({ key: `${prefix}.startDate`, value: startDate });
440
+ if (endDate) elements.push({ key: `${prefix}.endDate`, value: endDate });
441
+ elements.push({
442
+ key: `${prefix}.periodicitySelection`,
443
+ value: periodicity,
444
+ });
445
+ }
446
+
447
+ for (const [key, value] of Object.entries(params)) {
448
+ if (value == null) continue;
449
+ elements.push({
450
+ key: `studyAttributes.${attrName}.${key}`,
451
+ value: String(value),
452
+ });
453
+ }
454
+
455
+ for (const [key, value] of Object.entries(kwargs)) {
456
+ if (value == null) continue;
457
+ elements.push({ key: String(key), value: String(value) });
458
+ }
459
+
460
+ return elements;
461
+ }
462
+
463
+ class Subscription {
464
+ constructor(inner) {
465
+ this._inner = inner;
466
+ }
467
+
468
+ async next() {
469
+ try {
470
+ const batch = await this._inner.next();
471
+ if (batch == null) {
472
+ return { done: true, value: undefined };
473
+ }
474
+ return { done: false, value: toArrowTable(batch) };
475
+ } catch (err) {
476
+ throw wrapError(err);
477
+ }
478
+ }
479
+
480
+ async add(tickers) {
481
+ try {
482
+ await this._inner.add(tickers);
483
+ } catch (err) {
484
+ throw wrapError(err);
485
+ }
486
+ }
487
+
488
+ async remove(tickers) {
489
+ try {
490
+ await this._inner.remove(tickers);
491
+ } catch (err) {
492
+ throw wrapError(err);
493
+ }
494
+ }
495
+
496
+ async unsubscribe(drain = false) {
497
+ const drained = await this._inner.unsubscribe(Boolean(drain));
498
+ if (!drained) {
499
+ return [];
500
+ }
501
+ return drained.map(toArrowTable);
502
+ }
503
+
504
+ get tickers() {
505
+ return this._inner.tickers;
506
+ }
507
+
508
+ get fields() {
509
+ return this._inner.fields;
510
+ }
511
+
512
+ get isActive() {
513
+ return this._inner.isActive;
514
+ }
515
+
516
+ get stats() {
517
+ return this._inner.stats;
518
+ }
519
+
520
+ [Symbol.asyncIterator]() {
521
+ return this;
522
+ }
523
+ }
524
+
525
+ class Engine {
526
+ constructor(host = 'localhost', port = 8194) {
527
+ try {
528
+ this._inner = new native.JsEngine(host, port);
529
+ } catch (err) {
530
+ throw wrapError(err);
531
+ }
532
+ }
533
+
534
+ static withConfig(config = {}) {
535
+ const engine = Object.create(Engine.prototype);
536
+ try {
537
+ engine._inner = native.JsEngine.withConfig(config);
538
+ } catch (err) {
539
+ throw wrapError(err);
540
+ }
541
+ return engine;
542
+ }
543
+
544
+ async request(params) {
545
+ const backend = params.backend || Backend.ARROW;
546
+ const { backend: _b, ...nativeParams } = params;
547
+ try {
548
+ const buffer = await this._inner.request(nativeParams);
549
+ if (backend === Backend.JSON) {
550
+ return Array.from(tableFromIPC(buffer));
551
+ }
552
+ if (backend === Backend.POLARS) {
553
+ let pl;
554
+ try {
555
+ pl = require('nodejs-polars');
556
+ } catch {
557
+ throw new Error(
558
+ 'nodejs-polars is required for Polars backend. Install: npm install nodejs-polars',
559
+ );
560
+ }
561
+ return pl.readIPC(buffer);
562
+ }
563
+ return tableFromIPC(buffer);
564
+ } catch (err) {
565
+ throw wrapError(err);
566
+ }
567
+ }
568
+
569
+ async requestRaw(params) {
570
+ try {
571
+ return await this._inner.request(params);
572
+ } catch (err) {
573
+ throw wrapError(err);
574
+ }
575
+ }
576
+
577
+ async bdp(tickers, fields, options = {}) {
578
+ return this.request({
579
+ service: '//blp/refdata',
580
+ operation: 'ReferenceDataRequest',
581
+ securities: tickers,
582
+ fields,
583
+ overrides: mapObjectToPairs(options.overrides),
584
+ kwargs: mapObjectToPairs(options.kwargs),
585
+ format: options.format,
586
+ backend: options.backend,
587
+ includeSecurityErrors: Boolean(options.includeSecurityErrors),
588
+ extractor: 'refdata',
589
+ });
590
+ }
591
+
592
+ async bds(tickers, fields, options = {}) {
593
+ return this.request({
594
+ service: '//blp/refdata',
595
+ operation: 'ReferenceDataRequest',
596
+ securities: tickers,
597
+ fields,
598
+ overrides: mapObjectToPairs(options.overrides),
599
+ kwargs: mapObjectToPairs(options.kwargs),
600
+ format: options.format,
601
+ backend: options.backend,
602
+ extractor: 'bulk',
603
+ });
604
+ }
605
+
606
+ async bdh(tickers, fields, options = {}) {
607
+ return this.request({
608
+ service: '//blp/refdata',
609
+ operation: 'HistoricalDataRequest',
610
+ securities: tickers,
611
+ fields,
612
+ startDate: options.start,
613
+ endDate: options.end,
614
+ overrides: mapObjectToPairs(options.overrides),
615
+ kwargs: mapObjectToPairs(options.kwargs),
616
+ format: options.format,
617
+ backend: options.backend,
618
+ extractor: 'histdata',
619
+ });
620
+ }
621
+
622
+ async bdib(ticker, options = {}) {
623
+ return this.request({
624
+ service: '//blp/refdata',
625
+ operation: 'IntradayBarRequest',
626
+ security: ticker,
627
+ eventType: options.eventType || 'TRADE',
628
+ interval: options.interval || 1,
629
+ startDatetime: options.start,
630
+ endDatetime: options.end,
631
+ kwargs: mapObjectToPairs(options.kwargs),
632
+ backend: options.backend,
633
+ extractor: 'intraday_bar',
634
+ });
635
+ }
636
+
637
+ async bdtick(ticker, options = {}) {
638
+ return this.request({
639
+ service: '//blp/refdata',
640
+ operation: 'IntradayTickRequest',
641
+ security: ticker,
642
+ eventTypes: options.eventTypes || ['TRADE'],
643
+ startDatetime: options.start,
644
+ endDatetime: options.end,
645
+ kwargs: mapObjectToPairs(options.kwargs),
646
+ backend: options.backend,
647
+ extractor: 'intraday_tick',
648
+ });
649
+ }
650
+
651
+ async bql(query, options = {}) {
652
+ return this.request({
653
+ service: '//blp/bqlsvc',
654
+ operation: 'sendQuery',
655
+ elements: [{ key: 'expression', value: String(query) }],
656
+ backend: options.backend,
657
+ kwargs: mapObjectToPairs(options.kwargs),
658
+ format: options.format,
659
+ extractor: 'bql',
660
+ });
661
+ }
662
+
663
+ async beqs(screen, options = {}) {
664
+ const elements = [
665
+ { key: 'screenName', value: String(screen) },
666
+ { key: 'screenType', value: String(options.screenType || 'PRIVATE') },
667
+ { key: 'Group', value: String(options.group || 'General') },
668
+ ];
669
+ if (options.asof)
670
+ elements.push({ key: 'asOfDate', value: String(options.asof) });
671
+ const overrides = {
672
+ ...(options.overrides || {}),
673
+ };
674
+ return this.request({
675
+ service: '//blp/refdata',
676
+ operation: 'BeqsRequest',
677
+ elements,
678
+ backend: options.backend,
679
+ kwargs: mapObjectToPairs(options.kwargs),
680
+ overrides: mapObjectToPairs(overrides),
681
+ format: options.format,
682
+ extractor: 'generic',
683
+ });
684
+ }
685
+
686
+ async bsrch(searchSpec, options = {}) {
687
+ const elements = {
688
+ Domain: String(searchSpec),
689
+ ...(options.overrides || {}),
690
+ ...(options.kwargs || {}),
691
+ };
692
+ return this.request({
693
+ service: '//blp/exrsvc',
694
+ operation: 'ExcelGetGridRequest',
695
+ backend: options.backend,
696
+ elements: mapObjectToPairs(elements),
697
+ format: options.format,
698
+ extractor: 'bsrch',
699
+ });
700
+ }
701
+
702
+ async bta(ticker, study, options = {}) {
703
+ return this.request({
704
+ service: '//blp/tasvc',
705
+ operation: 'studyRequest',
706
+ elements: buildTaRequest(ticker, study, options),
707
+ backend: options.backend,
708
+ format: options.format,
709
+ extractor: 'generic',
710
+ });
711
+ }
712
+
713
+ async bflds(options = {}) {
714
+ if (options.searchSpec) {
715
+ return this.request({
716
+ service: '//blp/apiflds',
717
+ operation: 'FieldSearchRequest',
718
+ searchSpec: String(options.searchSpec),
719
+ backend: options.backend,
720
+ kwargs: mapObjectToPairs(options.kwargs),
721
+ format: options.format,
722
+ });
723
+ }
724
+ const fields = Array.isArray(options.fields)
725
+ ? options.fields
726
+ : options.fields
727
+ ? [options.fields]
728
+ : [];
729
+ return this.request({
730
+ service: '//blp/apiflds',
731
+ operation: 'FieldInfoRequest',
732
+ fieldIds: fields,
733
+ backend: options.backend,
734
+ kwargs: mapObjectToPairs(options.kwargs),
735
+ format: options.format,
736
+ });
737
+ }
738
+
739
+ async blkp(query, options = {}) {
740
+ return this.request({
741
+ service: '//blp/instruments',
742
+ operation: 'instrumentListRequest',
743
+ elements: [{ key: 'query', value: String(query) }],
744
+ backend: options.backend,
745
+ kwargs: mapObjectToPairs(options.kwargs),
746
+ format: options.format,
747
+ });
748
+ }
749
+
750
+ async bport(portfolio, fields, options = {}) {
751
+ return this.request({
752
+ service: '//blp/refdata',
753
+ operation: 'PortfolioDataRequest',
754
+ security: String(portfolio),
755
+ fields: Array.isArray(fields) ? fields : [fields],
756
+ backend: options.backend,
757
+ overrides: mapObjectToPairs(options.overrides),
758
+ kwargs: mapObjectToPairs(options.kwargs),
759
+ format: options.format,
760
+ });
761
+ }
762
+
763
+ async bcurves(ticker, options = {}) {
764
+ return this.request({
765
+ service: '//blp/instruments',
766
+ operation: 'curveListRequest',
767
+ elements: [{ key: 'query', value: String(ticker) }],
768
+ backend: options.backend,
769
+ kwargs: mapObjectToPairs(options.kwargs),
770
+ format: options.format,
771
+ });
772
+ }
773
+
774
+ async bgovts(ticker, options = {}) {
775
+ return this.request({
776
+ service: '//blp/instruments',
777
+ operation: 'govtListRequest',
778
+ elements: [{ key: 'query', value: String(ticker) }],
779
+ backend: options.backend,
780
+ kwargs: mapObjectToPairs(options.kwargs),
781
+ format: options.format,
782
+ });
783
+ }
784
+
785
+ async resolveFieldTypes(
786
+ fields,
787
+ overrides = undefined,
788
+ defaultType = 'string',
789
+ ) {
790
+ const items = await this._inner.resolveFieldTypes(
791
+ fields,
792
+ mapObjectToPairs(overrides),
793
+ defaultType,
794
+ );
795
+ return Object.fromEntries(items.map((item) => [item.key, item.value]));
796
+ }
797
+
798
+ getFieldInfo(field) {
799
+ return this._inner.getFieldInfo(field);
800
+ }
801
+
802
+ clearFieldCache() {
803
+ this._inner.clearFieldCache();
804
+ }
805
+
806
+ saveFieldCache() {
807
+ return this._inner.saveFieldCache();
808
+ }
809
+
810
+ validateFields(fields) {
811
+ return this._inner.validateFields(fields);
812
+ }
813
+
814
+ isFieldValidationEnabled() {
815
+ return this._inner.isFieldValidationEnabled();
816
+ }
817
+
818
+ getSchema(service) {
819
+ return this._inner.getSchema(service).then((json) => JSON.parse(json));
820
+ }
821
+
822
+ getOperation(service, operation) {
823
+ return this._inner
824
+ .getOperation(service, operation)
825
+ .then((json) => JSON.parse(json));
826
+ }
827
+
828
+ listOperations(service) {
829
+ return this._inner.listOperations(service);
830
+ }
831
+
832
+ getCachedSchema(service) {
833
+ const json = this._inner.getCachedSchema(service);
834
+ return json ? JSON.parse(json) : null;
835
+ }
836
+
837
+ invalidateSchema(service) {
838
+ this._inner.invalidateSchema(service);
839
+ }
840
+
841
+ clearSchemaCache() {
842
+ this._inner.clearSchemaCache();
843
+ }
844
+
845
+ listCachedSchemas() {
846
+ return this._inner.listCachedSchemas();
847
+ }
848
+
849
+ getEnumValues(service, operation, element) {
850
+ return this._inner.getEnumValues(service, operation, element);
851
+ }
852
+
853
+ listValidElements(service, operation) {
854
+ return this._inner.listValidElements(service, operation);
855
+ }
856
+
857
+ async subscribe(tickers, fields) {
858
+ try {
859
+ const stream = await this._inner.subscribe(tickers, fields);
860
+ return new Subscription(stream);
861
+ } catch (err) {
862
+ throw wrapError(err);
863
+ }
864
+ }
865
+
866
+ async subscribeWithOptions(
867
+ service,
868
+ tickers,
869
+ fields,
870
+ options = undefined,
871
+ flushThreshold = undefined,
872
+ overflowPolicy = undefined,
873
+ streamCapacity = undefined,
874
+ ) {
875
+ try {
876
+ const stream = await this._inner.subscribeWithOptions(
877
+ service,
878
+ tickers,
879
+ fields,
880
+ options,
881
+ flushThreshold,
882
+ overflowPolicy,
883
+ streamCapacity,
884
+ );
885
+ return new Subscription(stream);
886
+ } catch (err) {
887
+ throw wrapError(err);
888
+ }
889
+ }
890
+
891
+ signalShutdown() {
892
+ this._inner.signalShutdown();
893
+ }
894
+
895
+ isAvailable() {
896
+ return this._inner.isAvailable();
897
+ }
898
+
899
+ async stream(tickers, fields, options = {}) {
900
+ return this.subscribeWithOptions(
901
+ '//blp/mktdata',
902
+ tickers,
903
+ fields,
904
+ options.options,
905
+ options.flushThreshold,
906
+ options.overflowPolicy,
907
+ options.streamCapacity,
908
+ );
909
+ }
910
+
911
+ async vwap(tickers, fields, options = {}) {
912
+ return this.subscribeWithOptions(
913
+ '//blp/mktvwap',
914
+ tickers,
915
+ fields,
916
+ options.options,
917
+ options.flushThreshold,
918
+ options.overflowPolicy,
919
+ options.streamCapacity,
920
+ );
921
+ }
922
+
923
+ async mktbar(ticker, options = {}) {
924
+ return this.subscribeWithOptions(
925
+ '//blp/mktbar',
926
+ [ticker],
927
+ options.fields || [],
928
+ options.options,
929
+ options.flushThreshold,
930
+ options.overflowPolicy,
931
+ options.streamCapacity,
932
+ );
933
+ }
934
+
935
+ async depth(ticker, options = {}) {
936
+ return this.subscribeWithOptions(
937
+ '//blp/mktdepthdata',
938
+ [ticker],
939
+ options.fields || [],
940
+ options.options,
941
+ options.flushThreshold,
942
+ options.overflowPolicy,
943
+ options.streamCapacity,
944
+ );
945
+ }
946
+
947
+ async chains(ticker, options = {}) {
948
+ return this.subscribeWithOptions(
949
+ '//blp/mktlist',
950
+ [ticker],
951
+ options.fields || [],
952
+ options.options,
953
+ options.flushThreshold,
954
+ options.overflowPolicy,
955
+ options.streamCapacity,
956
+ );
957
+ }
958
+
959
+ async bops(service) {
960
+ return this._inner.listOperations(service);
961
+ }
962
+
963
+ async bschema(service, operation) {
964
+ if (operation)
965
+ return this._inner
966
+ .getOperation(service, operation)
967
+ .then((json) => JSON.parse(json));
968
+ return this._inner.getSchema(service).then((json) => JSON.parse(json));
969
+ }
970
+
971
+ fieldInfo(fields, options = {}) {
972
+ return this.bflds({
973
+ fields: Array.isArray(fields) ? fields : [fields],
974
+ ...options,
975
+ });
976
+ }
977
+
978
+ fieldSearch(searchSpec, options = {}) {
979
+ return this.bflds({ searchSpec: String(searchSpec), ...options });
980
+ }
981
+
982
+ _ipcToBackend(buffer, backend) {
983
+ if (backend === Backend.JSON) {
984
+ return Array.from(tableFromIPC(buffer));
985
+ }
986
+ if (backend === Backend.POLARS) {
987
+ let pl;
988
+ try {
989
+ pl = require('nodejs-polars');
990
+ } catch {
991
+ throw new Error(
992
+ 'nodejs-polars is required for Polars backend. Install: npm install nodejs-polars',
993
+ );
994
+ }
995
+ return pl.readIPC(buffer);
996
+ }
997
+ return tableFromIPC(buffer);
998
+ }
999
+
1000
+ async bqr(ticker, options = {}) {
1001
+ try {
1002
+ const buffer = await this._inner.recipeBqr(
1003
+ String(ticker),
1004
+ options.startDatetime || undefined,
1005
+ options.endDatetime || undefined,
1006
+ options.eventTypes || null,
1007
+ options.includeBrokerCodes !== false,
1008
+ );
1009
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1010
+ } catch (err) {
1011
+ throw wrapError(err);
1012
+ }
1013
+ }
1014
+
1015
+ async yas(tickers, fields, options = {}) {
1016
+ try {
1017
+ const buffer = await this._inner.recipeYas(
1018
+ toStringArray(tickers),
1019
+ toStringArray(fields),
1020
+ options.settleDt || undefined,
1021
+ options.yieldType ?? undefined,
1022
+ options.spread ?? undefined,
1023
+ options.yieldVal ?? undefined,
1024
+ options.price ?? undefined,
1025
+ options.benchmark || undefined,
1026
+ );
1027
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1028
+ } catch (err) {
1029
+ throw wrapError(err);
1030
+ }
1031
+ }
1032
+
1033
+ async preferreds(equityTicker, options = {}) {
1034
+ try {
1035
+ const buffer = await this._inner.recipePreferreds(
1036
+ String(equityTicker),
1037
+ options.fields ? toStringArray(options.fields) : null,
1038
+ );
1039
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1040
+ } catch (err) {
1041
+ throw wrapError(err);
1042
+ }
1043
+ }
1044
+
1045
+ async corporateBonds(ticker, options = {}) {
1046
+ try {
1047
+ const buffer = await this._inner.recipeCorporateBonds(
1048
+ String(ticker),
1049
+ options.ccy || undefined,
1050
+ options.fields ? toStringArray(options.fields) : null,
1051
+ options.activeOnly !== false,
1052
+ );
1053
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1054
+ } catch (err) {
1055
+ throw wrapError(err);
1056
+ }
1057
+ }
1058
+
1059
+ async futTicker(genTicker, dt, options = {}) {
1060
+ try {
1061
+ const buffer = await this._inner.recipeFutTicker(
1062
+ String(genTicker),
1063
+ String(dt),
1064
+ options.freq || undefined,
1065
+ );
1066
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1067
+ } catch (err) {
1068
+ throw wrapError(err);
1069
+ }
1070
+ }
1071
+
1072
+ async activeFutures(genTicker, dt, options = {}) {
1073
+ try {
1074
+ const buffer = await this._inner.recipeActiveFutures(
1075
+ String(genTicker),
1076
+ String(dt),
1077
+ options.freq || undefined,
1078
+ );
1079
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1080
+ } catch (err) {
1081
+ throw wrapError(err);
1082
+ }
1083
+ }
1084
+
1085
+ async cdxTicker(genTicker, dt, options = {}) {
1086
+ try {
1087
+ const buffer = await this._inner.recipeCdxTicker(
1088
+ String(genTicker),
1089
+ String(dt),
1090
+ );
1091
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1092
+ } catch (err) {
1093
+ throw wrapError(err);
1094
+ }
1095
+ }
1096
+
1097
+ async activeCdx(genTicker, dt, options = {}) {
1098
+ try {
1099
+ const buffer = await this._inner.recipeActiveCdx(
1100
+ String(genTicker),
1101
+ String(dt),
1102
+ options.lookbackDays ?? undefined,
1103
+ );
1104
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1105
+ } catch (err) {
1106
+ throw wrapError(err);
1107
+ }
1108
+ }
1109
+
1110
+ async dividend(tickers, startDate, endDate, options = {}) {
1111
+ try {
1112
+ const buffer = await this._inner.recipeDividend(
1113
+ toStringArray(tickers),
1114
+ String(startDate),
1115
+ String(endDate),
1116
+ options.dvdType || undefined,
1117
+ );
1118
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1119
+ } catch (err) {
1120
+ throw wrapError(err);
1121
+ }
1122
+ }
1123
+
1124
+ async turnover(tickers, startDate, endDate, options = {}) {
1125
+ try {
1126
+ const buffer = await this._inner.recipeTurnover(
1127
+ toStringArray(tickers),
1128
+ String(startDate),
1129
+ String(endDate),
1130
+ options.ccy || undefined,
1131
+ options.factor ?? undefined,
1132
+ );
1133
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1134
+ } catch (err) {
1135
+ throw wrapError(err);
1136
+ }
1137
+ }
1138
+
1139
+ async etfHoldings(etfTicker, options = {}) {
1140
+ try {
1141
+ const buffer = await this._inner.recipeEtfHoldings(
1142
+ String(etfTicker),
1143
+ options.fields ? toStringArray(options.fields) : null,
1144
+ );
1145
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1146
+ } catch (err) {
1147
+ throw wrapError(err);
1148
+ }
1149
+ }
1150
+
1151
+ async currencyConversion(
1152
+ ticker,
1153
+ targetCcy,
1154
+ startDate,
1155
+ endDate,
1156
+ options = {},
1157
+ ) {
1158
+ try {
1159
+ const buffer = await this._inner.recipeCurrencyConversion(
1160
+ String(ticker),
1161
+ String(targetCcy),
1162
+ String(startDate),
1163
+ String(endDate),
1164
+ );
1165
+ return this._ipcToBackend(buffer, options.backend || Backend.ARROW);
1166
+ } catch (err) {
1167
+ throw wrapError(err);
1168
+ }
1169
+ }
1170
+ }
1171
+
1172
+ async function connect(config = undefined) {
1173
+ if (!config) {
1174
+ return new Engine();
1175
+ }
1176
+ return Engine.withConfig(config);
1177
+ }
1178
+
1179
+ function configure(configOrHost = undefined, port = undefined) {
1180
+ configuredEngineConfig = normalizeConfigureArgs(configOrHost, port);
1181
+ clearConfiguredEngine();
1182
+ return configuredEngineConfig;
1183
+ }
1184
+
1185
+ async function abdp(tickers, fields, options = {}) {
1186
+ const engine = await getConfiguredEngine();
1187
+ return engine.bdp(toStringArray(tickers), toStringArray(fields), options);
1188
+ }
1189
+
1190
+ async function bdp(tickers, fields, options = {}) {
1191
+ return abdp(tickers, fields, options);
1192
+ }
1193
+
1194
+ async function abdh(
1195
+ tickers,
1196
+ fields,
1197
+ start = undefined,
1198
+ end = undefined,
1199
+ options = {},
1200
+ ) {
1201
+ const engine = await getConfiguredEngine();
1202
+ if (isPlainObject(start) && end === undefined) {
1203
+ return engine.bdh(toStringArray(tickers), toStringArray(fields), start);
1204
+ }
1205
+ return engine.bdh(toStringArray(tickers), toStringArray(fields), {
1206
+ ...options,
1207
+ start,
1208
+ end,
1209
+ });
1210
+ }
1211
+
1212
+ async function bdh(tickers, fields, options = {}) {
1213
+ return abdh(tickers, fields, options);
1214
+ }
1215
+
1216
+ async function abds(tickers, fields, overrides = undefined, options = {}) {
1217
+ const engine = await getConfiguredEngine();
1218
+ const normalizedOptions = isPlainObject(overrides)
1219
+ ? { ...options, overrides: { ...(options.overrides || {}), ...overrides } }
1220
+ : options;
1221
+ return engine.bds(
1222
+ toStringArray(tickers),
1223
+ toStringArray(fields),
1224
+ normalizedOptions,
1225
+ );
1226
+ }
1227
+
1228
+ async function bds(tickers, fields, options = {}) {
1229
+ return abds(tickers, fields, undefined, options);
1230
+ }
1231
+
1232
+ async function abdib(ticker, dt = undefined, interval = 1, options = {}) {
1233
+ const engine = await getConfiguredEngine();
1234
+ if (
1235
+ isPlainObject(dt) &&
1236
+ interval === 1 &&
1237
+ Object.keys(options).length === 0
1238
+ ) {
1239
+ return engine.bdib(String(ticker), dt);
1240
+ }
1241
+ const normalizedOptions = isPlainObject(interval)
1242
+ ? { ...interval }
1243
+ : { ...options, interval };
1244
+ if (normalizedOptions.start == null && normalizedOptions.end == null) {
1245
+ if (dt == null) {
1246
+ throw new TypeError('abdib requires dt or explicit start/end options');
1247
+ }
1248
+ Object.assign(normalizedOptions, fullDayRange(dt));
1249
+ }
1250
+ return engine.bdib(String(ticker), normalizedOptions);
1251
+ }
1252
+
1253
+ async function bdib(ticker, options = {}) {
1254
+ return abdib(ticker, options);
1255
+ }
1256
+
1257
+ async function abdtick(ticker, start, end, options = {}) {
1258
+ if (start == null || end == null) {
1259
+ throw new TypeError('abdtick requires both start and end datetimes');
1260
+ }
1261
+ const engine = await getConfiguredEngine();
1262
+ return engine.bdtick(String(ticker), { ...options, start, end });
1263
+ }
1264
+
1265
+ async function bdtick(ticker, options = {}) {
1266
+ const engine = await getConfiguredEngine();
1267
+ return engine.bdtick(String(ticker), options);
1268
+ }
1269
+
1270
+ async function asubscribe(tickers, fields) {
1271
+ const engine = await getConfiguredEngine();
1272
+ return engine.subscribe(toStringArray(tickers), toStringArray(fields));
1273
+ }
1274
+
1275
+ async function subscribe(tickers, fields) {
1276
+ return asubscribe(tickers, fields);
1277
+ }
1278
+
1279
+ async function acdx_info(ticker, options = {}) {
1280
+ const engine = await getConfiguredEngine();
1281
+ return engine.bdp([String(ticker)], [...CDX_INFO_FIELDS], options);
1282
+ }
1283
+
1284
+ async function acdx_pricing(ticker, options = {}) {
1285
+ const engine = await getConfiguredEngine();
1286
+ return engine.bdp(
1287
+ [String(ticker)],
1288
+ [...CDX_PRICING_FIELDS],
1289
+ normalizeRecoveryOptions(options),
1290
+ );
1291
+ }
1292
+
1293
+ async function acdx_risk(ticker, options = {}) {
1294
+ const engine = await getConfiguredEngine();
1295
+ return engine.bdp(
1296
+ [String(ticker)],
1297
+ [...CDX_RISK_FIELDS],
1298
+ normalizeRecoveryOptions(options),
1299
+ );
1300
+ }
1301
+
1302
+ const blp = Object.freeze({
1303
+ bdp,
1304
+ bdh,
1305
+ bds,
1306
+ bdib,
1307
+ bdtick,
1308
+ subscribe,
1309
+ abdp,
1310
+ abdh,
1311
+ abds,
1312
+ abdib,
1313
+ abdtick,
1314
+ asubscribe,
1315
+ });
1316
+
1317
+ const ext = Object.freeze({
1318
+ cdx: Object.freeze({
1319
+ acdx_info,
1320
+ acdx_pricing,
1321
+ acdx_risk,
1322
+ }),
1323
+
1324
+ // Date utilities
1325
+ parseDate: native.extParseDate,
1326
+ fmtDate: native.extFmtDate,
1327
+
1328
+ // Pivot utilities
1329
+ pivotToWide: native.extPivotToWide,
1330
+ isLongFormat: native.extIsLongFormat,
1331
+
1332
+ // Ticker utilities
1333
+ parseTicker: native.extParseTicker,
1334
+ isSpecificContract: native.extIsSpecificContract,
1335
+ buildFuturesTicker: native.extBuildFuturesTicker,
1336
+ normalizeTickers: native.extNormalizeTickers,
1337
+ filterEquityTickers: native.extFilterEquityTickers,
1338
+
1339
+ // Futures resolution
1340
+ generateFuturesCandidates: native.extGenerateFuturesCandidates,
1341
+ validateGenericTicker: native.extValidateGenericTicker,
1342
+ contractIndex: native.extContractIndex,
1343
+ filterCandidatesByCycle: native.extFilterCandidatesByCycle,
1344
+ filterValidContracts: native.extFilterValidContracts,
1345
+
1346
+ // CDX resolution
1347
+ parseCdxTicker: native.extParseCdxTicker,
1348
+ previousCdxSeries: native.extPreviousCdxSeries,
1349
+ cdxGenToSpecific: native.extCdxGenToSpecific,
1350
+
1351
+ // Currency utilities
1352
+ buildFxPair: native.extBuildFxPair,
1353
+ sameCurrency: native.extSameCurrency,
1354
+ currenciesNeedingConversion: native.extCurrenciesNeedingConversion,
1355
+
1356
+ // Column renaming
1357
+ renameDividendColumns: native.extRenameDividendColumns,
1358
+ renameEtfColumns: native.extRenameEtfColumns,
1359
+
1360
+ // Constants
1361
+ getMonthCode: native.extGetMonthCode,
1362
+ getMonthName: native.extGetMonthName,
1363
+ getFuturesMonths: native.extGetFuturesMonths,
1364
+ getDvdType: native.extGetDvdType,
1365
+ getDvdTypes: native.extGetDvdTypes,
1366
+ getDvdCols: native.extGetDvdCols,
1367
+ getEtfCols: native.extGetEtfCols,
1368
+
1369
+ // Fixed income / YAS
1370
+ buildYasOverrides: native.extBuildYasOverrides,
1371
+
1372
+ // Earnings utilities
1373
+ buildEarningHeaderRename: native.extBuildEarningHeaderRename,
1374
+ calculateLevelPercentages: native.extCalculateLevelPercentages,
1375
+
1376
+ // BQL query builders
1377
+ buildPreferredsQuery: native.extBuildPreferredsQuery,
1378
+ buildCorporateBondsQuery: native.extBuildCorporateBondsQuery,
1379
+ buildEtfHoldingsQuery: native.extBuildEtfHoldingsQuery,
1380
+
1381
+ // DateTime defaults
1382
+ defaultTurnoverDates: native.extDefaultTurnoverDates,
1383
+ defaultBqrDatetimes: native.extDefaultBqrDatetimes,
1384
+
1385
+ // Markets — sessions & timezone
1386
+ deriveSessions: native.extDeriveSessions,
1387
+ getMarketRule: native.extGetMarketRule,
1388
+ inferTimezone: native.extInferTimezone,
1389
+ setExchangeOverride: native.extSetExchangeOverride,
1390
+ getExchangeOverride: native.extGetExchangeOverride,
1391
+ clearExchangeOverride: native.extClearExchangeOverride,
1392
+ listExchangeOverrides: native.extListExchangeOverrides,
1393
+ sessionTimesToUtc: native.extSessionTimesToUtc,
1394
+ });
1395
+
1396
+ module.exports = {
1397
+ Engine,
1398
+ Subscription,
1399
+ connect,
1400
+ configure,
1401
+ bdp,
1402
+ bdh,
1403
+ bds,
1404
+ bdib,
1405
+ bdtick,
1406
+ subscribe,
1407
+ abdp,
1408
+ abdh,
1409
+ abds,
1410
+ abdib,
1411
+ abdtick,
1412
+ asubscribe,
1413
+ blp,
1414
+ ext,
1415
+ Backend,
1416
+ Format,
1417
+ BlpError,
1418
+ BlpSessionError,
1419
+ BlpRequestError,
1420
+ BlpValidationError,
1421
+ BlpTimeoutError,
1422
+ BlpInternalError,
1423
+ wrapError,
1424
+ version: () => packageJson.version,
1425
+ setLogLevel: native.setLogLevel,
1426
+ getLogLevel: native.getLogLevel,
1427
+ };