diff --git a/crypto_monitor_binance/.env.example b/crypto_monitor_binance/.env.example index 4efea0e..5ffd4ad 100644 --- a/crypto_monitor_binance/.env.example +++ b/crypto_monitor_binance/.env.example @@ -154,11 +154,11 @@ DAILY_OPEN_HARD_LIMIT=0 # 账户冷静期 / 日冻结风控(手动平仓、外部平仓、复盘情绪标签) # 详见 docs/account-risk-cooldown.md # ============================================================================= -# RISK_CONTROL_ENABLED=true -# RISK_COOLING_HOURS_MANUAL=4 -# RISK_COOLING_HOURS_MANUAL_JOURNAL=1 -# RISK_MANUAL_CLOSE_DAILY_LIMIT=2 -# RISK_MOOD_ISSUES_DAILY_FREEZE=true +RISK_CONTROL_ENABLED=true +RISK_COOLING_HOURS_MANUAL=4 +RISK_COOLING_HOURS_MANUAL_JOURNAL=1 +RISK_MANUAL_CLOSE_DAILY_LIMIT=2 +RISK_MOOD_ISSUES_DAILY_FREEZE=true # 资金与仓位刷新周期(秒) BALANCE_REFRESH_SECONDS=60 diff --git a/crypto_monitor_gate/.env.example b/crypto_monitor_gate/.env.example index 540cbdd..879e782 100644 --- a/crypto_monitor_gate/.env.example +++ b/crypto_monitor_gate/.env.example @@ -156,11 +156,11 @@ DAILY_OPEN_HARD_LIMIT=0 # 账户冷静期 / 日冻结风控(手动平仓、外部平仓、复盘情绪标签) # 详见 docs/account-risk-cooldown.md # ============================================================================= -# RISK_CONTROL_ENABLED=true -# RISK_COOLING_HOURS_MANUAL=4 -# RISK_COOLING_HOURS_MANUAL_JOURNAL=1 -# RISK_MANUAL_CLOSE_DAILY_LIMIT=2 -# RISK_MOOD_ISSUES_DAILY_FREEZE=true +RISK_CONTROL_ENABLED=true +RISK_COOLING_HOURS_MANUAL=4 +RISK_COOLING_HOURS_MANUAL_JOURNAL=1 +RISK_MANUAL_CLOSE_DAILY_LIMIT=2 +RISK_MOOD_ISSUES_DAILY_FREEZE=true # 资金与仓位刷新周期(秒) BALANCE_REFRESH_SECONDS=60 diff --git a/crypto_monitor_okx/.env.example b/crypto_monitor_okx/.env.example index 26a27c2..47d29e4 100644 --- a/crypto_monitor_okx/.env.example +++ b/crypto_monitor_okx/.env.example @@ -184,11 +184,11 @@ DAILY_OPEN_HARD_LIMIT=0 # 账户冷静期 / 日冻结风控(手动平仓、外部平仓、复盘情绪标签) # 详见 docs/account-risk-cooldown.md # ============================================================================= -# RISK_CONTROL_ENABLED=true -# RISK_COOLING_HOURS_MANUAL=4 -# RISK_COOLING_HOURS_MANUAL_JOURNAL=1 -# RISK_MANUAL_CLOSE_DAILY_LIMIT=2 -# RISK_MOOD_ISSUES_DAILY_FREEZE=true +RISK_CONTROL_ENABLED=true +RISK_COOLING_HOURS_MANUAL=4 +RISK_COOLING_HOURS_MANUAL_JOURNAL=1 +RISK_MANUAL_CLOSE_DAILY_LIMIT=2 +RISK_MOOD_ISSUES_DAILY_FREEZE=true # 资金与仓位刷新周期(秒) BALANCE_REFRESH_SECONDS=60 diff --git a/lib/env/env_ui_manifest.py b/lib/env/env_ui_manifest.py index 146e402..b267bf3 100644 --- a/lib/env/env_ui_manifest.py +++ b/lib/env/env_ui_manifest.py @@ -1,6 +1,7 @@ """env 配置页 UI 白名单:中文标签、按交易所过滤。""" from __future__ import annotations +import os from typing import Any, Optional from lib.env.env_file_lib import env_get_all, read_env_lines @@ -137,6 +138,27 @@ _OPTIONS_SECTION: dict[str, Any] = { } +# 与运行时 os.getenv 默认一致;.env 未写明时展示实际生效值(同风控说明页) +_RUNTIME_ENV_DEFAULTS: dict[str, str] = { + "RISK_CONTROL_ENABLED": "true", + "RISK_COOLING_HOURS_MANUAL": "4", + "RISK_COOLING_HOURS_MANUAL_JOURNAL": "1", + "RISK_MANUAL_CLOSE_DAILY_LIMIT": "2", + "RISK_MOOD_ISSUES_DAILY_FREEZE": "true", +} + + +def _effective_env_value(key: str, file_values: dict[str, str], schema_default: str = "") -> str: + if key in file_values: + return file_values[key] + runtime = os.getenv(key) + if runtime is not None and str(runtime).strip() != "": + return str(runtime).strip() + if schema_default: + return schema_default + return _RUNTIME_ENV_DEFAULTS.get(key, "") + + def _schema_field_map(example_path: str) -> dict[str, dict[str, Any]]: out: dict[str, dict[str, Any]] = {} for group in parse_env_example_schema(example_path): @@ -153,17 +175,15 @@ def _build_field( values: dict[str, str], ) -> dict[str, Any]: meta = schema.get(key) or {} - default_val = meta.get("default") or values.get(key) or "" - val = values.get(key) - if val is None: - val = default_val + schema_default = meta.get("default") or "" + val = _effective_env_value(key, values, schema_default) masked = _mask_value(key, val) - ftype = meta.get("type") or _field_type(key, default_val) + ftype = meta.get("type") or _field_type(key, val or schema_default) return { "key": key, "label": label, "note": note or meta.get("note") or "", - "default": default_val, + "default": val, "type": ftype, "sensitive": meta.get("sensitive", _is_sensitive(key)), "restart_required": meta.get("restart_required", _restart_required(key)),