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
+1
View File
@@ -114,6 +114,7 @@ OKX_OPTIONS_BUDGET_BUFFER=0.95
OKX_OPTIONS_DEFAULT_UNDERLY=ETH
OKX_OPTIONS_MAX_DTE_DAYS=2
OKX_OPTIONS_CHAIN_MAX_DTE_DAYS=14
OKX_SUB_ACCOUNT_NAME=
OKX_OPTIONS_ITM_MAX_DIST_USD=30
OKX_OPTIONS_PROFIT_ALERT_RATIO=1.0
OKX_OPTIONS_POLL_SECONDS=15
+29 -2
View File
@@ -343,6 +343,7 @@ OKX_OPTIONS_API_SECRET = os.getenv("OKX_OPTIONS_API_SECRET", "")
OKX_OPTIONS_API_PASSPHRASE = os.getenv("OKX_OPTIONS_API_PASSPHRASE", "")
OKX_OPTIONS_TRADE_BUDGET_USDC = float(os.getenv("OKX_OPTIONS_TRADE_BUDGET_USDC", "10"))
OKX_OPTIONS_DEFAULT_UNDERLY = (os.getenv("OKX_OPTIONS_DEFAULT_UNDERLY") or "ETH").strip().upper()
OKX_SUB_ACCOUNT_NAME = (os.getenv("OKX_SUB_ACCOUNT_NAME") or "").strip()
OKX_TD_MODE = os.getenv("OKX_TD_MODE", "cross")
OKX_POS_MODE = os.getenv("OKX_POS_MODE", "hedge")
EXCHANGE_DISPLAY_NAME = (os.getenv("EXCHANGE_DISPLAY_NAME") or "OKX").strip() or "OKX"
@@ -6505,6 +6506,14 @@ def render_main_page(page="trade", embed_mode=None):
funding_capital, trading_capital = None, None
funding_usdt = round(funding_capital, FUNDS_DECIMALS) if funding_capital is not None else None
current_capital = round(trading_capital, FUNDS_DECIMALS) if trading_capital is not None else round(local_current_capital, FUNDS_DECIMALS)
options_trading_usdc = None
if OKX_OPTIONS_ENABLED and exchange_options.apiKey:
try:
from lib.exchange.okx_options_lib import fetch_options_trading_usdc
options_trading_usdc = fetch_options_trading_usdc(exchange_options)
except Exception:
options_trading_usdc = None
recommended_capital = get_recommended_capital(current_capital)
key_list = (
conn.execute("SELECT * FROM key_monitors").fetchall() if plan.key_list else []
@@ -6622,7 +6631,8 @@ def render_main_page(page="trade", embed_mode=None):
total=total,
rate=rate,
profit_loss_ratio=profit_loss_ratio,
total_funds=total_funds_usdt(funding_usdt, current_capital),
total_funds=total_funds_usdt(funding_usdt, current_capital, options_trading_usdc),
options_trading_usdc=options_trading_usdc,
trading_day=trading_day,
daily_start_capital=DAILY_START_CAPITAL,
current_capital=current_capital,
@@ -6782,6 +6792,14 @@ def api_account_snapshot():
funding_capital, trading_capital = get_exchange_capitals(force=True)
funding_usdt = round(funding_capital, FUNDS_DECIMALS) if funding_capital is not None else None
current_capital = round(trading_capital, FUNDS_DECIMALS) if trading_capital is not None else round(local_current_capital, FUNDS_DECIMALS)
options_trading_usdc = None
if OKX_OPTIONS_ENABLED and exchange_options.apiKey:
try:
from lib.exchange.okx_options_lib import fetch_options_trading_usdc
options_trading_usdc = fetch_options_trading_usdc(exchange_options)
except Exception:
options_trading_usdc = None
recommended_capital = get_recommended_capital(current_capital)
from lib.strategy.strategy_trade_labels import count_position_limit_active_monitors
@@ -6824,7 +6842,8 @@ def api_account_snapshot():
return jsonify({
"funding_usdt": funding_usdt,
"current_capital": current_capital,
"total_funds": total_funds_usdt(funding_usdt, current_capital),
"options_trading_usdc": options_trading_usdc,
"total_funds": total_funds_usdt(funding_usdt, current_capital, options_trading_usdc),
"available_trading_usdt": round(available_trading_usdt, FUNDS_DECIMALS) if available_trading_usdt is not None else None,
"unrealized_pnl": unrealized_pnl,
"recommended_capital": recommended_capital,
@@ -8835,6 +8854,7 @@ _AI_REVIEW_RENDER_JS = os.path.join(_REPO_STATIC_DIR, "ai_review_render.js")
_FORM_SUBMIT_GUARD_JS = os.path.join(_REPO_STATIC_DIR, "form_submit_guard.js")
_MANUAL_ORDER_RR_PREVIEW_JS = os.path.join(_REPO_STATIC_DIR, "manual_order_rr_preview.js")
_OPTIONS_PANEL_JS = os.path.join(_REPO_STATIC_DIR, "options_panel.js")
_OPTIONS_SETTINGS_JS = os.path.join(_REPO_STATIC_DIR, "options_settings.js")
@app.route("/static/ai_review_render.js")
@@ -8865,6 +8885,13 @@ def static_options_panel_js():
return send_file(_OPTIONS_PANEL_JS, mimetype="application/javascript; charset=utf-8")
@app.route("/static/options_settings.js")
def static_options_settings_js():
if not os.path.isfile(_OPTIONS_SETTINGS_JS):
return Response("not found", status=404, mimetype="text/plain; charset=utf-8")
return send_file(_OPTIONS_SETTINGS_JS, mimetype="application/javascript; charset=utf-8")
@app.route("/export/review_md/<rid>")
@login_required
def export_review_md(rid):