fix(binance): show full funding wallet USDT balance

Sum free+locked/freeze from ccxt funding balance and fall back to get-funding-asset SAPI so the header matches Binance APP funding account.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-04 07:07:36 +08:00
parent 1b3f661bad
commit dd74770c66
+66 -8
View File
@@ -2599,23 +2599,65 @@ def exchange_private_api_configured():
return bool(BINANCE_API_KEY and BINANCE_API_SECRET)
def _float_balance_field(val):
if val is None or val == "":
return None
try:
return float(val)
except (TypeError, ValueError):
return None
def _extract_usdt_total(balance):
usdt_info = balance.get("USDT", {}) if isinstance(balance, dict) else {}
total_map = balance.get("total", {}) if isinstance(balance, dict) else {}
free_map = balance.get("free", {}) if isinstance(balance, dict) else {}
used_map = balance.get("used", {}) if isinstance(balance, dict) else {}
total = usdt_info.get("total")
if total is None:
total = usdt_info.get("equity")
if total is None:
total = total_map.get("USDT")
if total is None:
total = usdt_info.get("free")
if total is None:
total = free_map.get("USDT")
try:
return float(total) if total is not None else None
except Exception:
if total is not None:
fv = _float_balance_field(total)
if fv is not None:
return fv
free = usdt_info.get("free")
if free is None:
free = free_map.get("USDT")
used = usdt_info.get("used")
if used is None:
used = used_map.get("USDT")
if used is None:
used = usdt_info.get("locked")
free_f = _float_balance_field(free)
used_f = _float_balance_field(used) or 0.0
if free_f is not None:
return free_f + used_f
return None
def _parse_binance_funding_asset_rows(rows):
"""解析 /sapi/v1/asset/get-funding-assetUSDT 总额 = free + freeze + locked + withdrawing。"""
if isinstance(rows, dict):
rows = [rows]
if not isinstance(rows, list):
return None
for row in rows:
if not isinstance(row, dict):
continue
if str(row.get("asset") or "").upper() != "USDT":
continue
parts = [
_float_balance_field(row.get("free")),
_float_balance_field(row.get("freeze")),
_float_balance_field(row.get("locked")),
_float_balance_field(row.get("withdrawing")),
]
nums = [p for p in parts if p is not None]
if nums:
return sum(nums)
return None
def _extract_usdt_free(balance):
@@ -2690,7 +2732,7 @@ def _fetch_binance_swap_usdt_free():
def _fetch_binance_funding_usdt():
"""Binance 资金账户(Funding WalletUSDT 总额。"""
"""Binance 资金账户(Funding WalletUSDT 总额(free+冻结+锁定,与 APP 资金账户一致)"""
try:
ensure_markets_loaded()
bal = exchange.fetch_balance(params={"type": "funding"})
@@ -2699,6 +2741,22 @@ def _fetch_binance_funding_usdt():
return float(val)
except Exception:
pass
try:
ensure_markets_loaded()
raw = exchange.sapiPostAssetGetFundingAsset({"asset": "USDT"})
val = _parse_binance_funding_asset_rows(raw)
if val is not None:
return float(val)
except Exception:
pass
try:
ensure_markets_loaded()
raw = exchange.sapiPostAssetGetFundingAsset({})
val = _parse_binance_funding_asset_rows(raw)
if val is not None:
return float(val)
except Exception:
pass
return None