fix bug
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import socket
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass, field, fields
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
@@ -43,9 +43,7 @@ class AccountConfig:
|
||||
host_key: str = ""
|
||||
buy_value: float = 0
|
||||
min_cash_ratio: float = 0
|
||||
loss_trigger_pct: float = 0
|
||||
grid_step_pct: float = 1
|
||||
min_profit_pct: float = 0
|
||||
enable_loss_add_position: bool = False
|
||||
enable_auto_ipo: bool = True
|
||||
signal_allow: list[str] = field(default_factory=list)
|
||||
@@ -55,6 +53,10 @@ class AccountConfig:
|
||||
zt_sell_ratio: float = 0.5
|
||||
zt_buy_fall_pct: float = 1.0
|
||||
zt_max_price: float = 200.0
|
||||
# 正T/反T 中性带:现价在建仓价 ±N% 内不动手,避免来回摩擦。
|
||||
zt_t_band_pct: float = 1.0
|
||||
# 单轮最长持有自然日;超期告警并放弃继续平仓,残量留作隔夜持仓。
|
||||
zt_max_hold_days: int = 5
|
||||
|
||||
# 当前账户启用的策略名称,例如 trend。
|
||||
strategy: str = ""
|
||||
@@ -129,7 +131,7 @@ def load(
|
||||
# 策略状态文件写入该目录,启动时提前确保目录存在。
|
||||
Path(global_config.qmt_data_dir).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
account_config = AccountConfig(**_yaml(root / account_file))
|
||||
account_config = AccountConfig(**_account_values(root / account_file))
|
||||
if account_config.buy_value <= 0 or account_config.grid_step_pct <= 0:
|
||||
raise ValueError("buy_value、grid_step_pct 必须大于 0")
|
||||
if type(account_config.zt_open_hands) is not int or account_config.zt_open_hands < 0:
|
||||
@@ -138,6 +140,10 @@ def load(
|
||||
raise ValueError("zt_sell_ratio 必须在 (0, 1] 区间")
|
||||
if account_config.zt_buy_fall_pct <= 0 or account_config.zt_max_price <= 0:
|
||||
raise ValueError("zt_buy_fall_pct、zt_max_price 必须大于 0")
|
||||
if account_config.zt_t_band_pct < 0:
|
||||
raise ValueError("zt_t_band_pct 不能为负数")
|
||||
if type(account_config.zt_max_hold_days) is not int or account_config.zt_max_hold_days <= 0:
|
||||
raise ValueError("zt_max_hold_days 必须为正整数")
|
||||
if not account_config.strategy.strip():
|
||||
raise ValueError("strategy 不能为空")
|
||||
|
||||
@@ -156,3 +162,18 @@ def _yaml(path: Path) -> dict:
|
||||
return yaml.safe_load(handle) or {}
|
||||
except (OSError, yaml.YAMLError) as exc:
|
||||
raise ValueError(f"读取或解析配置 {path} 失败: {exc}") from exc
|
||||
|
||||
|
||||
def _account_values(path: Path) -> dict:
|
||||
"""读取账户配置,并拒绝拼错或已废弃的字段。
|
||||
|
||||
以前未知字段会被 ``AccountConfig(**raw)`` 抛成 TypeError,绕开 main()
|
||||
的异常分支并以裸 traceback 退出;这里改成带文件名的 ValueError。
|
||||
"""
|
||||
raw = _yaml(path)
|
||||
if not isinstance(raw, dict):
|
||||
raise ValueError(f"账户配置 {path} 的根节点必须是对象")
|
||||
unknown = sorted(set(raw) - {item.name for item in fields(AccountConfig)})
|
||||
if unknown:
|
||||
raise ValueError(f"账户配置 {path} 存在未知字段: {', '.join(unknown)}")
|
||||
return raw
|
||||
|
||||
Reference in New Issue
Block a user