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:
@@ -2599,22 +2599,64 @@ def exchange_private_api_configured():
|
|||||||
return bool(BINANCE_API_KEY and BINANCE_API_SECRET)
|
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):
|
def _extract_usdt_total(balance):
|
||||||
usdt_info = balance.get("USDT", {}) if isinstance(balance, dict) else {}
|
usdt_info = balance.get("USDT", {}) if isinstance(balance, dict) else {}
|
||||||
total_map = balance.get("total", {}) 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 {}
|
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")
|
total = usdt_info.get("total")
|
||||||
if total is None:
|
if total is None:
|
||||||
total = usdt_info.get("equity")
|
total = usdt_info.get("equity")
|
||||||
if total is None:
|
if total is None:
|
||||||
total = total_map.get("USDT")
|
total = total_map.get("USDT")
|
||||||
if total is None:
|
if total is not None:
|
||||||
total = usdt_info.get("free")
|
fv = _float_balance_field(total)
|
||||||
if total is None:
|
if fv is not None:
|
||||||
total = free_map.get("USDT")
|
return fv
|
||||||
try:
|
free = usdt_info.get("free")
|
||||||
return float(total) if total is not None else None
|
if free is None:
|
||||||
except Exception:
|
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-asset:USDT 总额 = 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
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -2690,7 +2732,7 @@ def _fetch_binance_swap_usdt_free():
|
|||||||
|
|
||||||
|
|
||||||
def _fetch_binance_funding_usdt():
|
def _fetch_binance_funding_usdt():
|
||||||
"""Binance 资金账户(Funding Wallet)USDT 总额。"""
|
"""Binance 资金账户(Funding Wallet)USDT 总额(free+冻结+锁定,与 APP 资金账户一致)。"""
|
||||||
try:
|
try:
|
||||||
ensure_markets_loaded()
|
ensure_markets_loaded()
|
||||||
bal = exchange.fetch_balance(params={"type": "funding"})
|
bal = exchange.fetch_balance(params={"type": "funding"})
|
||||||
@@ -2699,6 +2741,22 @@ def _fetch_binance_funding_usdt():
|
|||||||
return float(val)
|
return float(val)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
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
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user