hamuna-quant-cli 0.1.7__tar.gz → 0.1.8__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.
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/PKG-INFO +1 -1
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/live/runner.py +69 -4
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli.egg-info/PKG-INFO +1 -1
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/pyproject.toml +1 -1
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/MANIFEST.in +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/README.md +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/README.md +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/__init__.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/__main__.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/_market_fallback.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/_metrics_15.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/_test_akquant_parity.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/akquant_data_adapter.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/akquant_runner.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/akquant_schema_adapter.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/base_strategy.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/cross_sectional_helpers.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/live/__init__.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/live/loader.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/live/qmt_broker.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/live/qmt_market.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/prebuilt_downloader.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/prebuilt_resolver.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/qmt_translator.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/runtime/__init__.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/runtime/backtest.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/runtime/cache.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/runtime/discipline.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/runtime/http_client.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/runtime/s3client.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/runtime/server_client.py +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/scripts/server.json +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli.egg-info/SOURCES.txt +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli.egg-info/dependency_links.txt +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli.egg-info/entry_points.txt +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli.egg-info/requires.txt +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli.egg-info/top_level.txt +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/setup.cfg +0 -0
- {hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/tests/test_live_safety.py +0 -0
|
@@ -282,10 +282,10 @@ def configure_logging(level: str, log_file: Path | None) -> None:
|
|
|
282
282
|
def _with_live_history_depth(
|
|
283
283
|
cls: type, params: dict | None = None, calendar: list[str] | None = None
|
|
284
284
|
) -> type:
|
|
285
|
-
"""class mode 注入 set_history_depth + 交易日历重排定时器 — live
|
|
286
|
-
(engine.py:4637) 那样自动开 history tracking, 策略 on_bar 里
|
|
287
|
-
"History tracking is not enabled" (2026-08-19 实测). depth
|
|
288
|
-
warmup_period, 未设默认 120.
|
|
285
|
+
"""class mode 注入 set_history_depth + 交易日历重排定时器 + 5 类日志 hook — live
|
|
286
|
+
引擎不像回测 (engine.py:4637) 那样自动开 history tracking, 策略 on_bar 里
|
|
287
|
+
get_history 直接抛 "History tracking is not enabled" (2026-08-19 实测). depth
|
|
288
|
+
取策略 on_start 设的 warmup_period, 未设默认 120.
|
|
289
289
|
|
|
290
290
|
calendar: 真实交易日列表 (YYYY-MM-DD, 从 bars_df / bridge 历史提取). 非空时
|
|
291
291
|
wrapper 在 on_start 里按日历注册周五 14:55 的 schedule() 定时器 (payload
|
|
@@ -299,6 +299,20 @@ def _with_live_history_depth(
|
|
|
299
299
|
末尾 `model_cls(**kwargs)`, 盖 __init__ 传 kwargs 不回灌 — 2026-08-25
|
|
300
300
|
实测缺口), 因此 wrapper 保留 `__new__` override 做 params 注入.
|
|
301
301
|
|
|
302
|
+
5 类日志 hook (Round 18.55, 适应任何 class-mode 策略, 不改用户代码):
|
|
303
|
+
- [on_bar_entry] 替代 [signal_calc] — 每次 on_bar / on_tick 入口自动打
|
|
304
|
+
(含 sym / price / bar timestamp), 取代用户策略里手写
|
|
305
|
+
"我正在计算 MA5/MA20" 的样板. 用户策略内部指标计算仍可
|
|
306
|
+
用 self.log('[signal_calc] ma_fast=X ma_slow=Y') 加细节.
|
|
307
|
+
- [signal_trigger] on_order 触发前自动打 (side/sym/qty/price), 替代用户
|
|
308
|
+
自己写 "我要下单了" — 这是 risk_check / pos_check /
|
|
309
|
+
capital_check 通过后才触发, 所以 [signal_trigger] 出现 =
|
|
310
|
+
风控放行.
|
|
311
|
+
- [signal_filled] on_trade 回调自动打 (sym/qty/price), 等同成交回报.
|
|
312
|
+
- [risk_check] / [pos_check] / [capital_check] 由用户自己写 self.log(...)
|
|
313
|
+
(看不到 user 内部逻辑, wrapper 没法自动打; 例见 example_strategy.py
|
|
314
|
+
Round 18.52 的 _risk_check + 5 tick 节流).
|
|
315
|
+
|
|
302
316
|
ponytail: 只包 class mode; functional mode 用户自己管 get_history (ctx 侧).
|
|
303
317
|
日历定时器只覆盖周五重排; 非周五策略自己 on_timer 空转.
|
|
304
318
|
"""
|
|
@@ -338,6 +352,57 @@ def _with_live_history_depth(
|
|
|
338
352
|
print(f"[warn] set_history_depth({depth}) 失败: {e}", flush=True)
|
|
339
353
|
return ret_val
|
|
340
354
|
|
|
355
|
+
# ========== Round 18.55 5 类日志 hook ==========
|
|
356
|
+
# hook 在 super().xxx 调用前后自动打, 不破坏 user 的 on_bar / on_tick 逻辑.
|
|
357
|
+
# 用 try/except 包住 user 抛出的异常 — wrapper 的 log 失败不能让策略崩.
|
|
358
|
+
|
|
359
|
+
def on_bar(self, bar: _Any) -> _Any: # type: ignore[override]
|
|
360
|
+
try:
|
|
361
|
+
sym = getattr(bar, "symbol", "?")
|
|
362
|
+
ts = getattr(bar, "timestamp", 0)
|
|
363
|
+
close = float(getattr(bar, "close", 0.0) or 0.0)
|
|
364
|
+
from datetime import datetime as _dt2
|
|
365
|
+
ts_str = _dt2.fromtimestamp(ts / 1e9).strftime("%H:%M") if ts else "?"
|
|
366
|
+
print(f"[on_bar_entry] sym={sym} close={close:.3f} ts={ts_str}",
|
|
367
|
+
flush=True)
|
|
368
|
+
except Exception: # noqa: BLE001
|
|
369
|
+
pass
|
|
370
|
+
return super().on_bar(bar)
|
|
371
|
+
|
|
372
|
+
def on_tick(self, tick: _Any) -> _Any: # type: ignore[override]
|
|
373
|
+
try:
|
|
374
|
+
sym = getattr(tick, "symbol", "?")
|
|
375
|
+
price = float(getattr(tick, "price", 0.0) or 0.0)
|
|
376
|
+
print(f"[on_tick_entry] sym={sym} price={price:.3f}", flush=True)
|
|
377
|
+
except Exception: # noqa: BLE001
|
|
378
|
+
pass
|
|
379
|
+
return super().on_tick(tick)
|
|
380
|
+
|
|
381
|
+
def on_order(self, order: _Any) -> _Any: # type: ignore[override]
|
|
382
|
+
try:
|
|
383
|
+
side = getattr(order, "side", "?")
|
|
384
|
+
sym = getattr(order, "symbol", "?")
|
|
385
|
+
qty = int(getattr(order, "quantity", 0) or 0)
|
|
386
|
+
price = float(getattr(order, "price", 0.0) or 0.0)
|
|
387
|
+
print(f"[signal_trigger] side={side} sym={sym} qty={qty} "
|
|
388
|
+
f"price={price:.3f} (风控/持仓/资金 已通过)",
|
|
389
|
+
flush=True)
|
|
390
|
+
except Exception: # noqa: BLE001
|
|
391
|
+
pass
|
|
392
|
+
return super().on_order(order)
|
|
393
|
+
|
|
394
|
+
def on_trade(self, trade: _Any) -> _Any: # type: ignore[override]
|
|
395
|
+
try:
|
|
396
|
+
sym = getattr(trade, "symbol", "?")
|
|
397
|
+
qty = int(getattr(trade, "quantity", 0) or 0)
|
|
398
|
+
price = float(getattr(trade, "price", 0.0) or 0.0)
|
|
399
|
+
side = getattr(trade, "side", "?")
|
|
400
|
+
print(f"[signal_filled] side={side} sym={sym} qty={qty} "
|
|
401
|
+
f"price={price:.3f}", flush=True)
|
|
402
|
+
except Exception: # noqa: BLE001
|
|
403
|
+
pass
|
|
404
|
+
return super().on_trade(trade)
|
|
405
|
+
|
|
341
406
|
_Wrapped.__name__ = cls.__name__
|
|
342
407
|
_Wrapped.__qualname__ = cls.__qualname__
|
|
343
408
|
return _Wrapped
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "hamuna-quant-cli"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.8"
|
|
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"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/akquant_schema_adapter.py
RENAMED
|
File without changes
|
|
File without changes
|
{hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli/cross_sectional_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{hamuna_quant_cli-0.1.7 → hamuna_quant_cli-0.1.8}/hamuna_quant_cli.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|