fix: OKX spot orders below 1 unit rejected with 51000 (sz precision misread as 0 for small lotSz)#1
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.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📜 Recent review details🔇 Additional comments (1)
📝 WalkthroughWalkthrough修改了 ChangesOKX 下单精度修复
相关问题:未提供。 建议标签:bug, backend, tests 建议审阅者:未提供。 Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
backend_api_python/tests/test_okx_order_size_precision.py (1)
43-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win建议补充 lotSz="10" 的回归测试。
PR 目标中明确提到修复需覆盖
0.00000001、0.000001、1和10这几类lotSz值,但当前测试仅覆盖了lotSz="1"(exponent=0)的整数场景,未覆盖lotSz="10"(正 exponent,走max(0, -exp)钳位到 0 的分支)。这是一条与lotSz="1"不同的代码路径,建议补充一个用例以确认该分支同样正确。♻️ 建议新增的测试用例
def test_swap_integer_lot_sz_precision_zero(): # Swap contracts: lotSz=1 must keep precision 0 (whole contracts). c = _client_with_instrument("BTC-USDT-SWAP", "SWAP", "1", "1") c._inst_cache["SWAP:BTC-USDT-SWAP"][1]["ctVal"] = "0.01" sz, precision = c._normalize_order_size( inst_id="BTC-USDT-SWAP", market_type="swap", size=0.05 ) assert precision == 0 assert c._dec_str(sz, strict_precision=precision) == "5" + + +def test_swap_lot_sz_ten_precision_zero(): + # lotSz=10 exercises the positive-exponent branch of max(0, -exp). + c = _client_with_instrument("XYZ-USDT-SWAP", "SWAP", "10", "10") + c._inst_cache["SWAP:XYZ-USDT-SWAP"][1]["ctVal"] = "1" + sz, precision = c._normalize_order_size( + inst_id="XYZ-USDT-SWAP", market_type="swap", size=25 + ) + assert precision == 0 + assert c._dec_str(sz, strict_precision=precision) == "20"As per the PR objectives which state the fix "correctly handles small
lotSzvalues such as0.00000001,0.000001,1, and10", this branch should also be covered by a regression test.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend_api_python/tests/test_okx_order_size_precision.py` around lines 43 - 51, Add a regression test in test_okx_order_size_precision to cover the lotSz="10" case mentioned in the PR goals. Reuse _client_with_instrument and _normalize_order_size to build a SWAP instrument with ctVal set so the precision path exercises the positive exponent branch that clamps to 0, and assert the returned precision remains 0 and the normalized size string is correct. Keep the new test alongside test_swap_integer_lot_sz_precision_zero so the coverage is easy to find.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@backend_api_python/tests/test_okx_order_size_precision.py`:
- Around line 43-51: Add a regression test in test_okx_order_size_precision to
cover the lotSz="10" case mentioned in the PR goals. Reuse
_client_with_instrument and _normalize_order_size to build a SWAP instrument
with ctVal set so the precision path exercises the positive exponent branch that
clamps to 0, and assert the returned precision remains 0 and the normalized size
string is correct. Keep the new test alongside
test_swap_integer_lot_sz_precision_zero so the coverage is easy to find.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 536cdef8-a2fb-4329-81fe-4b9acbb26810
📒 Files selected for processing (2)
backend_api_python/app/services/live_trading/okx.pybackend_api_python/tests/test_okx_order_size_precision.py
📜 Review details
🧰 Additional context used
🪛 Ruff (0.15.20)
backend_api_python/tests/test_okx_order_size_precision.py
[error] 15-15: Possible hardcoded password assigned to argument: "secret_key"
(S106)
[error] 15-15: Possible hardcoded password assigned to argument: "passphrase"
(S106)
🔇 Additional comments (3)
backend_api_python/app/services/live_trading/okx.py (1)
257-276: LGTM!backend_api_python/tests/test_okx_order_size_precision.py (2)
1-21: LGTM!
23-40: LGTM!
Internal review PR before submitting upstream (brokermr810#159).
Problem
Spot market orders below one whole base unit fail with OKX error 51000 (
Parameter sz error) — e.g. a 50 USDT quick-trade buy of BTC/USDT (~0.0008 BTC).Root cause
OkxClient._normalize_order_size()infers size precision by string-parsinglot_sz.normalize().Decimal('0.00000001').normalize()renders as1E-8(no'.'), so precision falls back to 0 and_dec_str(sz, strict_precision=0)quantizes the size to"0".Fix
Derive precision from the Decimal exponent:
min(max(0, -exp), 18). Handles0.00000001→ 8,0.000001→ 6,1→ 0,10→ 0.Testing
tests/test_okx_order_size_precision.py(instrument cache pre-seeded, no network); first case fails on old code./api/quick-trade/place-order: previously-failing 50 USDT BTC/USDT market buy now fills (0.00081677 BTC @ 61246).Summary by CodeRabbit
lotSz被归一化为科学计数法时的误判,避免将小于 1 的数量错误格式化为0。lotSz、整数合约lotSz以及正指数归一化的精度与格式化表现。