Streaming
Subscription options, shared feeds, deltas, data loss, and cleanup.
Exchange auctions
Bloomberg publishes auction imbalance, indicative prices, auction state, and auction results only on the listing where the auction runs. xbbg.ext routes each input to that listing and checks Bloomberg's answer before it returns or streams any data.
WARNING
Auction fields need the matching exchange entitlements. Values are raw and venue-specific: read Reading the data before you build on them.
A composite ticker such as SPY US Equity returns no auction fields from reference data and only some of them in streams. A pricing-source suffix on an equity ISIN (/isin/<ISIN>@UP) is silently ignored, so Bloomberg answers with the composite. Every auction helper therefore works in three steps:
Look up the input's market sector, exchange codes, and pricing source, and build the venue topic.
Ask the venue topic for its EXCH_CODE or PRICING_SOURCE and compare it with the expected value.
Only validated venues carry data. Inputs that fail stay in the result with a status and an error message.
| Helper | Async | Purpose |
|---|---|---|
resolve_venues | aresolve_venues | Route and validate inputs; no auction data |
auction_snapshot | aauction_snapshot | Current auction fields from validated venues |
subscribe_auction | asubscribe_auction | Live Subscription on the validated venues |
stream_auction | astream_auction | Simple iteration over live auction rows |
AUCTION | Field groups | |
imbalance_side | Map imbalance codes to "buy", "sell", or "none" |
from xbbg import ext
# SPY US Equity -> SPY UP Equity, IBM US Equity -> IBM UN Equity,
# US0378331005 (Apple's ISIN) -> AAPL UW Equity
venues = ext.resolve_venues(["SPY US Equity", "IBM US Equity", "US0378331005"])resolve_venues(securities, *, pcs_overrides=None, backend=None) takes one identifier or a list of them. A bare ISIN with a valid ISO 6166 check digit is looked up as /isin/<ISIN>. The result has one row per input, in input order, duplicates included.
| Input | Venue topic | method | Checked against |
|---|---|---|---|
| Equity or ETF composite ticker, or its ISIN | {TICKER} {EQY_PRIM_EXCH_SHRT} Equity | exchange_ticker | venue EXCH_CODE |
Exchange ticker such as SPY UP Equity | unchanged | as_is | venue EXCH_CODE |
Preferred (Pfd) priced on its exchange (PRICING_SOURCE is EXCH) | /isin/<ISIN>@<PCS> | pcs_suffix | venue PRICING_SOURCE |
| Other preferred | unchanged | as_is | venue PRICING_SOURCE |
status | Meaning |
|---|---|
resolved | The venue returned the expected exchange code or pricing source. |
unresolved | A routing or validation field was missing, for example because Bloomberg rejected the input. |
unsupported | The market sector is not Equity or Pfd, or a preferred's exchange has no known pricing source. |
mismatch | The venue answered with a different exchange code or pricing source, for example after an ignored suffix. |
Only resolved rows are usable venues; the others never carry data, and error explains why. The columns are input_order, security (your input), lookup, kind (the lower-cased market sector, or unknown), composite, venue_topic, venue_figi, method, exch_code, mic, pricing_source, status, and error. venue_figi, exch_code, and pricing_source are filled only for resolved rows.
Preferreds route through a packaged exchange-to-PCS table: NEW YORK → SNY2; NASDAQ/NGS, NASDAQ/NGM, and NASDAQ/NCM → NASP; NYSE AMERICAN → AMEX. Every route is still validated against the returned PRICING_SOURCE. For other exchanges, or to replace a default, pass pcs_overrides, a mapping from the preferred's exchange name to a pricing source. Names match case- and whitespace-insensitively, values are upper-cased, and overrides win over the packaged table:
from xbbg import ext
def preferred_venues(isins: list[str]):
return ext.resolve_venues(isins, pcs_overrides={"NEW YORK": "SNY2"})Successful routing lookups are cached for the process for 12 hours, keyed by the normalized input and the effective pcs_overrides, with at most 4,096 routes (oldest first out). Cache hits do not extend the 12 hours, and a failed validation drops the cached route. Validation and data requests run on every call, so a route that has gone stale shows up as mismatch or unresolved rather than as wrong data.
from xbbg import ext
snap = ext.auction_snapshot(["SPY US Equity", "IBM US Equity"])
results = ext.auction_snapshot("IBM US Equity", ext.AUCTION.RESULTS, backend="pandas")auction_snapshot(securities, fields=AUCTION.DEFAULT, *, pcs_overrides=None, backend=None) routes every input, then fetches the fields and the validation codes from the venues in one reference-data request. The columns are input_order, security, venue_topic, status, and error, followed by one column per requested field. Rows that fail routing or validation keep null field values.
Field types follow Bloomberg's field metadata: time-of-day values become Time64 (microseconds) with no invented date, full datetimes become UTC timestamps, and dates become Date32. Integer fields are returned as Int64, and a temporal field whose values are mixed or unparseable stays text.
ext.AUCTION holds tuples of field names; concatenate them to combine groups, for example ext.AUCTION.IMBALANCE + ext.AUCTION.QUOTES.
| Group | Fields |
|---|---|
IMBALANCE | ORDER_IMB_BUY_VOLUME, ORDER_IMB_SELL_VOLUME, IMBALANCE_INDIC_RT, IMBALANCE_TIMESTAMP_RT, PAIRED_VOLUME_AT_REFERENCE_PX_RT, REFERENCE_PRICE_RT, MARKET_ORDER_IMBALANCE_VOLUME_RT, MARKET_ORDER_IMBALANCE_SIDE_RT, NEAR_REFERENCE_PX_VARIATION_RT, IMBALANCE_CROSS_TYPE_RT |
INDICATIVE | INDICATIVE_NEAR, INDICATIVE_FAR, THEO_PRICE, VOLUME_THEO, THEORETICAL_TIME_TODAY_RT, IMBALANCE_BUY, IMBALANCE_SELL |
STATE | AUCTION_TYPE_REALTIME, IN_AUCTION_RT, TIME_AUCTION_CALL_CONCLUSION_RT, SUB_SEC_TM_AUCT_CALL_CNCLSN_RT, AUCTION_EXTENSION_RT, MARKET_OR_LIMIT_CLOSE_ENTRY_RT, MOC_ELIGIBLE_RT, RT_TRADING_PERIOD, RT_EXCH_MARKET_STATUS, RT_SIMP_SEC_STATUS |
HALTS | TRADING_HALT_REASON_TYPE_RT, LULD_EVENT_CODE_RT, INTRADAY_AUCTION_VOLUME_RT |
RESULTS | OFFICIAL_CLOSE_AUCTION_PRICE_RT, OFFICIAL_CLOSE_AUCTION_VOLUME_RT, CLOSING_AUCTION_VOLUME_RT, CLOSING_AUCTION_VOLUME_DATE_RT, NUM_TRADES_CLOSING_AUCTION_RT, OFFICIAL_OPEN_AUCTION_PRICE_RT, OFFICIAL_OPEN_AUCTION_VOLUME_RT, OPENING_AUCTION_VOLUME_RT, PX_OFFICIAL_CLOSE_RT |
COMPOSITE | PRIMARY_MARKET_CLOSING_PRICE_RT, TIME_OF_CLOS_PX_ON_PRIM_MKT_RT, PRIMARY_MARKET_OPENING_PRICE_RT (opt-in) |
QUOTES | BID, ASK, BID_SIZE, ASK_SIZE (opt-in) |
DEFAULT | IMBALANCE + INDICATIVE + STATE + HALTS + RESULTS (39 fields) |
ext.AUCTION.ZERO_PRICE_FIELDS is a separate list, not a group: THEO_PRICE, INDICATIVE_NEAR, INDICATIVE_FAR, IMBALANCE_BUY, IMBALANCE_SELL, and REFERENCE_PRICE_RT.
The groups use streaming names such as THEO_PRICE and BID, which reference data also accepts. Live subscriptions reject static names such as PX_THEO and PX_BID. Snapshots and streams can deliver different scalar types for the same field: IN_AUCTION_RT, for example, can arrive as Y/N text on one path and as a boolean on the other.
import asyncio
from xbbg import ext
async def watch_auctions() -> None:
sub = await ext.asubscribe_auction(["SPY US Equity", "IBM US Equity"])
try:
async for table in sub:
print(table.to_pylist())
break
finally:
await sub.unsubscribe()
asyncio.run(watch_auctions())asubscribe_auction(securities, fields=AUCTION.DEFAULT, *, pcs_overrides=None, rows=True, on_field_error="warn", zero_as_null=None, **subscribe_kwargs) returns a Subscription; subscribe_auction is its synchronous wrapper.
BlpValidationError names the inputs and nothing is subscribed.latest() use the identifiers you passed, not the venue topics. xbbg sets aliases itself, so passing aliases raises BlpValidationError. remove() takes your labels; add() expects already resolved venue topics (optionally with aliases), so run resolve_venues first.on_field_error is "warn" (BlpFieldWarning), "raise" (fail the affected securities), or "ignore" (record in sub.field_errors only).zero_as_null is AUCTION.ZERO_PRICE_FIELDS intersected with the requested fields; it affects latest() and, since 1.8.0, delivery="state" images, never delta rows. Pass zero_as_null=() to keep the zeros.asubscribe, for example on_delayed, isolated, raw, tick_mode, output, or conflate. See Streaming for these options and for subscription lifecycle and diagnostics.astream_auction(...) and stream_auction(...) run the same preflight with the same pcs_overrides, on_field_error, and zero_as_null handling, always deliver rows, and pass other keywords to astream and stream. stream_auction iterates synchronously through xbbg's managed background loop; close it when you stop early:
from xbbg import ext
auction_rows = ext.stream_auction(["IBM US Equity"], ext.AUCTION.IMBALANCE)
try:
for batch in auction_rows:
print(batch)
break
finally:
auction_rows.close()A board you poll, rather than iterate, keeps only current values:
import asyncio
from xbbg import ext
async def auction_board() -> None:
board = await ext.asubscribe_auction(["SPY US Equity", "IBM US Equity"], rows=False)
try:
await asyncio.sleep(5)
print(board.latest()) # one row per security
finally:
await board.unsubscribe()
asyncio.run(auction_board())With rows=False nothing is queued, so a polled subscription cannot overflow, and iterating it raises RuntimeError. latest() returns one row per security: topic (your label), last_update (UTC), live (a non-initial update has arrived), delayed, and the current value of each field. latest(backend=...) converts like any request result. If Bloomberg reports DATALOSS, a board re-subscribes for a fresh image instead of ending: live turns false and DataLoss and then FeedRecovered appear in board.events. Once the subscription has ended, latest() raises.
INDICATIVE_NEAR and INDICATIVE_FAR are NYSE's continuous-book and closing-only clearing prices but Nasdaq's near and far indicative prices, and IMBALANCE_CROSS_TYPE_RT codes differ by venue.IMBALANCE_BUY and IMBALANCE_SELL are prices, not quantities. For imbalance-side codes use ext.imbalance_side(code).THEO_PRICE and VOLUME_THEO reset to 0 at the start of each auction call, and Bloomberg sends 0 for a price it does not have. Auction subscriptions therefore show the ZERO_PRICE_FIELDS as missing in latest() (and in state deliveries); delta rows always carry the raw values.AUCTION_TYPE_REALTIME, IN_AUCTION_RT, and the live column of latest() to tell current values from leftovers.IMBALANCE_TIMESTAMP_RT are times in the Terminal's local time zone, in snapshots and streams alike. Date fields such as CLOSING_AUCTION_VOLUME_DATE_RT are dates.from xbbg import ext
ext.imbalance_side("MBUY") # "buy" (BUY, MBUY, RBUY)
ext.imbalance_side("RSEL") # "sell" (SELL, MSEL, RSEL)
ext.imbalance_side("NIMB") # "none" (NOIM, NIMB)
ext.imbalance_side("XXXX") # None for unknown codesCodes are matched case-insensitively after trimming whitespace.
Raw batches convert to PyArrow record batches that can be appended to Parquet (install xbbg[pyarrow]). Keep __xbbg_present so a reader can tell unchanged fields from explicit clears, and start a new file when the schema changes:
import asyncio
import pyarrow.parquet as pq
from xbbg import ext
async def record_auction() -> None:
sub = await ext.asubscribe_auction(["IBM US Equity"], raw=True)
writer, part = None, 0
try:
async for batch in sub:
batch = batch.to_pyarrow()
if writer is None or batch.schema != writer.schema:
if writer is not None:
writer.close()
part += 1
writer = pq.ParquetWriter(f"ibm-auction-{part}.parquet", batch.schema)
writer.write_batch(batch)
finally:
await sub.unsubscribe()
if writer is not None:
writer.close()
asyncio.run(record_auction())Subscription rows are deltas, not complete images; see Streaming for the presence bitmap and data-loss semantics.
Auction results, unlike imbalance data, have history on the venue listing. Request it from the listing that resolve_venues returns; the composite returns none:
import xbbg
closing_volume = xbbg.bdh("IBM UN Equity", "OFFICIAL_CLOSE_AUCTION_VOLUME", "2024-01-02", "2024-03-28")Delayed data does not need a subscription to detect: xbbg.delay_status(...) reports per security whether this session's data is delayed, and bdp, bdh, bdib, and bdtick accept on_delayed=. Auction subscriptions warn when a stream is delayed, like every subscription; pass on_delayed= to asubscribe_auction to change that. See Entitlements and delayed data and Streaming.
The LangGraph adapters expose xbbg_resolve_venues and xbbg_auction_snapshot (LangGraph tools), and the MCP server exposes resolve_venues and auction_snapshot (MCP server).
Subscription options, shared feeds, deltas, data loss, and cleanup.
Delayed-data checks, entitlement IDs, and support RequestIds.
The other xbbg.ext helpers.
BlpValidationError, BlpFieldWarning, and the rest of the hierarchy.