feat: Refactor settings UI and fix commission fee recording

Settings improvements:
- Reorganize config groups with logical ordering (server, auth, ai, trading, etc.)
- Add description/tooltip for each config item with question mark icon
- Add icon to each group header
- Support i18n for descriptions (zh-CN, zh-TW, en-US)
- Move order execution config (ORDER_MODE, MAKER_WAIT_SEC, MAKER_OFFSET_BPS) to env

Commission fee fixes:
- Fix fee extraction in exchange clients: Bybit, Coinbase, Kraken, Gate, Kucoin, Bitfinex
- Properly accumulate and record commission fees in pending_order_worker
- Add fee/fee_ccy fields to wait_for_fill returns

Frontend updates:
- Remove order_mode config from trading-assistant frontend (now uses env config)
- Add sorted schema display by order field
- Add tooltip with description on hover
This commit is contained in:
TIANHE
2026-01-12 00:15:52 +08:00
parent e7cb9c6493
commit 5a4c770279
16 changed files with 1121 additions and 233 deletions
@@ -186,6 +186,8 @@ class KrakenFuturesClient(BaseRestClient):
status = str(last.get("status") or last.get("orderStatus") or "")
filled = 0.0
avg_price = 0.0
fee = 0.0
fee_ccy = ""
try:
filled = float(last.get("filledSize") or last.get("filled_size") or 0.0)
except Exception:
@@ -194,12 +196,20 @@ class KrakenFuturesClient(BaseRestClient):
avg_price = float(last.get("avgFillPrice") or last.get("avg_fill_price") or 0.0)
except Exception:
avg_price = 0.0
# Extract fee from Kraken Futures API (if available)
try:
fee = abs(float(last.get("fee") or 0.0))
except Exception:
fee = 0.0
# Kraken Futures fees are typically in USD
if fee > 0:
fee_ccy = "USD"
if filled > 0 and avg_price > 0:
return {"filled": filled, "avg_price": avg_price, "status": status, "order": last}
return {"filled": filled, "avg_price": avg_price, "fee": fee, "fee_ccy": fee_ccy, "status": status, "order": last}
if status.lower() in ("filled", "cancelled", "canceled", "rejected"):
return {"filled": filled, "avg_price": avg_price, "status": status, "order": last}
return {"filled": filled, "avg_price": avg_price, "fee": fee, "fee_ccy": fee_ccy, "status": status, "order": last}
if time.time() >= end_ts:
return {"filled": filled, "avg_price": avg_price, "status": status, "order": last}
return {"filled": filled, "avg_price": avg_price, "fee": fee, "fee_ccy": fee_ccy, "status": status, "order": last}
time.sleep(float(poll_interval_sec or 0.5))