Configuration
B-PIPE, ZFP, TLS, SOCKS5, auth, timeouts, pools, sharding, and logging.
Node.js quickstart
Connect, request reference, historical, bulk, intraday, and BQL data, choose an output backend, and handle errors with @xbbg/core.
WARNING
Every request needs a reachable Bloomberg endpoint and entitlements for the data requested. The examples use a Desktop API session on localhost:8194.
npm install @xbbg/core@xbbg/core needs Node.js 24+ or Bun 1.4+ and the Bloomberg SDK runtime library; see Installation. The samples use top-level await, so run them as ES modules (.mts files, or "type": "module" in package.json).
| Entry point | Returns | When the session starts |
|---|---|---|
configure(config) or configure(host, port) | The stored configuration | On the first top-level helper call (bdp, blp.abdh, subscribe, ...), off the event loop |
connect(config) or Engine.connect(config) | Promise<Engine> | Immediately, off the event loop |
new Engine(host, port) or Engine.withConfig(config) | Engine | Immediately, blocking the event loop until the session is up (up to the 30-second session timeout) |
configure() call. Without configure(), they connect to localhost:8194.configure() only stores settings. Invalid values reject the first helper call that builds the engine. Calling configure() again replaces the shared engine and signals the previous one to shut down.connect() in servers: the synchronous constructor and withConfig() block the event loop while Bloomberg connects.import { bdh, bdp, bds, configure } from '@xbbg/core';
configure({ host: 'localhost', port: 8194 });
// Reference data: one row per ticker and field in the default long format
const ref = await bdp(['AAPL US Equity', 'MSFT US Equity'], ['PX_LAST', 'SECURITY_NAME']);
// Historical data
const hist = await bdh('SPX Index', ['PX_LAST', 'PX_VOLUME'], {
start: '2024-01-01',
end: '2024-12-31',
});
// Bulk data with a Bloomberg override
const dividends = await bds('AAPL US Equity', 'DVD_Hist_All', {
overrides: { DVD_Start_Dt: '20240101' },
});
console.log(ref, hist, dividends);Top-level helpers accept a single string or an array for tickers and fields. Engine methods take arrays.
Results name the column that holds each row's security ticker. That default is deprecated because it collides with Bloomberg's TICKER field once names are case-folded: the first result that uses it emits one DeprecationWarning per process (code XBBG_TICKER_KEY_COLUMN), and the next major release makes security the default. Switch now with configure({ keyColumn: 'security' }) or connect({ keyColumn: 'security' }).
import { bdib, bdtick } from '@xbbg/core';
// 5-minute TRADE bars; naive datetimes are read in New York time
const bars = await bdib('AAPL US Equity', {
start: '2024-12-02T09:30:00',
end: '2024-12-02T16:00:00',
interval: 5,
requestTz: 'America/New_York',
});
// Trades and quotes for five minutes
const ticks = await bdtick('AAPL US Equity', {
start: '2024-12-02T09:30:00',
end: '2024-12-02T09:35:00',
eventTypes: ['TRADE', 'BID', 'ASK'],
requestTz: 'America/New_York',
});
console.log(bars, ticks);bdib defaults to 1-minute TRADE bars and bdtick to TRADE events. Naive datetimes are read as UTC unless requestTz is set, and the returned time column is UTC unless outputTz is set. Output Formats lists the accepted date inputs and time zone labels.
blp namespace blp groups the top-level helpers and adds Python-style positional forms:
import { blp } from '@xbbg/core';
const hist = await blp.abdh(['SPX Index'], ['PX_LAST'], '2024-01-01', '2024-12-31');
const bars = await blp.abdib('AAPL US Equity', '2024-12-02', 5); // whole day of 5-minute bars
const ticks = await blp.abdtick('AAPL US Equity', '2024-12-02T14:30:00', '2024-12-02T14:31:00');
const bulk = await blp.abds('AAPL US Equity', 'DVD_Hist_All', { DVD_Start_Dt: '20240101' });
console.log(hist, bars, ticks, bulk);| Positional form | Equivalent |
|---|---|
abdh(tickers, fields, start, end, options) | bdh(tickers, fields, { ...options, start, end }) |
abds(tickers, fields, overrides, options) | bds(tickers, fields, { ...options, overrides }) |
abdib(ticker, dt, interval, options) | bdib(ticker, { ...options, interval }) over the calendar day dt, 00:00:00 to 23:59:59 in the request time zone |
abdtick(ticker, start, end, options) | bdtick(ticker, { ...options, start, end }) |
abdp, asubscribe, and adelayStatus take the same arguments as bdp, subscribe, and delayStatus. BQL has no top-level helper; call it on an Engine.
import { bdh, bdp, ovr } from '@xbbg/core';
// The same override for every security
const eur = await bdp('AAPL US Equity', 'CRNCY_ADJ_PX_LAST', {
overrides: ovr({ EQY_FUND_CRNCY: 'EUR' }),
});
// A default plus per-security overrides
const mixed = await bdp(['AAPL US Equity', 'MSFT US Equity'], 'CRNCY_ADJ_PX_LAST', {
overrides: ovr({
EQY_FUND_CRNCY: 'USD',
'AAPL US Equity': ovr({ EQY_FUND_CRNCY: 'EUR' }),
'MSFT US Equity': ovr({ EQY_FUND_CRNCY: 'JPY' }),
}),
});
// Raw Bloomberg request elements go in kwargs
const weekly = await bdh('SPX Index', 'PX_LAST', {
start: '2024-01-01',
end: '2024-06-30',
kwargs: { periodicitySelection: 'WEEKLY' },
});
console.log(eur, mixed, weekly);overrides accepts a plain object, an array of [key, value] entries, or an OverrideSpec built with ovr(). ovr() merges its arguments left to right, later keys win, and Date values become YYYYMMDD.ovr() spec names a security and scopes those overrides to it. Per-security overrides work with bdp, bdh, and bds; beqs, bsrch, and bport reject them with a TypeError.kwargs sets request elements that have no typed option, such as periodicitySelection or maxDataPoints.import { connect } from '@xbbg/core';
const engine = await connect({ host: 'localhost', port: 8194 });
const ref = await engine.bdp(['AAPL US Equity'], ['PX_LAST']);
const bql = await engine.bql("get(px_last) for('AAPL US Equity')");
const fields = await engine.fieldSearch('vwap');
console.log(ref, bql, fields);Each Engine has its own request workers, subscription sessions, and shared subscription feeds. Engine also carries the BQL, BEQS, BSRCH, BTA, schema, streaming-service, and recipe methods; see the API Surface.
import type { Table } from 'apache-arrow';
import { Backend, connect } from '@xbbg/core';
const engine = await connect();
// Default: an Apache Arrow table
const table = (await engine.bdp(['AAPL US Equity'], ['PX_LAST'])) as Table;
console.log(table.numRows, table.schema.fields.map((field) => field.name));
// JSON rows
const rows = (await engine.bdp(['AAPL US Equity'], ['PX_LAST'], {
backend: Backend.JSON,
})) as Array<Record<string, unknown>>;
console.log(rows[0]?.value);Request methods return Promise<unknown>; cast the result to the shape of the backend you chose. backend: 'polars' returns a nodejs-polars DataFrame and needs the optional nodejs-polars package. Output Formats covers formats and result metadata.
import { asubscribe } from '@xbbg/core';
const sub = await asubscribe(['AAPL US Equity'], ['LAST_PRICE', 'BID', 'ASK']);
try {
for await (const tick of sub) {
console.log(tick.topic, tick.get('LAST_PRICE'));
break; // leaving the loop unsubscribes
}
} finally {
await sub.unsubscribe();
}See Streaming for Arrow reads, shared feeds, boards, and data-loss handling.
for await loop early also unsubscribes.engine.signalShutdown() stops an engine you created: it closes admission, ends its subscriptions, and signals its sessions to stop. Await subscription cleanup first, and do not use the engine afterwards.engine.isAvailable() reports whether at least one request session is healthy.import { connect } from '@xbbg/core';
const engine = await connect();
try {
console.log(await engine.bdp(['AAPL US Equity'], ['PX_LAST']));
} finally {
engine.signalShutdown();
}import {
BlpError,
BlpLimitError,
BlpRequestError,
BlpTimeoutError,
BlpValidationError,
connect,
} from '@xbbg/core';
const engine = await connect({ requestTimeoutMs: 60_000 });
try {
await engine.bdp(['AAPL US Equity'], ['PX_LAST']);
} catch (error) {
if (error instanceof BlpLimitError) {
console.error('Bloomberg capacity limit reached:', error.message);
} else if (error instanceof BlpRequestError) {
console.error(error.service, error.operation, error.code, error.bloomberg_request_ids);
} else if (error instanceof BlpTimeoutError) {
console.error('Timed out:', error.bloomberg_request_id);
} else if (error instanceof BlpValidationError) {
console.error('Invalid input:', error.element, error.suggestion);
} else if (error instanceof BlpError) {
console.error(error.name, error.message);
} else {
throw error;
}
}| Class | Raised for |
|---|---|
BlpError | Base class of every engine and Bloomberg error, including invalid engine configuration |
BlpSessionError | Session start, connection, and service-open failures |
BlpRequestError | Bloomberg request failures; carries service, operation, request_id, and code |
BlpLimitError | Bloomberg LIMIT and DAILY_CAPACITY_REACHED responses; a subclass of BlpRequestError, so test for it first |
BlpValidationError | Invalid request input; carries element and suggestion |
BlpTimeoutError | Timeouts, including requestTimeoutMs |
BlpSubscriptionDataLossError | A row subscription lost data (code: 'DATALOSS') |
BlpInternalError | Engine-internal failures |
Every BlpError carries Bloomberg's support identifiers in bloomberg_request_id and bloomberg_request_ids when the SDK assigned them; request_id is xbbg's own request label. In request methods, argument mistakes caught in JavaScript, such as an ambiguous date string or an unknown backend, reject with a TypeError before any request is sent.
B-PIPE, ZFP, TLS, SOCKS5, auth, timeouts, pools, sharding, and logging.
Backends, formats, metadata, and date inputs.
Real-time subscriptions in depth.
Higher-level workflows on the Engine.