Skip to content

xbbg 1.5.0

Latest

Choose a tag to compare

@github-actions github-actions released this 02 Oct 01:59
· 7 commits to main since this release

Added

  • Python LangChain/LangGraph adapter. The separate xbbg-langgraph package in py-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 returned EXCH_CODE/PRICING_SOURCE on every call, so an ignored routing suffix is reported as mismatch instead 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. AUCTION field groups use streaming names (THEO_PRICE, not PX_THEO), and imbalance_side() maps venue codes such as MBUY/RBUY to 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/mktdata subscriptions 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 one SUMMARY/INITPAINT row 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=True keeps 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 plus last_update, live, and delayed, typed from Bloomberg's field metadata at subscribe time, and raises once the subscription has ended. rows=False (Node rows: false) keeps only current values for polling: nothing is queued, so it cannot overflow, and after a Bloomberg DATALOSS xbbg re-subscribes the feed for a fresh image (DataLoss and FeedRecovered events) instead of ending the subscription. zero_as_null shows 0 as missing in latest() for chosen fields; auction subscriptions apply it to the price fields in AUCTION.ZERO_PRICE_FIELDS by default. sub.add_fields() extends a running subscription, and aliases label rows, status, and remove() with your own identifiers.
  • Delayed-data and rejected-field warnings. Subscriptions read Bloomberg's IS_DELAYED_STREAM flag and warn once per security when data is delayed (on_delayed="warn" | "raise" | "ignore"; Python BlpDelayedDataWarning, Node process.emitWarning). Fields Bloomberg rejects at subscribe time, such as static-only PX_BID, are reported in field_errors with a BlpFieldWarning instead of silently staying empty; on_field_error="raise" fails the affected securities instead, and "ignore" records the error without warning. Node subscriptions also gain status, events, failures, failedTickers, topicStates, and fieldErrors.

Changed

  • GitHub repository links and generated MCP metadata now use the underloam organization. The MCP Registry identity is io.github.underloam/xbbg-mcp; package names and xbbg.org are 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_SUBTYPE are no longer emitted, so a subscription's output does not depend on other subscriptions sharing its feed. all_fields=True subscriptions still see every scalar field the feed receives, including fields other subscriptions requested.
  • BREAKING (Rust): Engine::subscribe(SubscribeRequest) replaces subscribe(...) and subscribe_with_options(...) in xbbg-async. Streams split into a receiver and a cloneable SubscriptionHandle that owns consumer memberships rather than a session claim. xbbg_core sessions add resubscribe(). 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_sessions still caps concurrent sessions, and a session returns to the pool once it hosts no feeds. Python sync stream() 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 same RuntimeError("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_TYPED adds a value_time column (Time64, µs) after value_ts for time-only values, and value_ts holds full datetimes only; SEMI_LONG date/time columns become Date32, Time64, or UTC timestamps; LONG_WITH_METADATA reports the matching dtype. Default LONG output 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.ext recipes (for example resolve_isins(), cdx_ticker(), etf_nav_snapshot(), and the new auction helpers) now raise the same BlpTimeoutError, BlpRequestError, BlpValidationError, and other BlpError subclasses as the request APIs instead of RuntimeError; except RuntimeError no longer catches them. Invalid arguments still raise ValueError.
  • BREAKING (Rust): xbbg_core::MessageIterator is a cursor, not an Iterator. Loop with let mut messages = event.messages(); while let Some(msg) = messages.next() { ... }. Each message borrows the cursor, so iterator adapters such as count() and collect() no longer apply to messages. Event::iter() is removed; use Event::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 former bdp/bdh/bds/bdib/bdtick/request allowlist (for example bsrch(), beqs(), bflds(), bta(), bschema(), and the subscribe()/vwap()/mktbar()/depth()/chains() subscription handles) now use the notebook bridge instead of raising cannot be used inside an async context. The xbbg.schema sync helpers, resolve_field_types(), xbbg.markets fetch_exchange_info(), and generate_ta_stubs() use the same boundary instead of calling asyncio.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.11 and lock its coordinated @vitest/* dependencies, including @vitest/mocker, to 4.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 fflate to 0.8.3, fixing the malformed ZIP64 infinite loop in GHSA-px8p-9vwx-vf98.
  • Patched JavaScript dev tooling. Both JavaScript packages now lock brace-expansion 5.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_ms docstring and type stub still said Default: 60_000, but the default has been 0 (no timeout) since 1.1.1. Requests wait for Bloomberg until they finish unless you opt in with configure(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) returned status="resolved" with an invalid ticker such as "<id> Pfd Equity". They are now unresolved, with the market sector named in error.
  • xbbg_core messages 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 as let msg = event.messages().next().unwrap(); or messages().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