xbbg 1.2.0
Removed
xbbg-browser,xbbg-bridge, andxbbg-serverretired: Theapps/xbbg-serverRust HTTP server, its@xbbg/bridgenpm launcher and 5 platform-specific bridge binaries, and the@xbbg/browserHTTP client are removed.js-xbbg,napi-xbbg, andpyo3-xbbgremain the supported bindings.
Added
- Native datetime/date acceptance across all surfaces (#317):
bdh,bdib,bdtick,bqr,arequest, and thexbbg.ext.bonds/xbbg.ext.options/xbbg.ext.fixed_income/xbbg.ext.historical/xbbg.ext.futureshelpers now acceptdatetime.date,datetime.datetime(naive or tz-aware), and duck-typedpd.Timestamp(no hard pandas dependency) anywhere they previously took onlystr. ISO 8601, Bloomberg-native (YYYYMMDD), and"today"strings continue to work; ambiguousMM/DD/YYYY-style inputs are now rejected with a clearValueError. The two divergent_fmt_datehelpers were consolidated into a single source of truth inxbbg.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 toYYYYMMDDvia value-based duck typing. Mirrored on the JS side:@xbbg/coreacceptsDate, ISO/Bloomberg-nativestring, epoch-msnumber, and duck-typed LuxonDateTimeacrossbdh/bdib/bdtick/bqr/ recipe surfaces, with newformatDate/formatDateTimehelpers andDateLike/DateTimeLikeexported types. New guide atdocs/python/guides/dates. @xbbg/coresubscription replay benchmark: Added a JS-onlynpm run bench:subscription-replayharness for one-update-at-a-time synthetic replay, JSONL fixture replay, liveXBTUSD Curncycapture, and path-specific timing (legacy,arrow-decode-only,subscription-wrapper). Replay now supports--consume rows|vector|schema|noneand--warmup-iterations; row materialization remains the default. Live capture reports existingsub.statsslow-consumer telemetry without changing the production streaming API.xbbg-benchoffline Rust replay benchmarks: Added benchmark-controlled, non-Bloomberg, non-datamock harnesses for Arrow/TypedBuilderappend/finalize paths and syntheticxbbg-asyncsubscription-shaped replay. These live entirely undercrates/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-benchcached subscription-to-Arrow bridge benchmark: Added a bounded live Bloomberg subscription capture that replays cached real SDKEvent/Messageobjects throughxbbg-asyncSubscriptionStateinto 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, andbdtick/abdticknow 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, andIncludeExchangeCodes) 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/ArrowRecordBatchcarriers internally, with explicitbackend="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 realpyarrow.Table; the misleadingBackend.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/coresubscriptions 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 publicSubscription.next(): TableAPI remains unchanged.@xbbg/coreexposes full Bloomberg subscription payloads: JS streaming APIs now acceptallFields: true, forwarding the existing Rust engineall_fieldsmode so callers can receive every top-level scalar field Bloomberg sends instead of only requested fields plusMKTDATA_EVENT_TYPE/MKTDATA_EVENT_SUBTYPE. The NAPI zero-copy bridge also supportstime64[us]columns for dynamic all-fields schemas.- Rust Bloomberg SDK handle ownership hardened:
xbbg-corenow models session-owned SDK views with Rust lifetimes instead of unsupportedSend/Syncmarker 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
fieldExceptionslogging aggregated: Per-securityfieldExceptionsdiagnostics now stay atDEBUGwith field-level detail, while bulk requests emit a single summary warning with total exception count and affected tickers. @xbbg/coreTypeScript request surface completed: JS wrappers now forwardvalidateFieldsonbdp/bds/bdh,requestTz/outputTzonbdib/bdtick, and typedbdtickinclude-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; onlytickerandfieldare 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, andbgovtsnow expose static signatures for parameter hints, hover docs, and go-to-definition. Top-levelxbbgexports were also completed forabqr/bqrand 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()andxbbg.ext.bqr()now default toBID/ASKquote events withincludeBrokerCodes=true, normalize output to the 0.x-compatibleevent_type/price/broker_buy/broker_sellcolumns, 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 withinclude_broker_codes=False. Low-data live coverage uses an@MSG1 Corpfixed-income ISIN fixture capped withmaxDataPoints=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 Curncyquote updates keepBID/ASKasFloat64instead of degrading the Arrow schema toUtf8before 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 viaFUT_TRADING_HRS, and applies the Japan equity09:00-15:30session rule somarket_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. -
bdtickinclude-code options now keep typed tick tables (#309):IntradayTickStatedynamically discovers scalar fields inside Bloomberg'stickData.tickData[]rows, so options such asincludeConditionCodes,includeExchangeCodes, andincludeBloombergStandardConditionCodesadd 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 astickData.eidDataremains excluded from per-tick rows. -
bdsbulk rows discover subfields across the whole response:BulkDataStatenow 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. -
bdsmanually 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-locallibclang.dllalias for pixi/conda's versionedlibclang-*.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:
securityDatavalue arrays now useget_element(0)rather than child-element lookup, matching the SDK response shape. -
@xbbg/coreTypeScript package metadata repaired: Native optional dependencies now use package versions instead of localfile:links, release scripts use a checked-in CJS platform map helper, packaged-install smoke checks the publisheddistentrypoint, and the npm package includes the Apache license. -
@xbbg/corelocal Windows runtime loading fixed: The Node binding now adds the vendored Bloomberg SDK runtime DLL directory fromvendor/blpapi-sdk/<version>(orXBBG_DEV_SDK_ROOT) toPATHbefore loadingnapi_xbbg.node, so local tests do not require a manually exportedBLPAPI_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-asyncasync 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, whileSubscriptionState::Dropuses best-efforttry_sendsoOverflowPolicy::Blockcannot block the subscription worker during cleanup. -
Dynamic extractor hot paths avoid repeated linear duplicate scans and JSON clones:
bdsbulk rows andbdtickdynamic 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