Turn position/margin/sizing/direction env fields into dropdown selects.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-17 19:41:47 +08:00
parent 53e55aa4b4
commit aabbbef0a9
5 changed files with 150 additions and 10 deletions
+30 -10
View File
@@ -11,7 +11,9 @@ from lib.env.env_schema import (
_is_sensitive,
_mask_value,
_restart_required,
normalize_select_value,
parse_env_example_schema,
select_options_for,
)
# 各所「交易所与实盘」字段(顺序即页面顺序)
@@ -21,8 +23,8 @@ _EXCHANGE_LIVE_FIELDS: dict[str, list[tuple[str, str, str]]] = {
("OKX_API_KEY", "API Key", "永续子账户"),
("OKX_API_SECRET", "API Secret", "永续子账户"),
("OKX_API_PASSPHRASE", "API Passphrase", "OKX 必填"),
("OKX_TD_MODE", "保证金模式", "cross=全仓,isolated=逐仓"),
("OKX_POS_MODE", "持仓模式", "hedge=双向,net=单向净持仓"),
("OKX_TD_MODE", "保证金模式", ""),
("OKX_POS_MODE", "持仓模式", ""),
("OKX_POSITION_INST_TYPE", "仓位查询类型", "如 SWAP"),
("OKX_ACCOUNT_LABEL", "账户备注", "企业微信推送中显示"),
],
@@ -30,16 +32,16 @@ _EXCHANGE_LIVE_FIELDS: dict[str, list[tuple[str, str, str]]] = {
("LIVE_TRADING_ENABLED", "开启实盘下单", "关闭时仅走本地流程,不向交易所发单"),
("BINANCE_API_KEY", "API Key", "永续子账户"),
("BINANCE_API_SECRET", "API Secret", "永续子账户"),
("BINANCE_MARGIN_MODE", "保证金模式", "cross=全仓,isolated=逐仓"),
("BINANCE_POSITION_MODE", "持仓模式", "hedge=双向,one_way=单向"),
("BINANCE_MARGIN_MODE", "保证金模式", ""),
("BINANCE_POSITION_MODE", "持仓模式", ""),
("BINANCE_ACCOUNT_LABEL", "账户备注", "企业微信推送中显示"),
],
"gate": [
("LIVE_TRADING_ENABLED", "开启实盘下单", "关闭时仅走本地流程,不向交易所发单"),
("GATE_API_KEY", "API Key", "永续子账户"),
("GATE_API_SECRET", "API Secret", "永续子账户"),
("GATE_TD_MODE", "保证金模式", "cross=全仓,isolated=逐仓"),
("GATE_POS_MODE", "持仓模式", "hedge=双向,single=单向"),
("GATE_TD_MODE", "保证金模式", ""),
("GATE_POS_MODE", "持仓模式", ""),
("GATE_ACCOUNT_LABEL", "账户备注", "企业微信推送中显示"),
],
}
@@ -55,13 +57,13 @@ _SHARED_SECTIONS: list[dict[str, Any]] = [
{
"title": "交易执行",
"fields": [
("POSITION_SIZING_MODE", "计仓模式", "risk=以损定仓,full_margin=全仓杠杆"),
("POSITION_SIZING_MODE", "计仓模式", "切换须无仓后重启"),
("RISK_PERCENT", "以损定仓风险%", "单笔风险占资金比例"),
("FULL_MARGIN_BUFFER_RATIO", "全仓资金缓冲比例", "如 0.98"),
("BTC_LEVERAGE", "BTC 默认杠杆", ""),
("ALT_LEVERAGE", "山寨默认杠杆", ""),
("TRADE_DIRECTION_RESTRICT_ENABLED", "方向限制开关", ""),
("TRADE_DIRECTION", "允许方向", "long_only / short_only / both"),
("TRADE_DIRECTION", "允许方向", "需同时开启「方向限制开关」才生效"),
("TRADE_SYMBOL_RESTRICT_ENABLED", "币种白名单开关", ""),
("TRADE_SYMBOL_WHITELIST", "白名单币种", "逗号分隔,如 BTC,ETH"),
("TRADING_DAY_RESET_HOUR", "交易日切点(北京时间)", "整点,默认 8"),
@@ -183,7 +185,12 @@ def _build_field(
val = _effective_env_value(key, values, schema_default)
masked = _mask_value(key, val)
ftype = meta.get("type") or _field_type(key, val or schema_default)
return {
options = select_options_for(key)
if options:
ftype = "select"
val = normalize_select_value(key, val) or val
masked = _mask_value(key, val)
out: dict[str, Any] = {
"key": key,
"label": label,
"note": note or meta.get("note") or "",
@@ -197,6 +204,13 @@ def _build_field(
"tail": masked.get("tail") or "",
"has_value": masked["has_value"],
}
if options:
cur = (out["current"] or out["default"] or "").strip()
opt_vals = {o["value"] for o in options}
if cur and cur not in opt_vals:
options = [{"value": cur, "label": cur}] + options
out["options"] = options
return out
def ui_sections_for_exchange(exchange_key: str) -> list[dict[str, Any]]:
@@ -260,7 +274,12 @@ def validate_env_ui_updates(
fields: list[dict[str, Any]] = []
for key, _label, _note in sec["fields"]:
if key in schema:
fields.append(schema[key])
field = dict(schema[key])
opts = select_options_for(key)
if opts:
field["type"] = "select"
field["options"] = opts
fields.append(field)
else:
default = ""
fields.append(
@@ -270,6 +289,7 @@ def validate_env_ui_updates(
"sensitive": _is_sensitive(key),
"restart_required": _restart_required(key),
"hot_reload": _hot_reload(key),
"options": select_options_for(key),
}
)
groups.append({"title": sec["title"], "fields": fields})