hamuna-quant-cli 0.1.6__tar.gz → 0.1.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/PKG-INFO +1 -1
  2. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/__init__.py +1 -1
  3. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/__main__.py +46 -12
  4. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli.egg-info/PKG-INFO +1 -1
  5. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/pyproject.toml +1 -1
  6. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/MANIFEST.in +0 -0
  7. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/README.md +0 -0
  8. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/README.md +0 -0
  9. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/_market_fallback.py +0 -0
  10. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/_metrics_15.py +0 -0
  11. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/_test_akquant_parity.py +0 -0
  12. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/akquant_data_adapter.py +0 -0
  13. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/akquant_runner.py +0 -0
  14. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/akquant_schema_adapter.py +0 -0
  15. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/base_strategy.py +0 -0
  16. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/cross_sectional_helpers.py +0 -0
  17. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/live/__init__.py +0 -0
  18. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/live/loader.py +0 -0
  19. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/live/qmt_broker.py +0 -0
  20. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/live/qmt_market.py +0 -0
  21. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/live/runner.py +0 -0
  22. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/prebuilt_downloader.py +0 -0
  23. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/prebuilt_resolver.py +0 -0
  24. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/qmt_translator.py +0 -0
  25. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/runtime/__init__.py +0 -0
  26. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/runtime/backtest.py +0 -0
  27. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/runtime/cache.py +0 -0
  28. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/runtime/discipline.py +0 -0
  29. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/runtime/http_client.py +0 -0
  30. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/runtime/s3client.py +0 -0
  31. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/runtime/server_client.py +0 -0
  32. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli/scripts/server.json +0 -0
  33. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli.egg-info/SOURCES.txt +0 -0
  34. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli.egg-info/dependency_links.txt +0 -0
  35. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli.egg-info/entry_points.txt +0 -0
  36. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli.egg-info/requires.txt +0 -0
  37. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/hamuna_quant_cli.egg-info/top_level.txt +0 -0
  38. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/setup.cfg +0 -0
  39. {hamuna_quant_cli-0.1.6 → hamuna_quant_cli-0.1.7}/tests/test_live_safety.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hamuna-quant-cli
3
- Version: 0.1.6
3
+ Version: 0.1.7
4
4
  Summary: Hamuna A 股回测 + 实盘统一 CLI (akquant 0.3.x). 替代 v1 自建 driver + QMT-style 策略规范.
5
5
  Author-email: Hamuna Team <team@hamuna.example>
6
6
  License: MIT
@@ -12,4 +12,4 @@ server (13-key metrics schema). 全部走 akquant 0.3.x 引擎.
12
12
  """
13
13
  from __future__ import annotations
14
14
 
15
- __version__ = "0.1.6"
15
+ __version__ = "0.1.7"
@@ -30,6 +30,37 @@ def _load_config(path: str) -> dict:
30
30
  return json.loads(Path(path).read_text(encoding="utf-8"))
31
31
 
32
32
 
33
+ def _load_params_arg(arg: str) -> dict | None:
34
+ """Round 18.48+: --params 既支持 inline JSON (以 '{' 开头) 又支持文件路径.
35
+
36
+ 历史 CLI / 回测脚本传文件路径 (`hamuna_quant_cli run --params ./params.json`).
37
+ desktop Rust 调 live run 时通过 `read_to_string` 把 `<name>.params.json` 读成
38
+ String 后 inline 传过来 (`--params '<json>'`), 旧 cli 把 inline 当文件路径
39
+ 直接 `Path.read_text()` → FileNotFoundError (本轮 bug 报告).
40
+
41
+ 协议: 以 '{' (允许前导空白) 开头 → inline JSON parse; 否则 → 文件路径 read.
42
+ Caller 决定 None vs raise: cmd_commit 容忍 None + 走 schema warning,
43
+ cmd_live_run 期望非空否则 raise FileNotFoundError.
44
+ """
45
+ if not arg:
46
+ return None
47
+ stripped = arg.lstrip()
48
+ if stripped.startswith("{"):
49
+ import json as _json
50
+ try:
51
+ return _json.loads(arg)
52
+ except _json.JSONDecodeError as e:
53
+ raise ValueError(f"--params inline JSON 解析失败: {e}") from e
54
+ p = Path(arg)
55
+ if not p.exists():
56
+ raise FileNotFoundError(f"--params 不存在: {arg}")
57
+ import json as _json
58
+ try:
59
+ return _json.loads(p.read_text(encoding="utf-8"))
60
+ except _json.JSONDecodeError as e:
61
+ raise ValueError(f"--params 解析失败: {arg} ({e})") from e
62
+
63
+
33
64
  def _parse_symbols(s: str) -> list[str]:
34
65
  """CSV symbols → 裸码 list (A 股 dataset stockCode 不带 .SH/.SZ/.BJ 后缀)."""
35
66
  out: list[str] = []
@@ -72,18 +103,17 @@ def cmd_run(args) -> int:
72
103
  # --params (params.json 固定 schema) → strategy_params 段注入 cfg,
73
104
  # akquant_runner 展开注入 engine kwargs. 与 `live run --params` 同源:
74
105
  # 同一份 params.json 驱动回测 + 实盘, 参数约定不再分裂 (Round 18.13).
106
+ # Round 18.48+: 既支持文件路径也支持 inline JSON (见 _load_params_arg).
75
107
  if getattr(args, "params", None):
76
- params_path = Path(args.params)
77
- if not params_path.exists():
78
- print(f"--params 不存在: {args.params}", file=sys.stderr)
79
- return 2
80
- import json as _json
81
108
  try:
82
- params_doc = _json.loads(params_path.read_text(encoding="utf-8"))
83
- except _json.JSONDecodeError as e:
84
- print(f"--params 解析失败: {args.params} ({e})", file=sys.stderr)
109
+ params_doc = _load_params_arg(args.params) or {}
110
+ except FileNotFoundError as e:
111
+ print(f"--params 不存在: {e}", file=sys.stderr)
85
112
  return 2
86
- sp = (params_doc or {}).get("strategy_params")
113
+ except ValueError as e:
114
+ print(f"--params 解析失败: {e}", file=sys.stderr)
115
+ return 2
116
+ sp = params_doc.get("strategy_params")
87
117
  if isinstance(sp, dict):
88
118
  cfg["strategy_params"] = sp
89
119
  else:
@@ -91,7 +121,7 @@ def cmd_run(args) -> int:
91
121
  # Round 18.14: risk_config 段 → cfg['risk_config'] → runner 透传
92
122
  # run_backtest(risk_config={"max_position_pct": 0.1}) 原生消费 (账户级风控,
93
123
  # 引擎 hasattr 校验 + 未知字段仅 warning). skill 桌面编辑的实盘风控真正生效.
94
- rc = (params_doc or {}).get("risk_config")
124
+ rc = params_doc.get("risk_config")
95
125
  if isinstance(rc, dict):
96
126
  # 与既有 cfg['risk_config'] 合并 (显式 cfg 优先)
97
127
  merged = dict(cfg.get("risk_config") or {})
@@ -814,9 +844,13 @@ def cmd_live_run(args) -> int:
814
844
  print(f"[error] strategy.py 加载失败: {e}", file=sys.stderr)
815
845
  return 3
816
846
  try:
817
- import json as _json
818
847
  symbols = [s.strip() for s in args.symbols.split(",")] if args.symbols else None
819
- params = _json.loads(Path(args.params).read_text(encoding="utf-8")) if args.params else None
848
+ # Round 18.48+: --params 既支持 inline JSON 也支持文件路径 (desktop rust read_to_string 传 inline)
849
+ try:
850
+ params = _load_params_arg(args.params) if args.params else None
851
+ except (FileNotFoundError, ValueError) as e:
852
+ print(f"[error] --params: {e}", file=sys.stderr)
853
+ return 2
820
854
  # 只取 strategy_params 段 (schema 顶层: backtest / strategy_params / risk_config / meta)
821
855
  sp = (params or {}).get("strategy_params")
822
856
  run_live(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hamuna-quant-cli
3
- Version: 0.1.6
3
+ Version: 0.1.7
4
4
  Summary: Hamuna A 股回测 + 实盘统一 CLI (akquant 0.3.x). 替代 v1 自建 driver + QMT-style 策略规范.
5
5
  Author-email: Hamuna Team <team@hamuna.example>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hamuna-quant-cli"
7
- version = "0.1.6"
7
+ version = "0.1.7"
8
8
  description = "Hamuna A 股回测 + 实盘统一 CLI (akquant 0.3.x). 替代 v1 自建 driver + QMT-style 策略规范."
9
9
  readme = "hamuna_quant_cli/README.md"
10
10
  requires-python = ">=3.10"