env 锁定币本位并清掉对冲/USDC 配置项。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-09-30 23:42:10 +08:00
parent 2352a5fbdf
commit 6f9e6e2a32
6 changed files with 47 additions and 195 deletions
+19 -85
View File
@@ -27,8 +27,8 @@ _EXCHANGE_LIVE_FIELDS: dict[str, list[tuple[str, str, str]]] = {
("OKX_ACCOUNT_LABEL", "账户备注", "企业微信推送中显示"),
(
"OKX_SHOW_PERP_FUNDS",
"显示永续资金",
"默认关闭;开启后顶栏显示 USDT 资金/交易账户。币本位期权仍会显示交易账户以便买币",
"显示USDT资金/交易账户",
"默认关闭;开启后顶栏显示 USDT 资金与交易账户。币本位期权买币仍会显示交易账户可用额",
),
],
"binance": [
@@ -64,59 +64,34 @@ _OPTIONS_SECTION: dict[str, Any] = {
"title": "期权账户",
"exchanges": frozenset({"okx"}),
"fields": [
("OKX_OPTIONS_ENABLED", "启用期权模块", "与永续共用上方 OKX_API_*;不再单独配置期权密钥"),
("OKX_OPTIONS_ENABLED", "启用期权模块", "与上方 OKX_API_* 同源;不再单独配置期权密钥"),
("OKX_OPTIONS_ACCOUNT_LABEL", "期权账户备注", ""),
(
"OKX_OPTIONS_MARGIN_MODE",
"单笔期权本位",
"usdc=USDⓈ权利金;coin=币本位+USDT买币桥(默认)。有持仓/半成品桥时勿切换;改后需重启",
),
(
"OKX_OPTIONS_TRADE_BUDGET_USDC",
"单笔预算(USDC)",
"仅 USDC 模式且全仓复利关闭时显示/生效;用于「按可用余额打满」及张数/币数上限",
),
("OKX_OPTIONS_BUDGET_BUFFER", "预算缓冲比例", "如 0.95;USDC 打满/全仓复利与币本位复利共用"),
("OKX_OPTIONS_BUDGET_BUFFER", "预算缓冲比例", "如 0.95;币本位复利/固定预算共用"),
(
"OKX_OPTIONS_COIN_COMPOUND",
"币本位按交易户USDT复利",
"按交易户USDT复利",
"默认 true;预算=交易账户USDT×缓冲;关闭则用下方固定 USDT 预算×缓冲",
),
(
"OKX_OPTIONS_COIN_BUDGET_USDT",
"币本位固定预算(USDT)",
"仅币本位且复利关闭时生效",
"固定预算(USDT)",
"仅复利关闭时生效",
),
(
"OKX_OPTIONS_COIN_MAX_USDT_ENABLED",
"币本位单笔上限开关",
"单笔上限开关",
"默认 false=靠人工转走控规模;true 时预算不超过下方 N U",
),
(
"OKX_OPTIONS_COIN_MAX_USDT",
"币本位单笔上限(USDT)",
"单笔上限(USDT)",
"仅上限开关开启时生效",
),
(
"OKX_OPTIONS_COIN_SPOT_BUY_BUFFER",
"币本位现货买入缓冲",
"现货买入缓冲",
"相对权利金倍数,默认 1.10(=多买10%);也可写 0.10 表示+10%。按最大可开张数×卖一权利金×本缓冲买币,不全额兑换",
),
(
"OKX_OPTIONS_COMPOUND_FULL_ENABLED",
"全仓复利开关",
"默认 true;仅 USDC 模式。开启时隐藏单笔预算且不可用打满预算,下单以全仓复利为主;关闭则恢复单笔预算并隐藏全仓复利",
),
(
"OKX_OPTIONS_COMPOUND_FULL_CAP_ENABLED",
"全仓复利上限开关",
"仅全仓复利开启时有意义;默认 false=不设上限用期权户全部可用;true 时按下方上限封顶",
),
(
"OKX_OPTIONS_COMPOUND_FULL_CAP_USDC",
"全仓复利上限(USDC)",
"仅「全仓复利」且「上限开关」都开启时生效;例如 300",
),
(
"OKX_OPTIONS_MAX_ACTIVE_POSITIONS",
"期权持仓上限(笔)",
@@ -131,7 +106,7 @@ _OPTIONS_SECTION: dict[str, Any] = {
(
"OKX_OPTIONS_MAX_DTE_DAYS",
"开仓最大剩余天数",
"默认 2;单独开期权时拒绝更远到期(与链展示天数独立)",
"默认 2;开仓时拒绝更远到期(与链展示天数独立)",
),
(
"OKX_OPTIONS_CHAIN_ASK_LIQ_FILTER_ENABLED",
@@ -141,17 +116,12 @@ _OPTIONS_SECTION: dict[str, Any] = {
(
"OKX_OPTIONS_CLOSE_GATE_MODE",
"目标平仓门控模式",
"premium=可回收≥权利金×倍数(币本位默认×1.05);net_pnl=净盈亏折USDT≥阈值",
),
(
"OKX_OPTIONS_CLOSE_RECYCLE_MULT",
"门控权利金倍数(USDC)",
"仅 premium 模式;USDC 权利金仓默认 2",
"premium=可回收≥权利金×倍数(默认×1.05);net_pnl=净盈亏折USDT≥阈值",
),
(
"OKX_OPTIONS_CLOSE_RECYCLE_MULT_COIN",
"门控权利金倍数(币本位)",
"仅 premium 模式;ETH/BTC 权利金仓默认 1.05",
"门控权利金倍数",
"仅 premium 模式;默认 1.05",
),
(
"OKX_OPTIONS_CLOSE_NET_PNL_MIN_USDT",
@@ -182,9 +152,7 @@ _RUNTIME_ENV_DEFAULTS: dict[str, str] = {
"OKX_OPTIONS_CHAIN_MAX_DTE_DAYS": "14",
"OKX_OPTIONS_MAX_DTE_DAYS": "2",
"OKX_OPTIONS_MAX_ACTIVE_POSITIONS": "0",
"OKX_OPTIONS_MARGIN_MODE": "coin",
"OKX_OPTIONS_CLOSE_GATE_MODE": "premium",
"OKX_OPTIONS_CLOSE_RECYCLE_MULT": "2",
"OKX_OPTIONS_CLOSE_RECYCLE_MULT_COIN": "1.05",
"OKX_OPTIONS_CLOSE_NET_PNL_MIN_USDT": "0",
"OKX_OPTIONS_CLOSE_HOLD_SECONDS": "120",
@@ -194,13 +162,14 @@ _RUNTIME_ENV_DEFAULTS: dict[str, str] = {
def _effective_env_value(key: str, file_values: dict[str, str], schema_default: str = "") -> str:
if key == "OKX_TRADE_MODE":
# 展示值必须与运行时 get_okx_trade_mode() 一致(始终单独期权)
try:
from lib.options.okx_trade_mode_lib import get_okx_trade_mode
return get_okx_trade_mode()
except Exception:
return "options"
if key == "OKX_OPTIONS_MARGIN_MODE":
return "coin"
if key in file_values:
file_val = str(file_values.get(key) or "").strip()
if file_val:
@@ -313,24 +282,7 @@ def build_env_ui_payload(
return groups
# 币本位专属 / USDC 专属(配置页互斥隐藏)
_COIN_ONLY_ENV_KEYS = frozenset({
"OKX_OPTIONS_COIN_COMPOUND",
"OKX_OPTIONS_COIN_BUDGET_USDT",
"OKX_OPTIONS_COIN_MAX_USDT_ENABLED",
"OKX_OPTIONS_COIN_MAX_USDT",
"OKX_OPTIONS_COIN_SPOT_BUY_BUFFER",
"OKX_OPTIONS_CLOSE_RECYCLE_MULT_COIN",
})
_USDC_ONLY_ENV_KEYS = frozenset({
"OKX_OPTIONS_TRADE_BUDGET_USDC",
"OKX_OPTIONS_COMPOUND_FULL_ENABLED",
"OKX_OPTIONS_COMPOUND_FULL_CAP_ENABLED",
"OKX_OPTIONS_COMPOUND_FULL_CAP_USDC",
"OKX_OPTIONS_CLOSE_RECYCLE_MULT",
})
# 币本位专用:按复利/上限/门控模式标记 hidden
def _field_current(fields: list[dict[str, Any]], key: str, default: str = "") -> str:
for f in fields:
if f.get("key") == key:
@@ -339,37 +291,19 @@ def _field_current(fields: list[dict[str, Any]], key: str, default: str = "") ->
def _mark_options_section_hidden(fields: list[dict[str, Any]]) -> list[dict[str, Any]]:
"""按本位/门控模式/全仓复利标记 hidden(供 SSR/前端;切换开关仍可再显示)."""
margin = (_field_current(fields, "OKX_OPTIONS_MARGIN_MODE", "coin") or "coin").lower()
is_coin = margin != "usdc"
"""按门控模式/复利/单笔上限标记 hidden."""
gate_mode = (_field_current(fields, "OKX_OPTIONS_CLOSE_GATE_MODE", "premium") or "premium").lower()
compound_on = _env_truthy(_field_current(fields, "OKX_OPTIONS_COMPOUND_FULL_ENABLED", "true"))
coin_compound_on = _env_truthy(_field_current(fields, "OKX_OPTIONS_COIN_COMPOUND", "true"))
coin_max_on = _env_truthy(_field_current(fields, "OKX_OPTIONS_COIN_MAX_USDT_ENABLED", "false"))
compound_cap_on = _env_truthy(
_field_current(fields, "OKX_OPTIONS_COMPOUND_FULL_CAP_ENABLED", "false")
)
out: list[dict[str, Any]] = []
for f in fields:
key = str(f.get("key") or "")
hide = False
if is_coin and key in _USDC_ONLY_ENV_KEYS:
hide = True
elif (not is_coin) and key in _COIN_ONLY_ENV_KEYS:
hide = True
elif key == "OKX_OPTIONS_CLOSE_RECYCLE_MULT" and gate_mode != "premium":
hide = True
elif key == "OKX_OPTIONS_CLOSE_RECYCLE_MULT_COIN" and gate_mode != "premium":
if key == "OKX_OPTIONS_CLOSE_RECYCLE_MULT_COIN" and gate_mode != "premium":
hide = True
elif key == "OKX_OPTIONS_CLOSE_NET_PNL_MIN_USDT" and gate_mode != "net_pnl":
hide = True
elif key == "OKX_OPTIONS_TRADE_BUDGET_USDC" and compound_on:
hide = True
elif key == "OKX_OPTIONS_COMPOUND_FULL_CAP_ENABLED" and not compound_on:
hide = True
elif key == "OKX_OPTIONS_COMPOUND_FULL_CAP_USDC" and not (compound_on and compound_cap_on):
hide = True
elif key == "OKX_OPTIONS_COIN_BUDGET_USDT" and coin_compound_on:
hide = True
elif key == "OKX_OPTIONS_COIN_MAX_USDT" and not coin_max_on: