unicorn-binance-local-depth-cache Change Log¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
Discussions about unicorn-binance-local-depth-cache releases!
How to upgrade to the latest version!
2.14.0.dev (development stage/unreleased/unstable)¶
2.14.1¶
Changed¶
Bumped minimum
unicorn-binance-websocket-apidependency from>=2.12.2to>=2.13.0insetup.py,requirements.txt,pyproject.toml,environment.ymlandmeta.yaml. UBWA 2.13.0 introduces the per-category Futures WebSocket routing (/public,/market,/private) required by Binance since 2026-04-23 and raisesValueErroron mixed-category streams. See unicorn-binance-websocket-api#437.
2.14.0¶
Changed¶
Breaking: renamed the cluster client’s credential methods to drop the redundant
ubdcc_prefix and align with the rest of the API:ubdcc_add_credentials()→add_credentials(),ubdcc_remove_credentials()→remove_credentials(),ubdcc_get_credentials_list()→get_credentials_list()(each with its_asyncvariant). The matching UBDCC REST endpoints were renamed too (/ubdcc_*_credentials*→/*_credentials*) — use UBDCC ≥ 0.7.0. Examples underexamples/unicorn_binance_depth_cache_cluster/updated.
Fixed¶
manager.py: REST snapshot support for Binance margin exchanges. The exchange switch in_get_order_book_from_rest()had no case forbinance.com-margin,binance.com-margin-testnet,binance.com-isolated_marginandbinance.com-isolated_margin-testnet, so the snapshot returnedNoneand the DepthCache never reached thesynchronizedstate. Margin markets use the spot REST endpoint (/api/v3/depth) and the spot WebSocket diff-depth format (U/u), so they are now routed through the same code path asbinance.comacross all four exchange switches inmanager.py(snapshot fetch, live-update gap detection, post-sync buffer replay gap detection, and init-phase sync-point detection).
2.13.0¶
Added¶
manager.py: Newset_credentials(api_key, api_secret)method onBinanceLocalDepthCacheManager— swap the internalBinanceRestApiManagerto a fresh instance bound to the given credentials at runtime, without recreating the depth cache manager or interrupting the WebSocket streams. New credentials take effect from the next REST call (snapshot / resync). PassNone/Noneto drop credentials and fall back to public rate limits. Enables UBDCC DCNs to react to credential rebalances pushed from the cluster management.
2.12.3¶
Fixed¶
manager.py:binance.com-vanilla-optionsdepth caches never reached thesynchronizedstate because Binance’s/eapi/v1/depthREST endpoint serves a cached snapshot whoselastUpdateIdcan lag the live diff stream by ~25–30 seconds. With the snapshot consistently older than every buffered event, no event satisfied theU <= lastUpdateId <= usync predicate, and the previous replay implementation dropped the init buffer on every failed attempt, guaranteeing an endless resync loop. The init buffer is now retained across resync attempts (pruned byu < lastUpdateIdand capped at 10 000 entries), so once Binance’s REST cache rotates far enough forward, a previously buffered event matches the sync predicate and the cache synchronises. Spot and Futures are unaffected because their REST snapshots are live; behaviour for those exchanges is identical when the first replay finds the sync point on the first try (the common case). Post-sync events that were already in the buffer are now applied via the regular gap-detection path (Spot:U == lastUpdateId + 1, Futures/Options:pu == lastUpdateId) instead of being silently discarded, which also closes a pre-existing gap where fast initial bursts could leave the cache one or more events behind immediately after sync.
2.12.2¶
Changed¶
Bumped minimum
unicorn-binance-websocket-apidependency from>=2.12.0to>=2.12.2insetup.py,requirements.txt,pyproject.toml,environment.ymlandmeta.yaml. 2.12.2 is the cleanup-round UBWA release.setup.py,dev/set_version.py,dev/test_plain.py: file headerAuthor: LUCIT Systems and Development→Oliver Zehentleitner, copyrightLUCIT Systems and Development (2022-2023)→Oliver Zehentleitner (2022-2026).dev/test_plain.py: dropped the obsoletefrom lucit_licensing_python.exceptions import NoValidatedLucitLicenseimport and the correspondingtry/except NoValidatedLucitLicensewrapper — the LUCIT licensing manager has been removed from UBLDC.SECURITY.md: replaced the lucit.tech contact form URL with the GitHub Security Advisories private-reporting URL.README: switched all conda references from the legacy
lucitchannel toconda-forge. Added conda-forge version / downloads / feedstock build badges. Removed the “There is no conda support until migration” placeholders. Install section is now a singleconda install -c conda-forge unicorn-binance-local-depth-cache.README: reworded the PyPy paragraph. The old sentence (“For the PyPy interpreter we offer packages only from Python version 3.9 and higher”) made sense when we still shipped wheels for pre-3.9 CPython; replaced with “PyPy wheels are available for all supported Python versions.” Also dropped the stale “Anaconda packages are available from Python version 3.8 and higher” line and fixed the Python range in the Installation section to 3.9 – 3.14.
Aligned dependency pins across
requirements.txt,setup.py,pyproject.toml,environment.ymlandmeta.yamlusingsetup.pyas the source of truth (Cython>=3.0.10,requests>=2.32.3;orjsonwas missing fromenvironment.ymland has been added).environment.yml: dropped thelucitchannel and thedefaultschannel; removedlucit::prefixes on suite deps; bumpedpython>=3.8topython>=3.9to match the rest.meta.yaml: removed the leftoverchannels:anddependencies:blocks (they areenvironment.ymlkeys, not valid inmeta.yaml). Dropped thelucit::channel prefixes from suite deps. Re-embedded the currentREADME.mdintoabout.description. License is MIT.
Removed¶
.github/workflows/build_conda.yml: the conda-forge feedstock (conda-forge/unicorn-binance-local-depth-cache-feedstock) now builds and publishes the conda package; no in-repo build is needed.
2.12.1¶
Fixed¶
Options depth cache: default to
depth@500mswhendepth_cache_update_intervalis not set (Options has no bare@depthstream)
2.12.0¶
Added¶
Support for Binance European Options (Vanilla Options) depth caches via
exchange="binance.com-vanilla-options"New exchange strings:
binance.com-vanilla-options,binance.com-vanilla-options-testnetOptions depth cache uses the same sync algorithm as Futures (
pu-based gap detection)
Changed¶
Minimum dependency:
unicorn-binance-rest-api>=2.10.0(Options Market Data API)Minimum dependency:
unicorn-binance-websocket-api>=2.12.0(Options exchange support)
2.11.2¶
Fixed¶
Error in GitHub Action
2.11.1¶
Fixed¶
Dependency conflict
2.11.0¶
Added¶
Clusterclass now wraps the UBDCC 0.4.0 credential endpoints:ubdcc_add_credentials,ubdcc_remove_credentials,ubdcc_get_credentials_list(each with a sync + async variant). Lets you manage per-account-group Binance API key pairs on a running cluster without falling back to raw HTTP. Public responses keep keys masked and never exposeapi_secret. Two demo scripts underexamples/unicorn_depthcache_cluster_for_binance/(manage-credentials.py/-async.py).on_restartcallback parameter onBinanceLocalDepthCacheManager— invoked ason_restart(market, timestamp)every time a stream restart is detected, once per market on the affected stream. Enables reactive consumers (e.g. UBDCC) to forward restart events without polling.get_last_restart_time(market)— returns Unix timestamp of the last stream restart serving this market (orNoneif not restarted yet)get_restart_count(market)— returns the number of restarts of the stream serving this marketBoth getters expose UBLDC’’’s existing per-stream restart tracking as a clean public API for on-demand queries (complement to the callback).
2.10.0¶
Changed¶
cluster.py: switched from stdlib
jsontoorjson(suite-wide standard) — addedorjsonto dependenciescluster.py:
create_depthcache(s)switched from GET to POST — markets list is now sent as JSON body to UBDCC 0.2.0, fixing URL-too-long errors when creating many DepthCaches at onceREADME: updated cluster section (no longer “K8s application” — also runs locally via
pip install ubdcc)
Fixed¶
manager.py:
get_latest_version()crashed withAttributeError: 'NoneType' object has no attribute 'get'when the GitHub API request failed — now checksisinstance(status, dict)before calling.get()cluster.py: fixed double JSON serialization in POST requests (
json=json.dumps(params)→json=params) that caused server-side 500 errorsunittest: updated test_create_depthcache(s) to mock
requests.post(notrequests.get) after the GET→POST switchREADME: fixed wrong
ubdcc_port, method names, typo “DephtCache” → “DepthCache”
2.9.0¶
Added¶
Added
get_last_update_time(market)— returns Unix timestamp in milliseconds of the last processed depth update, orNoneif not yet synced (closes #35)Added support for exchange
trbinance.com(closes #13) — note: TRBinance requires an API key even for public REST endpoints; passapi_key/api_secrettoBinanceRestApiManagerAdded Python 3.14 support
Added mocked unit tests for
Clusterclass (cluster.py)
Fixed¶
manager.py: detect REST API error responses in
_get_order_book_from_rest()and log clearly instead of failing silently with aKeyError— includes hint fortrbinance.comabout required API keycluster.py: replaced
print()with properloggercalls in_request()and_request_async()—errorfor network/client failures,warningfor timeouts and cancellations
Changed¶
build_wheels.yml: Upgraded
cibuildwheelfromv3.0.0tov3.4.1setup.py: Fixed author from “LUCIT Systems and Development” to “Oliver Zehentleitner”
Removed¶
Dropped Python 3.8 support
Removed
Cluster.submit_license()andCluster.submit_license_async()— LUCIT licensing is goneRemoved
ClusterEndpoints.submit_licenseendpoint definitionRemoved
examples/unicorn_depthcache_cluster_for_binance/submit-license*.pyCluster.test_connection(): updated app name check fromlucit-ubdcc-restapitoubdcc-restapi
2.8.1¶
Added¶
build_wheels.yml:
CIBW_ARCHS_LINUX: “x86_64 aarch64” CIBW_ARCHS_MACOS: “x86_64 arm64 universal2” CIBW_ARCHS_WINDOWS: “AMD64” CIBW_MUSLLINUX_X86_64_IMAGE: “musllinux_1_1”
Changed¶
Moved from https://github.com/LUCIT-Systems-and-Development/ to https://github.com/oliver-zehentleitner
Removed¶
LUCIT Licensing Manager
2.8.0¶
Changed¶
get_list_of_depth_caches()is deprecated, useget_list_of_depthcaches()instead! From now on, only active DepthCaches are returned!stop_depthcache()removes asks and bids, but the rest of the DepthCache remains.
2.7.0¶
Changed¶
Holding the thread lock is now in the more abstract functions.
Fixed¶
‘Uncontrolling growth of elements in lists of asks and bids in Depth Cache Manager’ issue#45 Thanks to @chubatrik for finding and reporting it!
‘error’ and ‘result’ messages are now processed separately with corresponding log levels.
In
_get_book_side()only the thread lock of ‘bid’ was used by mistake, also for ‘asks’. This has now been corrected.‘stop_depth_cache returns “error_msg: stream_id is missing!”’ issue#46
2.6.0¶
Added¶
Counting restarts and logging last restart time in
ubldc.dc_streams.
2.5.0¶
Added¶
Support of
auto_data_cleanup_stopped_streams- Passthrough to UBWA.
2.4.1¶
Fixed¶
ValueError in
stop_depthcache()
2.4.0¶
Changed¶
Rewrite of the init process. Now it is possible to successfully create much more DepthCaches than before!
2.3.0¶
Added¶
Async client functions for interacting with the UNICORN DepthCache Cluster for Binance.
Fixed¶
DepthCache management now correctly handles refreshes.
2.2.0¶
Added¶
Experimental Client functions for interacting with the UNICORN DepthCache Cluster for Binance
Support multiple streams to bypass subscription limit per stream
Changed¶
Dropping support for Python 3.7
Renamed¶
‘ubldc.create_depth_cache()’ -> ‘ubldc.create_depthcache()’
‘ubldc.stop_depth_cache()’ -> ‘ubldc.stop_depthcache()’
2.1.1¶
Fixed¶
Wrong sort order in
get_asks()- bug was released with 2.1.0.
2.1.0¶
Stability and performance optimization
Added¶
DepthCache specific infos to
print_summary().
Changed¶
More granular and efficient transfer of update values.
init_time_windowdefault value 10 to 5websocket_ping_intervaldefault value 5 to 10websocket_ping_timeoutdefault value 15 to 20
Fixed¶
Filtering and removing 0 values now works with all formats. (0.0, 0.000, 0.0000000, …)
Updates were erroneously applied twice in
_init_depth_cache().Handling all stream signals of UBWA clearly.
RuntimeError in the for loop of
_sort_depth_cache()
2.0.0¶
Scaling. The core functions have been rewritten in this update. Instead of one stream per depth_cache, we now use one
stream up to the max subscription limit of the endpoint and use the new UBWA asyncio_queue interface.
get_stream_data_from_asyncio_queue(). And we avoid bans by complying with Binance weight costs on init.
Added¶
Support for “binance.us”
Since UBLDC is delivered as a compiled C extension, IDEs such as Pycharm and Visual Code cannot use information about available methods, parameters and their types for autocomplete and other intellisense functions. As a solution, from now on stub files (PYI) will be created in the build process and attached to the packages. The IDEs can automatically obtain the required information from these.
ubldc.get_ubwa_manager()returns the UBWA instance of UBLDCubldc.get_ubra_manager()returns the UBRA instance of UBLDCNew exceptions:
DepthCacheAlreadyStoppedandDepthCacheNotFound
Changed¶
The parameter
ubwa_managerwas removed fromBinanceLocalDepthCacheManager(), because UBLDC has to claim the callback function of thestream_signalsfor itself and has to initialize the instance itself. It is possible to request the activeBinanceWebSocketApiManager()instance with the new methodubldc.get_ubwa_manager().ubwa.create_stream()can be used normally, only thestream_signalsare only accessible for UBLDC.Updated description text in all files.
Fixed¶
Ip ban when using
create_depth_cachewith many symbols issue#30Import in
licensing_manager.py.Type of global
loggervariable.
Security¶
Set higher minimum version 2.4.0 for unicorn-binance-rest-api are affected by vulnerabilities in used dependencies!
Dependency
certifi:CVE-2023-37920, Score: 9.8 (High)
Certifi is a curated collection of Root Certificates for validating the trustworthiness of SSL certificates while verifying the identity of TLS hosts. Certifi 1.0.1 through 2023.5.7 recognizes “e-Tugra” root certificates. e-Tugra’s root certificates were subject to an investigation prompted by reporting of security issues in their systems. Certifi 2023.07.22 removes root certificates from “e-Tugra” from the root store.
https://devhub.checkmarx.com/cve-details/CVE-2023-37920/
Dependency
cryptography:CVE-2023-38325, Score: 7.5 (High)
The cryptography package versions prior to 41.0.2 for Python mishandles SSH certificates that have critical options.
https://devhub.checkmarx.com/cve-details/CVE-2023-38325/
CVE-2023-49083, Score: 7.5 (High)
Cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. Calling
load_pem_pkcs7_certificatesorload_der_pkcs7_certificatescould lead to a NULL-pointer dereference and segfault. Exploitation of this vulnerability poses a serious risk of Denial of Service (DoS) for any application attempting to deserialize a PKCS7 blob/certificate. The consequences extend to potential disruptions in system availability and stability. This issue affects versions 3.1 through 41.0.5.https://devhub.checkmarx.com/cve-details/CVE-2023-49083/
CVE-2023-50782, Score: 7.5 (High)
A flaw was found in the python cryptography package versions prior to 42.0.0. This issue may allow a remote attacker to decrypt captured messages in TLS servers that use RSA key exchanges, which may lead to exposure of confidential or sensitive data. This issue is an incomplete fix of CVE-2020-25659.
https://devhub.checkmarx.com/cve-details/CVE-2023-50782/
CVE-2024-26130, Score: 7.5 (High)
cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. Starting in version 38.0.0 and prior to version 42.0.4, if
pkcs12.serialize_key_and_certificatesis called with both a certificate whose public key did not match the provided private key and anencryption_algorithmwithhmac_hashset (viaPrivateFormat.PKCS12.encryption_builder().hmac_hash(...), then a NULL pointer dereference would occur, crashing the Python process. This has been resolved in version 42.0.4, the first version in which aValueErroris properly raised.https://devhub.checkmarx.com/cve-details/CVE-2024-26130/
Dependency
requests:CVE-2023-32681, Score: 6.1 (Medium)
Requests is a HTTP library. Requests has been leaking Proxy-Authorization headers to destination servers when redirected to an HTTPS endpoint. This is a product of how we use
rebuild_proxiesto reattach theProxy-Authorizationheader to requests. For HTTP connections sent through the tunnel, the proxy will identify the header in the request itself and remove it prior to forwarding to the destination server. However when sent over HTTPS, theProxy-Authorizationheader must be sent in the CONNECT request as the proxy has no visibility into the tunneled request. This results in Requests forwarding proxy credentials to the destination server unintentionally, allowing a malicious actor to potentially exfiltrate sensitive information. This issue affects versions 2.3.0 through 2.30.0.https://devhub.checkmarx.com/cve-details/CVE-2023-32681/
1.0.0¶
Added¶
Support for Python 3.11 and 3.12
Integration of the
lucit-licensing-pythonlibrary for verifying the UNICORN Binance Suite license. A license can be purchased in the LUCIT Online Shop: https://shop.lucit.services/software/unicorn-binance-suiteLicense change from MIT to LSOSL - LUCIT Synergetic Open Source License: https://github.com/oliver-zehentleitner/unicorn-binance-local-depth-cache/blob/master/LICENSE
Conversion to a C++ compiled Cython package with precompiled as well as PyPy and source code wheels.
Setup of a “Trusted Publisher” deployment chain. The source code is transparently packaged into wheels directly from the GitHub repository by a GitHub action for all possible platforms and published directly as a new release on GitHub and PyPi. A second process from Conda-Forge then uploads it to Anaconda. Thus, the entire deployment process is transparent and the user can be sure that the compilation of a version fully corresponds to the source code.
manager.stop_manager()alias formanager.stop_manager_with_all_caches()Support for
with-context.
0.7.3¶
Fixed¶
TypeError exception in
_init_depth_cache[issue#27](https://github.com/oliver-zehentleitner/unicorn-binance-local-depth-cache/issues/27
0.7.2¶
Codebase equal to 0.7.0, testing azure pipe
0.7.1¶
Codebase equal to 0.7.0, just preparing conda-forge packaging
0.7.0¶
Added¶
Active
high_performanceof UBWA.Exception handling for REST calls
Improved logging
Changed¶
Websocket reconnect intervals
Reduced calls of
market.lower()
Removed¶
Obsolete variable
self.timeout
0.6.0¶
Added¶
default_websocket_close_timeout,default_websocket_ping_interval,default_websocket_ping_timeoutandwebsocket_close_timeout,websocket_close_timeout,websocket_ping_interval
Changed¶
default_websocket_close_timeout,default_websocket_ping_interval,default_websocket_ping_timeoutdefault values is 1, so websockets disconnect very fast, and we recognize “out of sync” very fast.
0.5.3¶
Changed¶
Balanced log levels
Fixed¶
KeyError in
stop_depth_cache()
0.5.2¶
Changed¶
close_timeout=5 in
create_stream()
Fixed¶
_init_depth_cache()returns False iforder_bookis False
0.5.1¶
Fixed¶
Wrong proof of
is_stop_request()
0.5.0¶
Added¶
_reset_depth_cache()_get_order_book_from_depth_cache()is_stop_request()
Changed¶
Clear stream_buffer on disconnect
Better error handling in
_init_depth_cache()
Fixed¶
stop_depth_cache()did not stop its dependent stream and did not clear the stream_bufferA few error handling’s
0.4.1¶
Added¶
Resetting asks and bits on stream_signal DISCONNECT
Fixing¶
requests.exceptions.ConnectionErrorexception while fetching the order_book
0.4.0¶
Added¶
default_update_interval
Changes¶
a few small :)
0.3.0¶
Added¶
threading.Lock():
self.threading_lock_askandself.threading_lock_bid
Added¶
set_refresh_request()
0.2.0¶
Added¶
Binance Futures support (exchange=”binance.com-futures”)
Changed¶
create_depth_cache()renamed parametermarkettomarkets.marketscan be a str or a list of one or more market symbolsstop_depth_cache()renamed parametermarkettomarkets.marketscan be a str or a list of one or more market symbolsRenamed
stop_manager()tostop_manager_with_all_caches()
Removed¶
create_depth_caches()stop_depth_caches()
0.1.0¶
Initial Release!

