Added
- Python LangChain/LangGraph adapter. The separate
xbbg-langgraphpackage inpy-xbbg-langgraph/exposes 23 Bloomberg request/recipe/snapshot tools and 11 native helper/chart tools. It supports sync/async invocation, bounded content-and-artifact results, application-owned engines, and cancellation-safe subscription cleanup without adding LangChain dependencies to ordinary xbbg installs. Includes Python matrix and dependency-floor CI coverage; installation is from the checkout pending its first package publication. - Exchange auction and imbalance data. Bloomberg publishes imbalance, indicative-price, auction-state, and auction-result fields only on the listing where the auction runs.
resolve_venues()routes each ticker or ISIN there — equities and ETFs to their primary-exchange ticker (SPY US Equity→SPY UP Equity), preferreds to their venue pricing source (/isin/<ISIN>@SNY2) — and validates Bloomberg's returnedEXCH_CODE/PRICING_SOURCEon every call, so an ignored routing suffix is reported asmismatchinstead of returning composite data; routing lookups are cached for 12 hours.auction_snapshot()fetches the auction fields with typed columns (times and dates included) in one validated reference-data request.subscribe_auction()/stream_auction()resolve every input before subscribing and label rows with the identifiers you passed.AUCTIONfield groups use streaming names (THEO_PRICE, notPX_THEO), andimbalance_side()maps venue codes such asMBUY/RBUYto buy/sell. Available in Python (xbbg.ext), JavaScript (Engine.resolveVenues,auctionSnapshot,subscribeAuction,streamAuction,AuctionFields,imbalanceSide), LangGraph (xbbg_resolve_venues,xbbg_auction_snapshot), and MCP (resolve_venues,auction_snapshot). - Shared real-time subscriptions. Within one engine,
//blp/mktdatasubscriptions to the same security and options share one Bloomberg subscription that requests the union of their fields, instead of each opening its own. A subscription joining an existing feed immediately gets oneSUMMARY/INITPAINTrow from the feed's current values. Adding fields the feed lacks re-subscribes it once: the requesting subscription gets Bloomberg's full repaint, and subscriptions that already had the image get one row only for values the repaint changed.isolated=Truekeeps a subscription on its own feeds and session;subscription_feeds()lists feeds, field unions, and consumer counts. Other services are not shared. - Current values, field growth, and labels on live subscriptions.
sub.latest()returns one row per security with each field's current value pluslast_update,live, anddelayed, typed from Bloomberg's field metadata at subscribe time, and raises once the subscription has ended.rows=False(Noderows: false) keeps only current values for polling: nothing is queued, so it cannot overflow, and after a BloombergDATALOSSxbbg re-subscribes the feed for a fresh image (DataLossandFeedRecoveredevents) instead of ending the subscription.zero_as_nullshows 0 as missing inlatest()for chosen fields; auction subscriptions apply it to the price fields inAUCTION.ZERO_PRICE_FIELDSby default.sub.add_fields()extends a running subscription, andaliaseslabel rows, status, andremove()with your own identifiers. - Delayed-data and rejected-field warnings. Subscriptions read Bloomberg's
IS_DELAYED_STREAMflag and warn once per security when data is delayed (on_delayed="warn" | "raise" | "ignore"; PythonBlpDelayedDataWarning, Nodeprocess.emitWarning). Fields Bloomberg rejects at subscribe time, such as static-onlyPX_BID, are reported infield_errorswith aBlpFieldWarninginstead of silently staying empty;on_field_error="raise"fails the affected securities instead, and"ignore"records the error without warning. Node subscriptions also gainstatus,events,failures,failedTickers,topicStates, andfieldErrors.
Changed
- GitHub repository links and generated MCP metadata now use the
underloamorganization. The MCP Registry identity isio.github.underloam/xbbg-mcp; package names andxbbg.orgare unchanged. - Lower per-event subscription processing cost. Wide, sparse requested-field updates use a bounded present-field scan; narrow and dense updates retain name lookups. Schema discovery and type changes build the final immutable layout once per message without changing version increments. Requested-field order, null/absence semantics, terminal errors, and individual-event delivery are unchanged; no batching or API changes.
- BREAKING: filtered market-data subscriptions skip rows that contain none of their fields. Rows carrying only
MKTDATA_EVENT_TYPE/MKTDATA_EVENT_SUBTYPEare no longer emitted, so a subscription's output does not depend on other subscriptions sharing its feed.all_fields=Truesubscriptions still see every scalar field the feed receives, including fields other subscriptions requested. - BREAKING (Rust):
Engine::subscribe(SubscribeRequest)replacessubscribe(...)andsubscribe_with_options(...)inxbbg-async. Streams split into a receiver and a cloneableSubscriptionHandlethat owns consumer memberships rather than a session claim.xbbg_coresessions addresubscribe(). Python and JavaScript signatures only gain optional arguments. - Subscription sessions host shared feeds. A subscription that only joins existing feeds uses no session;
max_subscription_sessionsstill caps concurrent sessions, and a session returns to the pool once it hosts no feeds. Python syncstream()no longer keeps its own producer counter: a stream that only joins existing feeds never waits, and one that needs a new session waits up to 5 seconds for capacity, then raises the sameRuntimeError("sync stream producer limit reached (N)")as before instead of blocking. When a session terminates, only the securities on it fail; a stream ends with the session error once none of its securities remain. - BREAKING (typed outputs): date and time fields keep their types. Bloomberg's field metadata reports every date and time field as
Datetime, which xbbg resolved to text. Types now follow the field's kind:LONG_TYPEDadds avalue_timecolumn (Time64, µs) aftervalue_tsfor time-only values, andvalue_tsholds full datetimes only;SEMI_LONGdate/time columns become Date32, Time64, or UTC timestamps;LONG_WITH_METADATAreports the matchingdtype. DefaultLONGoutput still returns text. Field-type caches written by older versions are discarded and refreshed on first use. - BREAKING (Python): recipe failures raise typed xbbg exceptions. Engine errors from
xbbg.extrecipes (for exampleresolve_isins(),cdx_ticker(),etf_nav_snapshot(), and the new auction helpers) now raise the sameBlpTimeoutError,BlpRequestError,BlpValidationError, and otherBlpErrorsubclasses as the request APIs instead ofRuntimeError;except RuntimeErrorno longer catches them. Invalid arguments still raiseValueError. - BREAKING (Rust):
xbbg_core::MessageIteratoris a cursor, not anIterator. Loop withlet mut messages = event.messages(); while let Some(msg) = messages.next() { ... }. Each message borrows the cursor, so iterator adapters such ascount()andcollect()no longer apply to messages.Event::iter()is removed; useEvent::messages().
Fixed
- Every Python sync API works in notebooks (#353). In Jupyter, VS Code Interactive, and marimo,
blp.bql()and the other sync wrappers outside the formerbdp/bdh/bds/bdib/bdtick/requestallowlist (for examplebsrch(),beqs(),bflds(),bta(),bschema(), and thesubscribe()/vwap()/mktbar()/depth()/chains()subscription handles) now use the notebook bridge instead of raisingcannot be used inside an async context. Thexbbg.schemasync helpers,resolve_field_types(),xbbg.marketsfetch_exchange_info(), andgenerate_ta_stubs()use the same boundary instead of callingasyncio.run()directly. Other running event loops, such as FastAPI or ASGI apps, still raise and name the async API. - Synchronized native release versions. Cargo workspace and internal dependency versions now match 1.4.12, and future release workflows stamp and commit them before tagging. The binding version uses the stamped crate identity even without Git metadata; Git descriptions remain in build provenance. Release builds reject unstamped source trees and wheels whose Python, binding, or core versions disagree.
- Patched JavaScript test tooling. Both JavaScript packages now require Vitest
^4.1.11and lock its coordinated@vitest/*dependencies, including@vitest/mocker, to4.1.11, addressing the redirect-mock path traversal and arbitrary file read in GHSA-82fw-gwwq-j7x9. - Patched MCPB archive tooling. The private build tools now pin
fflateto0.8.3, fixing the malformed ZIP64 infinite loop in GHSA-px8p-9vwx-vf98. - Patched JavaScript dev tooling. Both JavaScript packages now lock
brace-expansion5.0.12 (#355), fixing the denial-of-service advisories GHSA-6j4f-fj2g-mc7p, GHSA-qhr7-859c-m2p7, and GHSA-q2hr-2g5m-vwhr. It is a development dependency and is not part of the published packages. - Python docs no longer claim a 60-second request timeout. The
PyEngineConfig.request_timeout_msdocstring and type stub still saidDefault: 60_000, but the default has been0(no timeout) since 1.1.1. Requests wait for Bloomberg until they finish unless you opt in withconfigure(request_timeout_ms=...). resolve_isins()no longer reports preferreds as resolved equities. ISINs whose Bloomberg parsekey carries a non-Equity yellow key (Pfd, Corp, Govt, and so on) returnedstatus="resolved"with an invalid ticker such as"<id> Pfd Equity". They are nowunresolved, with the market sector named inerror.xbbg_coremessages can no longer be used after Bloomberg releases them. The SDK keeps an iterated message valid only until its iterator advances or is destroyed, but messages were tied to the event, so safe code such aslet msg = event.messages().next().unwrap();ormessages().collect()compiled and then used messages the SDK no longer kept valid, which could read freed memory. The compiler now rejects both. Python and JavaScript were not affected.
Full Changelog: v1.4.12...v1.5.0