refactor: flatten account command to a single balances view

Remove overview/balances/positions subcommands in favor of one
`account` command that returns all balances with an `is_dust` flag.
Add descriptions to every parser and expose -a/--agent and --doc
on all leaf commands for better help discoverability.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-17 18:19:19 +08:00
parent d629c25232
commit 3855477155
7 changed files with 123 additions and 165 deletions

View File

@@ -13,6 +13,7 @@ class AssetBalance:
locked: float
total: float
notional_usdt: float
is_dust: bool
@dataclass
@@ -59,6 +60,7 @@ def get_balances(
spot_client: Any,
) -> dict[str, Any]:
quote = str(config.get("market", {}).get("default_quote", "USDT")).upper()
dust = float(config.get("trading", {}).get("dust_usdt_threshold", 0.0))
rows: list[dict[str, Any]] = []
balances, _, price_map = _spot_account_data(spot_client, quote)
for item in balances:
@@ -68,6 +70,7 @@ def get_balances(
if total <= 0:
continue
asset = item["asset"]
notional = total * price_map.get(asset, 0.0)
rows.append(
asdict(
AssetBalance(
@@ -75,7 +78,8 @@ def get_balances(
free=free,
locked=locked,
total=total,
notional_usdt=total * price_map.get(asset, 0.0),
notional_usdt=notional,
is_dust=notional < dust,
)
)
)
@@ -113,60 +117,3 @@ def get_positions(
)
)
return {"positions": rows}
def get_overview(
config: dict[str, Any],
*,
spot_client: Any,
) -> dict[str, Any]:
quote = str(config.get("market", {}).get("default_quote", "USDT")).upper()
dust = float(config.get("trading", {}).get("dust_usdt_threshold", 0.0))
balances: list[dict[str, Any]] = []
positions: list[dict[str, Any]] = []
spot_balances, _, price_map = _spot_account_data(spot_client, quote)
for item in spot_balances:
free = float(item.get("free", 0.0))
locked = float(item.get("locked", 0.0))
total = free + locked
if total <= 0:
continue
asset = item["asset"]
balances.append(
asdict(
AssetBalance(
asset=asset,
free=free,
locked=locked,
total=total,
notional_usdt=total * price_map.get(asset, 0.0),
)
)
)
mark_price = price_map.get(asset, 1.0 if asset == quote else 0.0)
notional = total * mark_price
if notional >= dust:
positions.append(
asdict(
PositionView(
symbol=quote if asset == quote else f"{asset}{quote}",
quantity=total,
entry_price=None,
mark_price=mark_price,
notional_usdt=notional,
side="LONG",
)
)
)
spot_equity = sum(item["notional_usdt"] for item in balances)
overview = asdict(
AccountOverview(
total_equity_usdt=spot_equity,
spot_equity_usdt=spot_equity,
spot_asset_count=len(balances),
spot_position_count=len(positions),
)
)
return {"overview": overview, "balances": balances, "positions": positions}