fix: OKX spot orders below 1 unit rejected with 51000 (sz precision misread as 0 for small lotSz)#159
Open
lollipopkit wants to merge 2 commits into
Open
Conversation
Decimal.normalize() renders lotSz values like 0.00000001 in scientific notation (1E-8). The string-based precision parser found no '.' in '1E-8' and fell back to precision 0, so any spot order below one whole unit was quantized to sz="0" and rejected by OKX with error 51000 (Parameter sz error). Derive precision from the Decimal exponent instead, and add regression tests.
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.
Problem
Placing a spot market order through the OKX adapter fails with:
This affects any spot order below one whole base unit — e.g. a 50 USDT quick-trade buy of BTC/USDT (~0.0008 BTC).
Root cause
OkxClient._normalize_order_size()infers the size precision fromlotSzby string-parsing the normalized Decimal:Decimal.normalize()renders small steps in scientific notation, so BTC-USDT spot (lotSz=0.00000001) yields precision 0._dec_str(sz, strict_precision=0)then quantizes 0.00081471 down tosz="0", which OKX rejects with 51000.Fix
Derive the precision from the Decimal exponent instead of parsing the string representation:
Handles
0.00000001→ 8,0.000001→ 6,1→ 0 (whole swap contracts),10→ 0.Testing
tests/test_okx_order_size_precision.py(3 regression tests, instrument cache pre-seeded so no network needed) — all pass; the first case fails on the old code.x-simulated-trading: 1) via/api/quick-trade/place-order: a 50 USDT market buy of BTC/USDT that previously failed with 51000 now fills correctly (0.00081677 BTC @ 61246).