env 配置去掉期权/对冲模式与对冲计划区块,仅保留单独期权。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Vendored
-5
@@ -170,7 +170,6 @@ SELECT_OPTIONS: dict[str, tuple[tuple[str, str], ...]] = {
|
|||||||
),
|
),
|
||||||
"OKX_TRADE_MODE": (
|
"OKX_TRADE_MODE": (
|
||||||
("options", "单独期权"),
|
("options", "单独期权"),
|
||||||
("options_options", "期期对冲"),
|
|
||||||
),
|
),
|
||||||
"OKX_OPTIONS_MARGIN_MODE": (
|
"OKX_OPTIONS_MARGIN_MODE": (
|
||||||
("coin", "币本位(USDT买币桥)"),
|
("coin", "币本位(USDT买币桥)"),
|
||||||
@@ -180,10 +179,6 @@ SELECT_OPTIONS: dict[str, tuple[tuple[str, str], ...]] = {
|
|||||||
("premium", "权利金倍数"),
|
("premium", "权利金倍数"),
|
||||||
("net_pnl", "净盈亏(USDT)"),
|
("net_pnl", "净盈亏(USDT)"),
|
||||||
),
|
),
|
||||||
"HEDGE_PLAN_OPTION_PRIMARY": (
|
|
||||||
("true", "以期权为主"),
|
|
||||||
("false", "保险模式"),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_SELECT_ALIASES: dict[str, dict[str, str]] = {
|
_SELECT_ALIASES: dict[str, dict[str, str]] = {
|
||||||
|
|||||||
Vendored
+15
-204
@@ -20,9 +20,9 @@ from lib.env.env_schema import (
|
|||||||
# 合约计仓/杠杆/自动单等已从 env UI 移除;永续划转等见系统设置开关(默认关)
|
# 合约计仓/杠杆/自动单等已从 env UI 移除;永续划转等见系统设置开关(默认关)
|
||||||
_EXCHANGE_LIVE_FIELDS: dict[str, list[tuple[str, str, str]]] = {
|
_EXCHANGE_LIVE_FIELDS: dict[str, list[tuple[str, str, str]]] = {
|
||||||
"okx": [
|
"okx": [
|
||||||
("LIVE_TRADING_ENABLED", "开启实盘下单", "关闭时仅走本地流程,不向交易所发单(期权/对冲共用)"),
|
("LIVE_TRADING_ENABLED", "开启实盘下单", "关闭时仅走本地流程,不向交易所发单(期权共用)"),
|
||||||
("OKX_API_KEY", "API Key", "账户 API(永续腿+期权共用)"),
|
("OKX_API_KEY", "API Key", "账户 API(期权共用)"),
|
||||||
("OKX_API_SECRET", "API Secret", "账户 API(永续腿+期权共用)"),
|
("OKX_API_SECRET", "API Secret", "账户 API(期权共用)"),
|
||||||
("OKX_API_PASSPHRASE", "API Passphrase", "OKX 必填"),
|
("OKX_API_PASSPHRASE", "API Passphrase", "OKX 必填"),
|
||||||
("OKX_ACCOUNT_LABEL", "账户备注", "企业微信推送中显示"),
|
("OKX_ACCOUNT_LABEL", "账户备注", "企业微信推送中显示"),
|
||||||
(
|
(
|
||||||
@@ -49,7 +49,7 @@ _EXCHANGE_LIVE_FIELDS: dict[str, list[tuple[str, str, str]]] = {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
# 仅保留与期权/对冲产品相关的共享区块(永续执行/风控/冷静期/划转/当日资金已从 UI 移除)
|
# 共享区块(企业微信等);对冲配置已从 UI 移除
|
||||||
_SHARED_SECTIONS: list[dict[str, Any]] = [
|
_SHARED_SECTIONS: list[dict[str, Any]] = [
|
||||||
{
|
{
|
||||||
"title": "企业微信",
|
"title": "企业微信",
|
||||||
@@ -60,18 +60,6 @@ _SHARED_SECTIONS: list[dict[str, Any]] = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
_MODE_SECTION: dict[str, Any] = {
|
|
||||||
"title": "期权/对冲模式",
|
|
||||||
"exchanges": frozenset({"okx"}),
|
|
||||||
"fields": [
|
|
||||||
(
|
|
||||||
"OKX_TRADE_MODE",
|
|
||||||
"交易模式",
|
|
||||||
"二选一:单独期权 / 期期对冲。选单独期权时隐藏对冲导航与对冲配置;选期期对冲时不可单独开期权。永期对冲(含合约腿)已从配置页移除",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
_OPTIONS_SECTION: dict[str, Any] = {
|
_OPTIONS_SECTION: dict[str, Any] = {
|
||||||
"title": "期权账户",
|
"title": "期权账户",
|
||||||
"exchanges": frozenset({"okx"}),
|
"exchanges": frozenset({"okx"}),
|
||||||
@@ -132,7 +120,7 @@ _OPTIONS_SECTION: dict[str, Any] = {
|
|||||||
(
|
(
|
||||||
"OKX_OPTIONS_MAX_ACTIVE_POSITIONS",
|
"OKX_OPTIONS_MAX_ACTIVE_POSITIONS",
|
||||||
"期权持仓上限(笔)",
|
"期权持仓上限(笔)",
|
||||||
"仅「单独期权」模式生效;默认 0=不限制;按交易所期权合约笔数计数,同合约加仓不占新笔数",
|
"默认 0=不限制;按交易所期权合约笔数计数,同合约加仓不占新笔数",
|
||||||
),
|
),
|
||||||
("OKX_OPTIONS_DEFAULT_UNDERLY", "默认标的", "如 ETH"),
|
("OKX_OPTIONS_DEFAULT_UNDERLY", "默认标的", "如 ETH"),
|
||||||
(
|
(
|
||||||
@@ -178,93 +166,6 @@ _OPTIONS_SECTION: dict[str, Any] = {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
# 对冲公共字段(不含已由 OKX_TRADE_MODE 取代的 ENABLED/SHOW/MUTUAL)
|
|
||||||
_HEDGE_COMMON_FIELDS: list[tuple[str, str, str]] = [
|
|
||||||
("HEDGE_PLAN_LIVE_ORDER", "允许对冲真实下单", "再与实盘 LIVE_TRADING_ENABLED 同开才可启动"),
|
|
||||||
(
|
|
||||||
"MAX_ACTIVE_HEDGE_PLANS",
|
|
||||||
"对冲组数上限",
|
|
||||||
"默认 1;同时进行中的对冲计划组数(opening/active/partial),可改",
|
|
||||||
),
|
|
||||||
("HEDGE_PLAN_MONITOR_POLL_SECONDS", "对冲监控轮询(秒)", "默认 15"),
|
|
||||||
(
|
|
||||||
"HEDGE_PLAN_BUDGET_BUFFER",
|
|
||||||
"对冲预算缓冲比例",
|
|
||||||
"默认 0.95;仅对冲计划;与期权页 OKX_OPTIONS_BUDGET_BUFFER 独立",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"HEDGE_PLAN_MANUAL_COMPLETE_ON_PARTIAL",
|
|
||||||
"半腿失败改手动补开",
|
|
||||||
"默认 true;开启时半腿失败不自动平,计划挂 partial,页面可补开;并强制关闭下方自动平",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"HEDGE_PLAN_PARTIAL_AUTO_CLOSE_OPTION",
|
|
||||||
"半腿失败时自动平期权",
|
|
||||||
"默认 true;若上方「半腿失败改手动补开」开启则本项强制无效",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
_HEDGE_PO_FIELDS: list[tuple[str, str, str]] = [
|
|
||||||
(
|
|
||||||
"HEDGE_PLAN_OPTION_PRIMARY",
|
|
||||||
"永期模式(以期权为主/保险)",
|
|
||||||
"默认 true=以期权为主;false=保险模式;页面标题前显示标识,不可在页内切换",
|
|
||||||
),
|
|
||||||
("HEDGE_PLAN_OPEN_ORDER", "永期开仓顺序", "options_first 或 perp_first"),
|
|
||||||
("HEDGE_PLAN_ON_PERP_SL_CLOSE_OPTIONS", "永期止损后强制平期权", "保护机制,建议保持 true"),
|
|
||||||
("HEDGE_PLAN_ON_PERP_TP_CLOSE_OPTIONS", "永期止盈后强制平期权", "默认 false,保险腿不平"),
|
|
||||||
(
|
|
||||||
"HEDGE_PLAN_ITM_MAX_DIST_USD",
|
|
||||||
"永期实值最大深度(U)",
|
|
||||||
"默认空=沿用 OKX_OPTIONS_ITM_MAX_DIST_USD(常 30);0=不限制",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"HEDGE_PLAN_MIN_OPTION_HOURS",
|
|
||||||
"对冲期权最低剩余小时",
|
|
||||||
"默认 8;测算/启动时若传 hours_to_expiry 则校验",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"HEDGE_PLAN_MIN_OPTION_LEVERAGE",
|
|
||||||
"对冲期权最低杠杆(S/ask)",
|
|
||||||
"默认 0=不启用;>0 时拒绝杠杆过低的保险腿",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
_HEDGE_OO_FIELDS: list[tuple[str, str, str]] = [
|
|
||||||
("HEDGE_PLAN_OO_CLOSE_WINNER_ONLY", "期期只平盈利腿", "达目标价只平盈利方"),
|
|
||||||
(
|
|
||||||
"HEDGE_PLAN_OO_CLOSE_MODE_ENABLED",
|
|
||||||
"期期平仓模式(方案C)",
|
|
||||||
"默认 true;开启后页面可选「到期平/全平」;关闭则固定到期平",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"HEDGE_PLAN_OO_BIAS_SPLIT_BY",
|
|
||||||
"期期做多做空拆分口径",
|
|
||||||
"默认预算金额;budget=按权利金预算分两腿;sheets=先算同张数再按比例拆",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"HEDGE_PLAN_OO_BIAS_RATIO",
|
|
||||||
"期期做多做空主腿占比",
|
|
||||||
"默认 0.7(即 7:3);做多主腿=Call,做空主腿=Put;须在 0~1 之间",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
# 兼容旧测试/全量字段列表(写 env 时仍允许这些键,但 UI 按模式过滤)
|
|
||||||
_HEDGE_PLAN_SECTION: dict[str, Any] = {
|
|
||||||
"title": "对冲计划",
|
|
||||||
"exchanges": frozenset({"okx"}),
|
|
||||||
"fields": [
|
|
||||||
("HEDGE_PLAN_ENABLED", "启用对冲计划", "已由「交易模式」取代,一般无需再改"),
|
|
||||||
("HEDGE_PLAN_SHOW_PERP_OPTIONS", "显示永期对冲", "已由「交易模式」取代"),
|
|
||||||
("HEDGE_PLAN_SHOW_OPTIONS_OPTIONS", "显示期期对冲", "已由「交易模式」取代"),
|
|
||||||
("HEDGE_PLAN_OPTIONS_MUTUAL_EXCLUSIVE", "对冲与期权互斥门控", "已由「交易模式」三选一取代"),
|
|
||||||
*_HEDGE_COMMON_FIELDS,
|
|
||||||
*_HEDGE_PO_FIELDS,
|
|
||||||
*_HEDGE_OO_FIELDS,
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# 与运行时 os.getenv 默认一致;.env 未写明时展示实际生效值(同风控说明页)
|
# 与运行时 os.getenv 默认一致;.env 未写明时展示实际生效值(同风控说明页)
|
||||||
_RUNTIME_ENV_DEFAULTS: dict[str, str] = {
|
_RUNTIME_ENV_DEFAULTS: dict[str, str] = {
|
||||||
"RISK_CONTROL_ENABLED": "true",
|
"RISK_CONTROL_ENABLED": "true",
|
||||||
@@ -276,8 +177,6 @@ _RUNTIME_ENV_DEFAULTS: dict[str, str] = {
|
|||||||
"AUTO_TRANSFER_FROM": "funding",
|
"AUTO_TRANSFER_FROM": "funding",
|
||||||
"AUTO_TRANSFER_TO": "swap",
|
"AUTO_TRANSFER_TO": "swap",
|
||||||
"TRANSFER_CCY": "USDT",
|
"TRANSFER_CCY": "USDT",
|
||||||
"HEDGE_PLAN_SHOW_PERP_OPTIONS": "false",
|
|
||||||
"HEDGE_PLAN_SHOW_OPTIONS_OPTIONS": "false",
|
|
||||||
"OKX_SHOW_PERP_FUNDS": "false",
|
"OKX_SHOW_PERP_FUNDS": "false",
|
||||||
"OKX_OPTIONS_CHAIN_ASK_LIQ_FILTER_ENABLED": "true",
|
"OKX_OPTIONS_CHAIN_ASK_LIQ_FILTER_ENABLED": "true",
|
||||||
"OKX_OPTIONS_CHAIN_MAX_DTE_DAYS": "14",
|
"OKX_OPTIONS_CHAIN_MAX_DTE_DAYS": "14",
|
||||||
@@ -290,32 +189,18 @@ _RUNTIME_ENV_DEFAULTS: dict[str, str] = {
|
|||||||
"OKX_OPTIONS_CLOSE_NET_PNL_MIN_USDT": "0",
|
"OKX_OPTIONS_CLOSE_NET_PNL_MIN_USDT": "0",
|
||||||
"OKX_OPTIONS_CLOSE_HOLD_SECONDS": "120",
|
"OKX_OPTIONS_CLOSE_HOLD_SECONDS": "120",
|
||||||
"OKX_TRADE_MODE": "options",
|
"OKX_TRADE_MODE": "options",
|
||||||
"HEDGE_PLAN_ENABLED": "false",
|
|
||||||
"MAX_ACTIVE_HEDGE_PLANS": "1",
|
|
||||||
"HEDGE_PLAN_OO_CLOSE_MODE_ENABLED": "true",
|
|
||||||
"HEDGE_PLAN_OO_BIAS_SPLIT_BY": "budget",
|
|
||||||
"HEDGE_PLAN_OO_BIAS_RATIO": "0.7",
|
|
||||||
"HEDGE_PLAN_BUDGET_BUFFER": "0.95",
|
|
||||||
"HEDGE_PLAN_OPTION_PRIMARY": "true",
|
|
||||||
"HEDGE_PLAN_OPTIONS_MUTUAL_EXCLUSIVE": "true",
|
|
||||||
"HEDGE_PLAN_MANUAL_COMPLETE_ON_PARTIAL": "true",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _effective_env_value(key: str, file_values: dict[str, str], schema_default: str = "") -> str:
|
def _effective_env_value(key: str, file_values: dict[str, str], schema_default: str = "") -> str:
|
||||||
if key == "OKX_TRADE_MODE":
|
if key == "OKX_TRADE_MODE":
|
||||||
# 展示值必须与运行时 get_okx_trade_mode() 一致,避免未写入时默认 options 静默改模式
|
# 展示值必须与运行时 get_okx_trade_mode() 一致(始终单独期权)
|
||||||
file_val = str(file_values.get(key) or "").strip() if key in file_values else ""
|
|
||||||
if file_val:
|
|
||||||
from lib.options.okx_trade_mode_lib import normalize_okx_trade_mode
|
|
||||||
|
|
||||||
return normalize_okx_trade_mode(file_val) or file_val
|
|
||||||
try:
|
try:
|
||||||
from lib.options.okx_trade_mode_lib import get_okx_trade_mode
|
from lib.options.okx_trade_mode_lib import get_okx_trade_mode
|
||||||
|
|
||||||
return get_okx_trade_mode()
|
return get_okx_trade_mode()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
return "options"
|
||||||
if key in file_values:
|
if key in file_values:
|
||||||
file_val = str(file_values.get(key) or "").strip()
|
file_val = str(file_values.get(key) or "").strip()
|
||||||
if file_val:
|
if file_val:
|
||||||
@@ -350,13 +235,6 @@ def _build_field(
|
|||||||
meta = schema.get(key) or {}
|
meta = schema.get(key) or {}
|
||||||
schema_default = meta.get("default") or ""
|
schema_default = meta.get("default") or ""
|
||||||
val = _effective_env_value(key, values, schema_default)
|
val = _effective_env_value(key, values, schema_default)
|
||||||
# 与运行时一致:手动补开开启时,「自动平期权」展示为关闭(实际也不会执行)
|
|
||||||
if key == "HEDGE_PLAN_PARTIAL_AUTO_CLOSE_OPTION":
|
|
||||||
manual = _effective_env_value(
|
|
||||||
"HEDGE_PLAN_MANUAL_COMPLETE_ON_PARTIAL", values, "true"
|
|
||||||
)
|
|
||||||
if _env_truthy(manual):
|
|
||||||
val = "false"
|
|
||||||
masked = _mask_value(key, val)
|
masked = _mask_value(key, val)
|
||||||
ftype = meta.get("type") or _field_type(key, val or schema_default)
|
ftype = meta.get("type") or _field_type(key, val or schema_default)
|
||||||
options = select_options_for(key)
|
options = select_options_for(key)
|
||||||
@@ -381,86 +259,34 @@ def _build_field(
|
|||||||
if options:
|
if options:
|
||||||
cur = (out["current"] or out["default"] or "").strip()
|
cur = (out["current"] or out["default"] or "").strip()
|
||||||
opt_vals = {o["value"] for o in options}
|
opt_vals = {o["value"] for o in options}
|
||||||
# 永期对冲不再作为可选模式;已选历史值也不塞回下拉,避免继续强化合约 UI
|
|
||||||
if key == "OKX_TRADE_MODE" and cur == "perp_options":
|
|
||||||
cur = ""
|
|
||||||
out["current"] = "options"
|
|
||||||
out["default"] = "options"
|
|
||||||
out["note"] = (
|
|
||||||
(out.get("note") or "")
|
|
||||||
+ "(当前 .env 仍为永期对冲:请改选「单独期权」或「期期对冲」后保存并重启)"
|
|
||||||
).strip()
|
|
||||||
if cur and cur not in opt_vals:
|
if cur and cur not in opt_vals:
|
||||||
options = [{"value": cur, "label": cur}] + options
|
options = [{"value": cur, "label": cur}] + options
|
||||||
out["options"] = options
|
out["options"] = options
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def _okx_mode_for_env_ui() -> str:
|
|
||||||
try:
|
|
||||||
from lib.options.okx_trade_mode_lib import get_okx_trade_mode
|
|
||||||
|
|
||||||
return get_okx_trade_mode()
|
|
||||||
except Exception:
|
|
||||||
return "options"
|
|
||||||
|
|
||||||
|
|
||||||
def _options_fields_for_mode(mode: str) -> list[tuple[str, str, str]]:
|
|
||||||
fields = list(_OPTIONS_SECTION["fields"])
|
|
||||||
if mode != "options":
|
|
||||||
fields = [f for f in fields if f[0] != "OKX_OPTIONS_MAX_ACTIVE_POSITIONS"]
|
|
||||||
return fields
|
|
||||||
|
|
||||||
|
|
||||||
def _hedge_fields_for_mode(mode: str) -> list[tuple[str, str, str]]:
|
|
||||||
if mode == "perp_options":
|
|
||||||
return [*_HEDGE_COMMON_FIELDS, *_HEDGE_PO_FIELDS]
|
|
||||||
if mode == "options_options":
|
|
||||||
return [*_HEDGE_COMMON_FIELDS, *_HEDGE_OO_FIELDS]
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
def ui_sections_for_exchange(
|
def ui_sections_for_exchange(
|
||||||
exchange_key: str,
|
exchange_key: str,
|
||||||
*,
|
*,
|
||||||
mode: str | None = None,
|
mode: str | None = None,
|
||||||
) -> list[dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
|
del mode # 对冲模式已移除;保留参数兼容旧调用
|
||||||
ex = (exchange_key or "").strip().lower()
|
ex = (exchange_key or "").strip().lower()
|
||||||
sections: list[dict[str, Any]] = []
|
sections: list[dict[str, Any]] = []
|
||||||
live_fields = _EXCHANGE_LIVE_FIELDS.get(ex, _EXCHANGE_LIVE_FIELDS["okx"])
|
live_fields = _EXCHANGE_LIVE_FIELDS.get(ex, _EXCHANGE_LIVE_FIELDS["okx"])
|
||||||
sections.append({"title": "交易所与实盘", "fields": live_fields})
|
sections.append({"title": "交易所与实盘", "fields": live_fields})
|
||||||
sections.extend(_SHARED_SECTIONS)
|
sections.extend(_SHARED_SECTIONS)
|
||||||
if ex in _MODE_SECTION.get("exchanges", frozenset()):
|
if ex == "okx":
|
||||||
from lib.options.okx_trade_mode_lib import normalize_okx_trade_mode
|
sections.append({"title": "期权账户", "fields": list(_OPTIONS_SECTION["fields"])})
|
||||||
|
|
||||||
m = normalize_okx_trade_mode(mode) if mode else ""
|
|
||||||
if not m:
|
|
||||||
m = _okx_mode_for_env_ui()
|
|
||||||
sections.append(_MODE_SECTION)
|
|
||||||
sections.append({"title": "期权账户", "fields": _options_fields_for_mode(m)})
|
|
||||||
# 永期对冲配置块不再展示(含合约腿);期期仍展示
|
|
||||||
if m != "perp_options":
|
|
||||||
hedge_fields = _hedge_fields_for_mode(m)
|
|
||||||
if hedge_fields:
|
|
||||||
title = "对冲计划·期期"
|
|
||||||
sections.append({"title": title, "fields": hedge_fields})
|
|
||||||
return sections
|
return sections
|
||||||
|
|
||||||
|
|
||||||
def ui_allowed_keys(exchange_key: str) -> frozenset[str]:
|
def ui_allowed_keys(exchange_key: str) -> frozenset[str]:
|
||||||
"""可写键=当前模式可见字段 + 模式切换键 + 遗留对冲开关(兼容旧脚本写入)."""
|
"""可写键=当前可见字段。.env 里遗留对冲键仍保留在文件中,但 UI 不可再写入."""
|
||||||
keys: set[str] = set()
|
keys: set[str] = set()
|
||||||
for sec in ui_sections_for_exchange(exchange_key):
|
for sec in ui_sections_for_exchange(exchange_key):
|
||||||
for item in sec["fields"]:
|
for item in sec["fields"]:
|
||||||
keys.add(item[0])
|
keys.add(item[0])
|
||||||
ex = (exchange_key or "").strip().lower()
|
|
||||||
if ex == "okx":
|
|
||||||
keys.add("OKX_TRADE_MODE")
|
|
||||||
# 允许写入遗留键,避免旧自动化/手改失败;页面不再展示
|
|
||||||
for item in _HEDGE_PLAN_SECTION["fields"]:
|
|
||||||
keys.add(item[0])
|
|
||||||
for item in _OPTIONS_SECTION["fields"]:
|
|
||||||
keys.add(item[0])
|
|
||||||
return frozenset(keys)
|
return frozenset(keys)
|
||||||
|
|
||||||
|
|
||||||
@@ -473,9 +299,7 @@ def build_env_ui_payload(
|
|||||||
env_lines = read_env_lines(env_path)
|
env_lines = read_env_lines(env_path)
|
||||||
values = env_get_all(env_lines)
|
values = env_get_all(env_lines)
|
||||||
groups: list[dict[str, Any]] = []
|
groups: list[dict[str, Any]] = []
|
||||||
for sec in ui_sections_for_exchange(
|
for sec in ui_sections_for_exchange(exchange_key):
|
||||||
exchange_key, mode=values.get("OKX_TRADE_MODE") or ""
|
|
||||||
):
|
|
||||||
fields = [
|
fields = [
|
||||||
_build_field(key, label, note, schema, values)
|
_build_field(key, label, note, schema, values)
|
||||||
for key, label, note in sec["fields"]
|
for key, label, note in sec["fields"]
|
||||||
@@ -609,19 +433,6 @@ def coerce_hedge_partial_close_with_manual(
|
|||||||
*,
|
*,
|
||||||
env_path: str = "",
|
env_path: str = "",
|
||||||
) -> dict[str, str]:
|
) -> dict[str, str]:
|
||||||
"""手动补开为开启时,强制把自动平写成 false(与运行时一致)."""
|
"""兼容旧调用名;对冲已移除,原样返回."""
|
||||||
out = dict(clean or {})
|
del env_path
|
||||||
manual = out.get("HEDGE_PLAN_MANUAL_COMPLETE_ON_PARTIAL")
|
return dict(clean or {})
|
||||||
if manual is None and env_path:
|
|
||||||
try:
|
|
||||||
from lib.env.env_file_lib import env_get_all, read_env_lines
|
|
||||||
|
|
||||||
file_vals = env_get_all(read_env_lines(env_path))
|
|
||||||
manual = _effective_env_value(
|
|
||||||
"HEDGE_PLAN_MANUAL_COMPLETE_ON_PARTIAL", file_vals, "true"
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
manual = "true"
|
|
||||||
if _env_truthy(str(manual or "")):
|
|
||||||
out["HEDGE_PLAN_PARTIAL_AUTO_CLOSE_OPTION"] = "false"
|
|
||||||
return out
|
|
||||||
|
|||||||
@@ -16,11 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if env_config_groups %}
|
{% if env_config_groups %}
|
||||||
{% set ns = namespace(mode_idx=0) %}
|
<div class="env-config-body card" data-env-ssr="1" id="env-config-body">
|
||||||
{% for group in env_config_groups %}
|
|
||||||
{% if '期权/对冲模式' in (group.title or '') %}{% set ns.mode_idx = loop.index0 %}{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
<div class="env-config-body card" data-env-ssr="1" id="env-config-body" data-env-mode-section-idx="{{ ns.mode_idx }}">
|
|
||||||
{% for group in env_config_groups %}
|
{% for group in env_config_groups %}
|
||||||
<input type="radio" name="env-section" id="env-sec-{{ loop.index0 }}" class="env-tab-radio"{% if loop.first %} checked{% endif %}>
|
<input type="radio" name="env-section" id="env-sec-{{ loop.index0 }}" class="env-tab-radio"{% if loop.first %} checked{% endif %}>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -67,6 +67,21 @@ class RemoveHedgeSmokeTests(unittest.TestCase):
|
|||||||
self.assertNotIn("hedge_target_map", src)
|
self.assertNotIn("hedge_target_map", src)
|
||||||
self.assertNotIn("hedge_plan_target", src)
|
self.assertNotIn("hedge_plan_target", src)
|
||||||
|
|
||||||
|
def test_env_ui_no_hedge_mode_section(self):
|
||||||
|
from lib.env.env_ui_manifest import ui_sections_for_exchange
|
||||||
|
from lib.env.env_schema import select_options_for
|
||||||
|
|
||||||
|
titles = [s["title"] for s in ui_sections_for_exchange("okx")]
|
||||||
|
self.assertNotIn("期权/对冲模式", titles)
|
||||||
|
self.assertTrue(any("对冲" not in t for t in titles))
|
||||||
|
for t in titles:
|
||||||
|
self.assertNotIn("对冲", t)
|
||||||
|
labels = [f[1] for s in ui_sections_for_exchange("okx") for f in s["fields"]]
|
||||||
|
for lab in labels:
|
||||||
|
self.assertNotIn("对冲", lab)
|
||||||
|
mode_opts = [o["value"] for o in select_options_for("OKX_TRADE_MODE")]
|
||||||
|
self.assertEqual(mode_opts, ["options"])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user