修正期权开仓 51008 文案:不再误报资金账户 USDT,按 USDC/USDT 区分提示。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -19,32 +19,11 @@ from lib.options.options_pricing_lib import (
|
||||
)
|
||||
|
||||
_OKX_OPTION_ERR_ZH: dict[str, str] = {
|
||||
"51008": "资金账户 USDT 可用余额不足",
|
||||
"51008": "可用余额或保证金不足(期权买入请确认交易账户 USDC 足够)",
|
||||
"51018": "期权账户不能持有净空头头寸",
|
||||
"51019": "期权买入须使用逐仓模式(全仓模式下不能持有多头净头寸)",
|
||||
}
|
||||
|
||||
_OPTIONS_BALANCE_CACHE: dict[str, Any] = {"updated_at": 0.0, "data": None}
|
||||
|
||||
# public/instruments 全族缓存:合约列表变化慢,限频时用旧数据保活
|
||||
_OPTION_INSTRUMENTS_CACHE: dict[str, dict[str, Any]] = {}
|
||||
_OPTION_INSTRUMENTS_CACHE_LOCK = threading.Lock()
|
||||
_OPTION_INSTRUMENTS_CACHE_TTL = 90.0
|
||||
_OPTION_INSTRUMENTS_STALE_MAX = 600.0
|
||||
|
||||
|
||||
def invalidate_options_balance_cache() -> None:
|
||||
_OPTIONS_BALANCE_CACHE["updated_at"] = 0.0
|
||||
_OPTIONS_BALANCE_CACHE["data"] = None
|
||||
|
||||
|
||||
def invalidate_option_instruments_cache(inst_family: str | None = None) -> None:
|
||||
with _OPTION_INSTRUMENTS_CACHE_LOCK:
|
||||
if inst_family:
|
||||
_OPTION_INSTRUMENTS_CACHE.pop(str(inst_family), None)
|
||||
else:
|
||||
_OPTION_INSTRUMENTS_CACHE.clear()
|
||||
|
||||
|
||||
def _okx_trade_error_message(exc: BaseException | None = None, resp: Any = None) -> str:
|
||||
row: dict[str, Any] | None = None
|
||||
@@ -65,10 +44,18 @@ def _okx_trade_error_message(exc: BaseException | None = None, resp: Any = None)
|
||||
pass
|
||||
if row:
|
||||
code = str(row.get("sCode") or "")
|
||||
msg = str(row.get("sMsg") or "").strip()
|
||||
low = msg.lower()
|
||||
if code == "51008":
|
||||
# 勿写死「资金账户 USDT」:期权开仓常因交易户 USDC 不足
|
||||
if "usdc" in low:
|
||||
return "交易账户 USDC 可用余额不足"
|
||||
if "usdt" in low:
|
||||
return "USDT 可用余额不足(期权请先兑成 USDC 并划入交易账户)"
|
||||
return _OKX_OPTION_ERR_ZH["51008"]
|
||||
zh = _OKX_OPTION_ERR_ZH.get(code)
|
||||
if zh:
|
||||
return zh
|
||||
msg = str(row.get("sMsg") or "").strip()
|
||||
if msg:
|
||||
return msg
|
||||
if exc is not None:
|
||||
@@ -79,6 +66,28 @@ def _okx_trade_error_message(exc: BaseException | None = None, resp: Any = None)
|
||||
return "下单失败"
|
||||
|
||||
|
||||
_OPTIONS_BALANCE_CACHE: dict[str, Any] = {"updated_at": 0.0, "data": None}
|
||||
|
||||
# public/instruments 全族缓存:合约列表变化慢,限频时用旧数据保活
|
||||
_OPTION_INSTRUMENTS_CACHE: dict[str, dict[str, Any]] = {}
|
||||
_OPTION_INSTRUMENTS_CACHE_LOCK = threading.Lock()
|
||||
_OPTION_INSTRUMENTS_CACHE_TTL = 90.0
|
||||
_OPTION_INSTRUMENTS_STALE_MAX = 600.0
|
||||
|
||||
|
||||
def invalidate_options_balance_cache() -> None:
|
||||
_OPTIONS_BALANCE_CACHE["updated_at"] = 0.0
|
||||
_OPTIONS_BALANCE_CACHE["data"] = None
|
||||
|
||||
|
||||
def invalidate_option_instruments_cache(inst_family: str | None = None) -> None:
|
||||
with _OPTION_INSTRUMENTS_CACHE_LOCK:
|
||||
if inst_family:
|
||||
_OPTION_INSTRUMENTS_CACHE.pop(str(inst_family), None)
|
||||
else:
|
||||
_OPTION_INSTRUMENTS_CACHE.clear()
|
||||
|
||||
|
||||
def td_mode_for_option_buy(configured: str | None = None) -> str:
|
||||
"""OKX 买入期权(多头)必须使用逐仓."""
|
||||
mode = (configured or "isolated").strip().lower()
|
||||
|
||||
@@ -37,9 +37,24 @@ class TestOkxSpotSwap(unittest.TestCase):
|
||||
)
|
||||
result = spot_market_swap_usdt_usdc(ex, direction="usdt_to_usdc", amount=20)
|
||||
self.assertFalse(result["ok"])
|
||||
self.assertEqual(result["msg"], "资金账户 USDT 可用余额不足")
|
||||
self.assertEqual(result["msg"], "USDT 可用余额不足(期权请先兑成 USDC 并划入交易账户)")
|
||||
self.assertNotIn("{", result["msg"])
|
||||
|
||||
def test_insufficient_usdc_message(self):
|
||||
from lib.exchange.okx_options_lib import _okx_trade_error_message
|
||||
|
||||
msg = _okx_trade_error_message(
|
||||
resp={
|
||||
"data": [
|
||||
{
|
||||
"sCode": "51008",
|
||||
"sMsg": "Order failed. Insufficient USDC balance in account.",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
self.assertEqual(msg, "交易账户 USDC 可用余额不足")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user