fix: make full_margin env save/restart reliable (no empty numeric wipe).
EOF Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Vendored
+48
-1
@@ -103,6 +103,23 @@ SENSITIVE_EXACT = frozenset({
|
||||
SENSITIVE_SUBSTR = ("_SECRET", "_PASSPHRASE", "_API_KEY", "_PASSWORD")
|
||||
|
||||
|
||||
def normalize_position_sizing_mode(raw: str) -> str:
|
||||
"""把中文/别名规范成 risk | full_margin。"""
|
||||
s = (raw or "").strip().lower().replace("-", "_").replace(" ", "")
|
||||
if s in ("risk", "以损", "以损定仓", "riskpercent", "risk_percent"):
|
||||
return "risk"
|
||||
if s in (
|
||||
"full_margin",
|
||||
"fullmargin",
|
||||
"full",
|
||||
"全仓",
|
||||
"全仓杠杆",
|
||||
"margin",
|
||||
):
|
||||
return "full_margin"
|
||||
return (raw or "").strip()
|
||||
|
||||
|
||||
def _is_sensitive(key: str) -> bool:
|
||||
if key in SENSITIVE_EXACT:
|
||||
return True
|
||||
@@ -275,17 +292,47 @@ def validate_env_updates(groups: list[dict], updates: dict[str, str]) -> tuple[d
|
||||
val = str(value).strip()
|
||||
if allowed[key].get("sensitive") and (val == "" or (val.startswith("****") and len(val) <= 8)):
|
||||
continue
|
||||
# 数字项留空不覆盖已有 .env,避免 RISK_PERCENT= 导致重启崩掉
|
||||
ftype = allowed[key].get("type")
|
||||
if val == "" and ftype in ("float", "int"):
|
||||
continue
|
||||
if val == "" and key in (
|
||||
"POSITION_SIZING_MODE",
|
||||
"TRADE_DIRECTION",
|
||||
"RISK_PERCENT",
|
||||
"FULL_MARGIN_BUFFER_RATIO",
|
||||
"BTC_LEVERAGE",
|
||||
"ALT_LEVERAGE",
|
||||
"MAX_ACTIVE_POSITIONS",
|
||||
):
|
||||
continue
|
||||
# API Key 被密码管理器/自动填充成登录密码时通常很短;OKX Key 一般为 36 位
|
||||
if key.endswith("_API_KEY") and 0 < len(val) < 16:
|
||||
errors.append(f"{key} 长度异常,疑似自动填充;留空则不修改已有密钥")
|
||||
continue
|
||||
ftype = allowed[key].get("type")
|
||||
if key == "POSITION_SIZING_MODE":
|
||||
val = normalize_position_sizing_mode(val)
|
||||
if val not in ("risk", "full_margin"):
|
||||
errors.append("计仓模式须为 risk(以损定仓)或 full_margin(全仓杠杆)")
|
||||
continue
|
||||
if ftype == "bool":
|
||||
low = val.lower()
|
||||
if low not in ("true", "false", "1", "0", "yes", "no", "on", "off"):
|
||||
errors.append(f"{key} 须为 true/false")
|
||||
continue
|
||||
val = "true" if low in ("true", "1", "yes", "on") else "false"
|
||||
elif ftype == "float" and val != "":
|
||||
try:
|
||||
float(val)
|
||||
except ValueError:
|
||||
errors.append(f"{key} 须为数字")
|
||||
continue
|
||||
elif ftype == "int" and val != "":
|
||||
try:
|
||||
int(val)
|
||||
except ValueError:
|
||||
errors.append(f"{key} 须为整数")
|
||||
continue
|
||||
clean[key] = val
|
||||
return clean, errors
|
||||
|
||||
|
||||
Reference in New Issue
Block a user