Skip to content

xbbg 1.2.0

Choose a tag to compare

@github-actions github-actions released this 29 Apr 01:36
· 92 commits to main since this release

Removed

  • xbbg-browser, xbbg-bridge, and xbbg-server retired: The apps/xbbg-server Rust HTTP server, its @xbbg/bridge npm launcher and 5 platform-specific bridge binaries, and the @xbbg/browser HTTP client are removed. js-xbbg, napi-xbbg, and pyo3-xbbg remain the supported bindings.

Added

  • Native datetime/date acceptance across all surfaces (#317): bdh, bdib, bdtick, bqr, arequest, and the xbbg.ext.bonds / xbbg.ext.options / xbbg.ext.fixed_income / xbbg.ext.historical / xbbg.ext.futures helpers now accept datetime.date, datetime.datetime (naive or tz-aware), and duck-typed pd.Timestamp (no hard pandas dependency) anywhere they previously took only str. ISO 8601, Bloomberg-native (YYYYMMDD), and "today" strings continue to work; ambiguous MM/DD/YYYY-style inputs are now rejected with a clear ValueError. The two divergent _fmt_date helpers were consolidated into a single source of truth in xbbg.ext._utils (extended with native-type support and a new _fmt_datetime). Bloomberg field overrides passed as **kwargs (e.g. USER_LOCAL_TRADE_DATE=date(2023, 1, 17)) are normalized to YYYYMMDD via value-based duck typing. Mirrored on the JS side: @xbbg/core accepts Date, ISO/Bloomberg-native string, epoch-ms number, and duck-typed Luxon DateTime across bdh / bdib / bdtick / bqr / recipe surfaces, with new formatDate / formatDateTime helpers and DateLike / DateTimeLike exported types. New guide at docs/python/guides/dates.
  • @xbbg/core subscription replay benchmark: Added a JS-only npm run bench:subscription-replay harness for one-update-at-a-time synthetic replay, JSONL fixture replay, live XBTUSD Curncy capture, and path-specific timing (legacy, arrow-decode-only, subscription-wrapper). Replay now supports --consume rows|vector|schema|none and --warmup-iterations; row materialization remains the default. Live capture reports existing sub.stats slow-consumer telemetry without changing the production streaming API.
  • xbbg-bench offline Rust replay benchmarks: Added benchmark-controlled, non-Bloomberg, non-datamock harnesses for Arrow/TypedBuilder append/finalize paths and synthetic xbbg-async subscription-shaped replay. These live entirely under crates/xbbg-bench, emit JSON artifacts, and use env knobs for row counts, flush size, and iterations so production crates do not carry benchmark-only hot-path changes.
  • xbbg-bench cached subscription-to-Arrow bridge benchmark: Added a bounded live Bloomberg subscription capture that replays cached real SDK Event/Message objects through xbbg-async SubscriptionState into Arrow batches. This connects core SDK traversal with the subscription Arrow path while keeping Bloomberg usage to a small initial capture and avoiding datamock.
  • Low-data live regression coverage for recent Bloomberg issues: Added live integration coverage for recent BDTICK/ABDTICK, BDS bulk headers, numeric backend typing, optional conversion backend dispatch, BQL economic calendar, exchange-resolution, subscription timestamp, and options-extension regressions. The new fixtures favor bounded requests (maxDataPoints, narrow chains, and current low-volume windows) so the live suite keeps request volume limited while still exercising real service behavior. Users remain responsible for Bloomberg entitlements and usage terms.
  • Bloomberg Excel/0.x request aliases restored (#301): bdh / abdh, bdib / abdib, and bdtick / abdtick now accept the 0.x/Excel-style request aliases (Per, PerAdj, Curr/FX, Days, Fill, Points, Quote, QuoteType/QtTyp, CshAdj*, CapChg, UseDPDF, Calendar, BarSz/BarSize, BarTp/BarType, and IncludeExchangeCodes) and normalize enum shorthand values before requests reach Bloomberg. bdh() also consumes Excel-only presentation aliases (Dts/Dates, DtFmt/DateFormat, Sort, Orientation/Direction/Dir) locally for date/period display, row ordering, and default orientation. Coverage includes offline routing tests plus a capped live Bloomberg suite.

Changed

  • Python backend clean-cutover to native xbbg Arrow objects: The Rust layer now returns native xbbg._core.ArrowTable / ArrowRecordBatch carriers internally, with explicit backend="native" for callers that want those raw objects. The public default remains a Narwhals DataFrame and prefers a real PyArrow table when PyArrow is installed, then falls back through installed dataframe libraries before the minimal xbbg Narwhals plugin. backend="pyarrow" returns a real pyarrow.Table; the misleading Backend.ARROW / backend="arrow" alias was removed. Pandas, Polars, DuckDB, and Narwhals remain explicit optional conversion backends, and PyArrow is no longer a core dependency.
  • @xbbg/core subscriptions now require NAPI Arrow zero-copy transfer: Subscription.next() asks the native binding for Arrow buffer descriptors and builds Apache Arrow JS tables directly from native Arrow buffers for common Bloomberg subscription types (bool, date32, float64, int32, int64, time64[us], timestamp[us], utf8, null). The JS subscription path no longer falls back to standalone IPC; unsupported or sliced schemas fail fast with column-level diagnostics while the public Subscription.next(): Table API remains unchanged.
  • @xbbg/core exposes full Bloomberg subscription payloads: JS streaming APIs now accept allFields: true, forwarding the existing Rust engine all_fields mode so callers can receive every top-level scalar field Bloomberg sends instead of only requested fields plus MKTDATA_EVENT_TYPE / MKTDATA_EVENT_SUBTYPE. The NAPI zero-copy bridge also supports time64[us] columns for dynamic all-fields schemas.
  • Rust Bloomberg SDK handle ownership hardened: xbbg-core now models session-owned SDK views with Rust lifetimes instead of unsupported Send/Sync marker impls. Service, schema operations/definitions, and constants are tied to their owning session/service, pointer correlation IDs are explicit unsafe values, and async request workers reopen short-lived service handles rather than caching session-owned handles across worker state.
  • Reference data fieldExceptions logging aggregated: Per-security fieldExceptions diagnostics now stay at DEBUG with field-level detail, while bulk requests emit a single summary warning with total exception count and affected tickers.
  • @xbbg/core TypeScript request surface completed: JS wrappers now forward validateFields on bdp/bds/bdh, requestTz/outputTz on bdib/bdtick, and typed bdtick include-code options while rejecting unknown backend strings instead of silently returning Arrow.
  • Generic bds() / abds() bulk-header contract documented (#274): xbbg preserves Bloomberg bulk subfield labels exactly in the generic BDS path; only ticker and field are xbbg-added metadata columns. Higher-level helpers that need stable semantic names must rename their own outputs explicitly.
  • Generated sync wrappers now resolve in IDEs (#307): bdp, bdh, bds, bdib, bdtick, bql, bsrch, bqr, bflds, beqs, blkp, bport, bcurves, and bgovts now expose static signatures for parameter hints, hover docs, and go-to-definition. Top-level xbbg exports were also completed for abqr / bqr and the generated endpoint stubs.
  • Retired mock crates removed from the workspace: The old C++ mock stack and Cargo mock feature forwarding were removed so the Rust workspace has a single live Bloomberg SDK FFI path.

Fixed

  • BQR dealer attribution restored (#312): bqr() / abqr() and xbbg.ext.bqr() now default to BID/ASK quote events with includeBrokerCodes=true, normalize output to the 0.x-compatible event_type / price / broker_buy / broker_sell columns, warn when an attributed request is not shaped like a fixed-income ISIN with @MSG1 Corp, and raise when Bloomberg returns quote rows without broker attribution unless callers explicitly opt out with include_broker_codes=False. Low-data live coverage uses an @MSG1 Corp fixed-income ISIN fixture capped with maxDataPoints=5.

  • Subscription schemas preserve sparse numeric quote fields: Requested subscription fields now observe Bloomberg element datatypes even when a particular update carries a null value, so sparse streams such as XBTUSD Curncy quote updates keep BID / ASK as Float64 instead of degrading the Arrow schema to Utf8 before a non-null quote arrives. Live schema tests now print sample raw batches for easier diagnosis.

  • Exchange/session resolution handles Bloomberg time-valued metadata: Exchange metadata parsing now accepts Arrow time columns for TRADING_DAY_START_TIME_EOD / TRADING_DAY_END_TIME_EOD, avoids futures-only metadata field requests on ordinary equities, preserves futures fallback via FUT_TRADING_HRS, and applies the Japan equity 09:00-15:30 session rule so market_timing(..., "EOD", "UTC") resolves to the expected Tokyo close.

  • Options live tests derive valid contracts dynamically: The options extension live suite no longer relies on stale hardcoded SPY expiry/strike fixtures; it discovers a current low-data SPY call through a narrow option_chain() request and reuses that valid ticker/expiry/strike for info, greeks, pricing, screen, and BQL-chain checks.

  • bdtick include-code options now keep typed tick tables (#309): IntradayTickState dynamically discovers scalar fields inside Bloomberg's tickData.tickData[] rows, so options such as includeConditionCodes, includeExchangeCodes, and includeBloombergStandardConditionCodes add typed columns after the stable core [ticker, time, type, value, size] instead of forcing callers into generic [path, type, value_str, value_num] output. Dynamic columns are padded with nulls for ticks where Bloomberg omitted that field; response metadata such as tickData.eidData remains excluded from per-tick rows.

  • bds bulk rows discover subfields across the whole response: BulkDataState now scans every scalar child in each Bloomberg bulk row instead of freezing the output schema from the first row. Late-appearing subfields are appended in first-seen order and earlier rows are padded with nulls, preserving row alignment for dynamic bulk datasets.

  • bds manually selected bulk extraction could be overwritten by defaults: RequestParams::with_defaults() now preserves an explicit non-default extractor hint, preventing bulk requests from falling back to reference-data long extraction when callers build request params manually.

  • Pixi/libclang bindgen discovery on Windows: Shared build support now creates an OUT_DIR-local libclang.dll alias for pixi/conda's versioned libclang-*.dll, so all bindgen build scripts can run without manually installing LLVM or mutating the pixi environment.

  • Live reference-data tests and benchmarks used the wrong Bloomberg array accessor: securityData value arrays now use get_element(0) rather than child-element lookup, matching the SDK response shape.

  • @xbbg/core TypeScript package metadata repaired: Native optional dependencies now use package versions instead of local file: links, release scripts use a checked-in CJS platform map helper, packaged-install smoke checks the published dist entrypoint, and the npm package includes the Apache license.

  • @xbbg/core local Windows runtime loading fixed: The Node binding now adds the vendored Bloomberg SDK runtime DLL directory from vendor/blpapi-sdk/<version> (or XBBG_DEV_SDK_ROOT) to PATH before loading napi_xbbg.node, so local tests do not require a manually exported BLPAPI_ROOT.

  • Python subscription unsubscribe keeps reusable workers clean: PySubscription.unsubscribe() now propagates Bloomberg unsubscribe failures instead of suppressing them and only clears active subscription status after termination succeeds, so clean explicit unsubscribes return the subscription worker to the pool while failed/implicit cleanup keeps the conservative discard path.

  • xbbg-async async boundaries no longer perform cache disk I/O on hot Tokio paths: Request kwarg routing now uses memory-only schema metadata, explicit schema loads/persists are offloaded to blocking workers, field and exchange caches preload during engine startup, and exchange cache persistence snapshots entries before filesystem writes instead of holding cache locks across I/O.

  • Rust subscription cleanup preserves clean worker reuse and avoids blocking drop flushes: SubscriptionStream::unsubscribe() now clears active status after successful termination before the claim drops, matching the Python/NAPI clean-close path, while SubscriptionState::Drop uses best-effort try_send so OverflowPolicy::Block cannot block the subscription worker during cleanup.

  • Dynamic extractor hot paths avoid repeated linear duplicate scans and JSON clones: bds bulk rows and bdtick dynamic columns now track discovered fields with membership sets while preserving output order, and BQL JSON parsing stores borrowed intermediate values where safe before building owned Arrow arrays.

Full Changelog: v1.1.2...v1.2.0