release: v1.8.1 - single-source version, batch backtest detail output

- Consolidate version to pyproject.toml as single source of truth
- __init__.py, cli/__init__.py, docs/conf.py all read dynamically
- run_all_strategies.py now shows best strategy full trade details
- Update README changelog for 1.8.1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
GitHub
2026-06-09 22:12:27 +08:00
co-authored by Claude Opus 4.8
parent b5b5d0dc5b
commit b44636207b
7 changed files with 71 additions and 5 deletions
+2 -1
View File
@@ -78,7 +78,8 @@
"Bash(mypy src/easy_tdx/backtest/types.py tests/unit/test_backtest_types.py)",
"Bash(mypy *)",
"Bash(git diff *)",
"Bash(echo \"exit: $?\")"
"Bash(echo \"exit: $?\")",
"Bash(where easy-tdx *)"
]
}
}
+8
View File
@@ -1081,6 +1081,14 @@ ruff format --check src/ tests/ # format check
## Changelog
### 1.8.1 (2026-06-09)
**回测增强** — 批量策略对比脚本新增最佳策略完整交易明细输出;版本号统一为单一来源(`pyproject.toml`)。
- `run_all_strategies.py` 排名结束后自动输出最佳策略的绩效概要 + 最近 10 笔交易记录
- 修复 `turtle_breakout` 策略 `TAQ()` 返回 3 值但只解包 2 个的 bug
- 版本号统一:`pyproject.toml` 为唯一来源,`__init__.py` / `cli/__init__.py` / `docs/conf.py` 均动态读取
### 1.8.0 (2026-06-09)
**回测引擎** — 内置向量回测引擎,支持自定义策略回测和全策略批量对比。
+9 -1
View File
@@ -3,8 +3,16 @@ project = "easy-tdx"
copyright = "2025, Justin Gu"
author = "Justin Gu"
# The full version, including alpha/beta/rc tags
release = "1.8.0"
# Read from package metadata to keep single source of truth (pyproject.toml)
def _get_version() -> str:
from importlib.metadata import version
return version("easy-tdx")
release = _get_version()
# -- Extensions ---------------------------------------------------------------
extensions = [
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "easy-tdx"
version = "1.8.0"
version = "1.8.1"
description = "通达信 TCP 协议行情数据客户端,支持在线行情、离线数据读取与写入同步"
readme = "README.md"
requires-python = ">=3.10"
+42
View File
@@ -13,6 +13,7 @@ import json
import sys
import time
from pathlib import Path
from typing import Any
# 确保 easy_tdx 可导入
sys.path.insert(0, str(Path(__file__).parent / "src"))
@@ -75,6 +76,7 @@ def run_all(
# 3. 逐个运行策略
results: list[dict] = []
backtest_results: dict[str, Any] = {} # strategy_name -> BacktestResult
for sf in strategy_files:
strategy_name = sf.stem
@@ -132,6 +134,7 @@ def run_all(
"profit_factor": perf.get("profit_factor", 0),
"volatility": perf.get("volatility", 0),
})
backtest_results[strategy_name] = result
except Exception as e:
elapsed = time.perf_counter() - t0
click.echo(f" 错误 ({elapsed:.1f}s): {e}")
@@ -220,6 +223,45 @@ def run_all(
f"{r['sharpe']:>8.2f} {ret_dd_ratio:>10.2f} {r['win_rate']:>7.1%}"
)
# 最佳策略完整交易明细
best_name = valid[0]["strategy"]
if best_name in backtest_results:
bt = backtest_results[best_name]
bp = bt.performance
bc = bt.config
click.echo("\n" + "=" * 80)
click.echo(f"[DETAIL] 最佳策略交易明细: {best_name}")
click.echo("=" * 80)
click.echo("=== 回测绩效概要 ===")
click.echo(f"总收益率: {bp.get('total_return', 0):.2%}")
click.echo(f"年化收益: {bp.get('annual_return', 0):.2%}")
click.echo(f"最大回撤: {bp.get('max_drawdown', 0):.2%}")
click.echo(f"夏普比率: {bp.get('sharpe', 0):.2f}")
click.echo(f"胜率: {bp.get('win_rate', 0):.2%}")
click.echo(f"交易次数: {bp.get('total_trades', 0)}")
click.echo()
click.echo("=== 配置参数 ===")
click.echo(f"初始资金: {bc.get('cash', 0):.2f}")
click.echo(f"佣金率: {bc.get('commission', 0):.4f}")
click.echo(f"成交规则: {bc.get('execution', 'next_open')}")
click.echo()
if not bt.trades.empty:
click.echo("=== 最近交易记录 ===")
recent_trades = bt.trades.tail(10)
for _, trade in recent_trades.iterrows():
direction = "买入" if trade["direction"] == "BUY" else "卖出"
status = "拒绝" if trade["rejected"] else "成交"
click.echo(
f" [{trade['datetime']}] {direction} "
f"数量={trade['size']:.0f} 价格={trade['price']:.2f} "
f"盈亏={trade['pnl']:.2f} [{status}]"
)
else:
click.echo("无交易记录")
# 报告错误
if errored:
click.echo("\n[!] 以下策略运行失败:")
+8 -1
View File
@@ -107,4 +107,11 @@ __all__ = [
"save_best_ex_host",
]
__version__ = "1.8.0"
def _get_version() -> str:
from importlib.metadata import version
return version("easy-tdx")
__version__ = _get_version()
+1 -1
View File
@@ -23,7 +23,7 @@ from ..backtest.cli import backtest
@click.group()
@click.version_option(version="1.8.0", prog_name="easy-tdx")
@click.version_option(version=__import__("importlib.metadata", fromlist=["version"]).version("easy-tdx"), prog_name="easy-tdx")
def cli() -> None:
"""easy-tdx -- 通达信行情数据 CLI(默认 JSON 输出,适合 Agent 使用)。