feat: restructure OKX options UI with header funds, settings card, and dual-column layout

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-07 09:36:00 +08:00
parent 38f6bc240e
commit 090b9c6215
15 changed files with 619 additions and 225 deletions
+88
View File
@@ -70,11 +70,14 @@ def _build_cfg(app_module: Any) -> dict[str, Any]:
place_option_limit_order,
place_option_market_order,
quote_option_contract,
spot_market_swap_usdt_usdc,
transfer_ccy,
transfer_main_sub_account,
)
return {
"enabled": _env_bool("OKX_OPTIONS_ENABLED", False),
"sub_account_name": (os.getenv("OKX_SUB_ACCOUNT_NAME") or "").strip(),
"get_db": app_module.get_db,
"login_required": app_module.login_required,
"exchange_options": getattr(app_module, "exchange_options", None),
@@ -101,6 +104,8 @@ def _build_cfg(app_module: Any) -> dict[str, Any]:
"estimate_usdt_to_usdc": estimate_usdt_to_usdc,
"execute_convert": execute_convert,
"transfer_ccy": transfer_ccy,
"spot_market_swap_usdt_usdc": spot_market_swap_usdt_usdc,
"transfer_main_sub_account": transfer_main_sub_account,
"options_api_ready": options_api_ready,
}
@@ -452,6 +457,89 @@ def register_options_routes(app: Flask, cfg: dict[str, Any]) -> None:
conn.close()
return jsonify(result)
@app.route("/api/options/spot/swap", methods=["POST"])
@lr
def api_options_spot_swap():
ex, err = _require_options_ex(cfg)
if ex is None:
return jsonify({"ok": False, "msg": err})
data = request.get_json(silent=True) or {}
direction = (data.get("direction") or "usdt_to_usdc").strip()
try:
amount = float(data.get("amount"))
except (TypeError, ValueError):
return jsonify({"ok": False, "msg": "数量无效"})
return jsonify(cfg["spot_market_swap_usdt_usdc"](ex, direction=direction, amount=amount))
@app.route("/api/options/cross-transfer", methods=["POST"])
@lr
def api_options_cross_transfer():
ex, err = _require_options_ex(cfg)
if ex is None:
return jsonify({"ok": False, "msg": err})
data = request.get_json(silent=True) or {}
ccy = (data.get("ccy") or "USDT").upper()
account = (data.get("account") or "funding").strip()
direction = (data.get("direction") or "sub_to_main").strip()
try:
amount = float(data.get("amount"))
except (TypeError, ValueError):
return jsonify({"ok": False, "msg": "数量无效"})
main_to_sub = direction == "main_to_sub"
result = cfg["transfer_main_sub_account"](
ex,
ccy=ccy,
amount=amount,
sub_acct=cfg.get("sub_account_name") or "",
main_to_sub=main_to_sub,
account=account,
)
if result.get("ok"):
conn = cfg["get_db"]()
try:
init_options_tables(conn)
conn.execute(
"""
INSERT INTO options_transfer_log (ccy, amount, from_account, to_account, status, message)
VALUES (?, ?, ?, ?, 'ok', ?)
""",
(
ccy,
amount,
"main" if main_to_sub else "sub",
"sub" if main_to_sub else "main",
f"cross:{account}",
),
)
conn.commit()
finally:
conn.close()
return jsonify(result)
@app.route("/api/options/history")
@lr
def api_options_history():
ex, err = _require_options_ex(cfg)
if ex is None:
return jsonify({"ok": False, "msg": err})
conn = cfg["get_db"]()
try:
init_options_tables(conn)
rows = conn.execute(
"""
SELECT id, inst_id, underlying, opt_type, strike, sheets, eth_amount,
open_quote, premium_paid, close_quote, premium_received,
realized_pnl, status, signal_note, created_at, closed_at
FROM options_trades
ORDER BY id DESC
LIMIT 200
"""
).fetchall()
items = [dict(r) for r in rows]
finally:
conn.close()
return jsonify({"ok": True, "history": items})
def _start_monitor_thread(app: Flask, cfg: dict[str, Any]) -> None:
if app.extensions.get("options_monitor_started"):