feat etf
This commit is contained in:
62
labs/analysis/etf/validate_config.py
Normal file
62
labs/analysis/etf/validate_config.py
Normal file
@@ -0,0 +1,62 @@
|
||||
"""校验 py-client/etc/_etf.yaml:用策略自己的 config.load 解析,并核对每只标的的数据可用性。
|
||||
|
||||
用法: py -3.14 -B labs/analysis/etf/validate_config.py
|
||||
"""
|
||||
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
REPO = HERE.parents[2]
|
||||
sys.path.insert(0, str(HERE))
|
||||
sys.path.insert(0, str(REPO / "py-client"))
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
import yaml # noqa: E402
|
||||
|
||||
import config # noqa: E402
|
||||
from backtest import CACHE, fetch_daily # noqa: E402
|
||||
|
||||
ETC = REPO / "py-client" / "etc"
|
||||
|
||||
# 1) 用策略自身的校验逻辑加载(除了 _global/account 这两层,直接调 _etf_config)
|
||||
cfg = config._etf_config(ETC / "_etf.yaml")
|
||||
if cfg is None:
|
||||
print("FAIL: _etf_config 返回 None(文件不存在?)")
|
||||
raise SystemExit(1)
|
||||
|
||||
print(f"配置解析通过:{len(cfg.symbols)} 只标的,顺序 = 资金优先级")
|
||||
print(f"{'#':>3} {'代码':11} {'每档':>6} {'上限':>7} {'T+0':>5} {'atr×':>5} {'inner':>6} 数据")
|
||||
ok = True
|
||||
for index, code in enumerate(cfg.codes, 1):
|
||||
symbol = cfg.symbols[code]
|
||||
try:
|
||||
bars = fetch_daily(code)
|
||||
first, last = bars[0]["date"], bars[-1]["date"]
|
||||
data = f"{len(bars)} 根 {first}..{last}"
|
||||
if len(bars) < 61:
|
||||
data += " ← 不足 61 根,策略会跳过"
|
||||
ok = False
|
||||
except Exception as exc:
|
||||
data = f"抓取失败:{exc}"
|
||||
ok = False
|
||||
print(f"{index:3} {code:11} {symbol.buy_shares:6} {symbol.max_shares:7} "
|
||||
f"{str(symbol.is_t0):>5} {symbol.atr_multiplier:5.1f} {symbol.inner_step:6.1f} {data}")
|
||||
|
||||
# 2) 断言:inner_grids × inner_step < min_profit_pct,否则副出口不可能触发
|
||||
grids, step = cfg.defaults.inner_grids, min(s.inner_step for s in cfg.symbols.values())
|
||||
profit = cfg.defaults.min_profit_pct
|
||||
print()
|
||||
print(f"副出口可达性:inner_grids({grids}) × inner_step({step}) = {grids * step:.2f}% "
|
||||
f"vs min_profit_pct {profit}% → {'可达' if grids * step < profit else '不可达(会被主出口压制)'}")
|
||||
|
||||
# 3) 估算资金需求
|
||||
need_one = sum(cfg.symbols[c].buy_shares * fetch_daily(c)[-1]["close"] for c in cfg.codes)
|
||||
print(f"资金需求:16 只各铺 1 档 ≈ {need_one:,.0f} 元;各铺满 10 档 ≈ {need_one * 10:,.0f} 元")
|
||||
print()
|
||||
print("校验结果:", "通过" if ok else "存在问题(见上)")
|
||||
raise SystemExit(0 if ok else 1)
|
||||
Reference in New Issue
Block a user