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
+26
-3
@@ -11,6 +11,7 @@ from lib.env.env_schema import (
|
||||
_is_sensitive,
|
||||
_mask_value,
|
||||
_restart_required,
|
||||
normalize_position_sizing_mode,
|
||||
parse_env_example_schema,
|
||||
)
|
||||
|
||||
@@ -55,7 +56,7 @@ _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 默认杠杆", ""),
|
||||
@@ -149,12 +150,25 @@ _RUNTIME_ENV_DEFAULTS: dict[str, str] = {
|
||||
"RISK_COOLING_HOURS_MANUAL_JOURNAL": "1",
|
||||
"RISK_MANUAL_CLOSE_DAILY_LIMIT": "2",
|
||||
"RISK_MOOD_ISSUES_DAILY_FREEZE": "true",
|
||||
"RISK_PERCENT": "2",
|
||||
"FULL_MARGIN_BUFFER_RATIO": "0.98",
|
||||
"POSITION_SIZING_MODE": "risk",
|
||||
"BTC_LEVERAGE": "10",
|
||||
"ALT_LEVERAGE": "5",
|
||||
"MAX_ACTIVE_POSITIONS": "1",
|
||||
}
|
||||
|
||||
_POSITION_SIZING_OPTIONS: list[dict[str, str]] = [
|
||||
{"value": "risk", "label": "以损定仓 (risk)"},
|
||||
{"value": "full_margin", "label": "全仓杠杆 (full_margin)"},
|
||||
]
|
||||
|
||||
|
||||
def _effective_env_value(key: str, file_values: dict[str, str], schema_default: str = "") -> str:
|
||||
if key in file_values:
|
||||
return file_values[key]
|
||||
file_val = str(file_values.get(key) or "").strip()
|
||||
if file_val != "":
|
||||
return file_val
|
||||
runtime = os.getenv(key)
|
||||
if runtime is not None and str(runtime).strip() != "":
|
||||
return str(runtime).strip()
|
||||
@@ -183,7 +197,7 @@ 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 {
|
||||
out: dict[str, Any] = {
|
||||
"key": key,
|
||||
"label": label,
|
||||
"note": note or meta.get("note") or "",
|
||||
@@ -197,6 +211,15 @@ def _build_field(
|
||||
"tail": masked.get("tail") or "",
|
||||
"has_value": masked["has_value"],
|
||||
}
|
||||
if key == "POSITION_SIZING_MODE":
|
||||
out["type"] = "enum"
|
||||
out["options"] = list(_POSITION_SIZING_OPTIONS)
|
||||
cur = normalize_position_sizing_mode(out["current"] or out["default"] or "risk")
|
||||
if cur not in ("risk", "full_margin"):
|
||||
cur = "risk"
|
||||
out["current"] = cur
|
||||
out["default"] = cur
|
||||
return out
|
||||
|
||||
|
||||
def ui_sections_for_exchange(exchange_key: str) -> list[dict[str, Any]]:
|
||||
|
||||
Reference in New Issue
Block a user