fix: infer Bybit, Bitget and Binance precision from Decimal exponent - #243
Merged
brokermr810 merged 1 commit intoSep 13, 2026
Conversation
Decimal.normalize() renders steps below 1E-6 in scientific notation, so parsing the string for a '.' read the precision of a 0.0000001 tick or a 0.00000001 lot step as 0 and truncated prices and quantities to integers. Apply the exponent-based inference already used for OKX lotSz.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The OKX client was fixed to infer lot precision from the Decimal exponent, because
Decimal.normalize()turns small steps into scientific notation (Decimal("0.0000001").normalize()is1E-7, with no.in it). I found the same string parsing still in place in the Bybit and Bitget clients and inBinanceSpotClient._decimal_places_from_step, which the Binance futures client also uses. For any step or tick at 1E-7 or smaller, precision comes out as 0.That value then goes to
_dec_str(..., strict_precision=0), which rounds down to an integer. Take Bybit linear with atickSizeof0.0000001: a limit price of0.01234567is sent as"0". Quantities with an0.00000001step are cut the same way, and on Binance futuresmin(quantityPrecision, 0)keeps the 0.Changes
bybit.py:_normalize_qtyand_normalize_priceget the precision fromstep.normalize().as_tuple().exponent, the same wayokx.pyalready doesbitget.py: same change in_normalize_sizeand_normalize_price, for the fallback used whensizePlace/pricePlaceare missingbinance_spot.py:_decimal_places_from_stepuses the exponent tootests/test_step_precision_scientific_notation.pywith one case for each call siteSteps of 1E-6 or more and integer steps like
10(1E+1, precision 0) give the same result as before, so nothing changes for the instruments that already worked.Test plan
docker compose up -d --buildWithout the fix, all 5 new tests fail on the value itself (
assert 0 == 7,assert 0 == 8). With it they pass, and the fulltests/suite gives 2343 passed and 20 skipped (Python 3.12).ruff check app scripts tests,scripts/backend_quality_check.pyandscripts/check_mojibake.pyalso pass. I didn't run the Docker stack because the change doesn't touch any route or config.API documentation (if routes/schemas changed)
No routes or schemas changed.
AI tools used