From 25f1a4bce5c92d91fc390854c3ce12fb1b7f7406 Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Fri, 16 Oct 2026 21:06:33 +0800 Subject: [PATCH] docs: synchronize English and Chinese READMEs Co-Authored-By: Codex --- README.md | 137 ++++++++++++++++++++++++++++------------------- README.zh-CN.md | 139 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 183 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index e777b49..df007b9 100644 --- a/README.md +++ b/README.md @@ -1,106 +1,131 @@ # QmtPlatform -A-share quant platform layer for **miniQMT / QMT**, built on `QuantPlatformKit` and `CnEquityStrategies`. +English | [简体中文](README.zh-CN.md) -Current scope is **offline dry-run only**: evaluate strategy targets and preview orders without submitting to the broker. This repository is not a shadow/live runtime; any non-dry-run order request is rejected as `blocked` and is never reported as `submitted`. +A-share quant platform layer for miniQMT / QMT, built on `QuantPlatformKit` and `CnEquityStrategies`. -## QSL architecture role +## Status -- **Layer**: `runtime-platform`. -- **Responsibility**: QMT / miniQMT A-share execution runtime. -- **Owns**: QMT runtime controls and A-share platform integration. -- **Consumes**: CnEquityStrategies, QuantPlatformKit, QuantRuntimeSettings, market-history inputs. -- **Must not**: own strategy research logic or publish snapshot artifacts. +Experimental. The current implementation evaluates strategies offline and previews orders. This project is not financial advice and does not guarantee any trading result. -## Offline paper admission (not broker paper) +## What this is -`--paper-admission` is a deterministic local configuration gate, not a miniQMT/QMT paper account connection. It requires all of the following: +QmtPlatform provides the QMT platform integration layer. It loads strategy profiles from `CnEquityStrategies`, reads local market-history inputs, and evaluates target weights against a synthetic portfolio. `QuantPlatformKit` supplies shared runtime and strategy contracts; `QuantRuntimeSettings` supplies runtime target definitions. -- `QMT_EXECUTION_MODE=paper`; -- `QMT_DRY_RUN_ONLY=true`; -- a pre-recorded SHA-256 digest matching the fixed `QMT_MARKET_HISTORY_PATH` input. +## What this is not -It only loads the strategy contract and hashes the local input. It does not call a QMT SDK/provider, read credentials, create orders, evaluate a broker account, or make this repository broker-paper or live ready. - -```bash -export QMT_EXECUTION_MODE=paper -export QMT_DRY_RUN_ONLY=true -export QMT_PAPER_ADMISSION_INPUT_SHA256=5612a923290ed9fb779ce39613c5ea875ee68f69bf2aade0358761f2b86b3afb -python3 scripts/preflight_qmt_runtime.py --paper-admission -``` - -## Supported dry-run profiles - -| Profile | Input mode | -|---|---| -| `cn_industry_etf_rotation` | `market_history` (**主轨,runtime_enabled**) | -| `cn_industry_etf_rotation_aggressive` | `market_history` (**optional target,live_candidate**) | - -Research-only profiles such as `cn_dividend_quality_snapshot` and `cn_index_etf_tactical_rotation` are intentionally rejected by QMT runtime settings until they are promoted in `CnEquityStrategies`. +This repository does not implement strategy research or publish snapshot artifacts. It has no miniQMT / QMT broker connection. The offline broker adapter returns `blocked` for non-dry-run order requests and never reports them as `submitted`. ## Quick start -### Industry ETF rotation (market history, primary) +Requirements: Python 3.11 or later and Git. Run these commands from the repository root. The package installation resolves the dependency revisions declared in `pyproject.toml`. ```bash python3 -m pip install -e '.[test]' -python3 -m pip install --no-deps -e ../QuantPlatformKit ../CnEquityStrategies +python3 -m pytest -q tests +unset RUNTIME_TARGET_JSON export STRATEGY_PROFILE=cn_industry_etf_rotation export QMT_DRY_RUN_ONLY=true +export QMT_EXECUTION_MODE=dry_run export QMT_MARKET_HISTORY_PATH=data/fixtures/market_history.sample.csv python3 scripts/preflight_qmt_runtime.py python3 main.py -curl http://127.0.0.1:8080/probe -curl http://127.0.0.1:8080/dry-run ``` -### Industry ETF rotation aggressive (optional second target, vol25%) +In another terminal, query the local service: ```bash -export STRATEGY_PROFILE=cn_industry_etf_rotation_aggressive -export QMT_DRY_RUN_ONLY=true -export QMT_MARKET_HISTORY_PATH=data/fixtures/market_history.sample.csv - -python3 main.py +curl http://127.0.0.1:8080/probe +curl http://127.0.0.1:8080/profiles curl http://127.0.0.1:8080/dry-run ``` -Runtime target example: `QuantRuntimeSettings/examples/targets/qmt/industry_etf_aggressive_dry_run.example.json` - -End-to-end smoke (stage/build/run): +The fixture-backed smoke scripts run a local strategy cycle without starting the HTTP service: ```bash python3 scripts/smoke_cn_industry_etf_rotation_dry_run_e2e.py python3 scripts/smoke_cn_industry_etf_rotation_aggressive_dry_run_e2e.py ``` -## Environment variables +## Configuration + +Use [`.env.example`](.env.example) as the dry-run configuration reference. Export its values in your shell; the entrypoint reads environment variables. The preflight command validates the selected profile and required input paths without accessing broker credentials. + +| Variable | Required | Default | Purpose | +|---|---|---|---| +| `STRATEGY_PROFILE` | Unless `RUNTIME_TARGET_JSON` is set | none | QMT-enabled strategy profile ID. | +| `QMT_DRY_RUN_ONLY` | No | `true` | Keep `true`; preflight rejects `false`, and the HTTP dry-run endpoint always uses dry-run settings. | +| `QMT_EXECUTION_MODE` | No | `dry_run` | Set to `paper` only for offline paper admission; this value does not create a broker connection. | +| `QMT_PAPER_ADMISSION_INPUT_SHA256` | For `--paper-admission` | none | Pre-recorded SHA-256 digest of the fixed market-history input. | +| `QMT_MARKET_HISTORY_PATH` | For market-history profiles | none | Local CSV path with `date,symbol,close` columns. | +| `RUNTIME_TARGET_JSON` | No | none | JSON runtime target from `QuantRuntimeSettings`; takes precedence over `STRATEGY_PROFILE`. | +| `PORT` | No | `8080` | HTTP port; the Flask entrypoint binds to `0.0.0.0`. | + +## Supported dry-run profiles -| Variable | Default | Description | +| Profile | Input mode | Role | |---|---|---| -| `QMT_DRY_RUN_ONLY` | `true` | Offline-only guard; non-dry-run requests remain blocked | -| `QMT_EXECUTION_MODE` | `dry_run` | Must be `paper` for offline paper admission; it never enables a broker connection | -| `QMT_PAPER_ADMISSION_INPUT_SHA256` | — | Required only for `--paper-admission`; pre-recorded digest of the fixed market-history input | -| `STRATEGY_PROFILE` | required | QMT-enabled strategy profile id | -| `QMT_MARKET_HISTORY_PATH` | — | CSV with `date,symbol,close` for direct strategies | -| `RUNTIME_TARGET_JSON` | — | Optional runtime target override from QuantRuntimeSettings | +| `cn_industry_etf_rotation` | `market_history` | Primary profile. | +| `cn_industry_etf_rotation_aggressive` | `market_history` | Optional profile with a 25% volatility target. | -Use `.env.example` as the dry-run configuration template. Run `python3 scripts/preflight_qmt_runtime.py` before starting the service; it validates the selected profile and required input paths without touching any live account credentials. +Set `STRATEGY_PROFILE=cn_industry_etf_rotation_aggressive` to select the optional profile when `RUNTIME_TARGET_JSON` is unset. A runtime target example is available in [QuantRuntimeSettings](https://github.com/QuantStrategyLab/QuantRuntimeSettings/blob/main/examples/targets/qmt/industry_etf_aggressive_dry_run.example.json). + +Profile availability follows the `CnEquityStrategies` catalog and QMT rollout allowlist. Research-only profiles such as `cn_dividend_quality_snapshot` and `cn_index_etf_tactical_rotation` are rejected by the QMT runtime policy. + +## Offline paper admission + +`--paper-admission` checks a local configuration and fixed input file. It requires `QMT_EXECUTION_MODE=paper`, `QMT_DRY_RUN_ONLY=true`, and a pre-recorded SHA-256 digest matching `QMT_MARKET_HISTORY_PATH`. + +After configuring the profile and input path, replace `` with that recorded digest: + +```bash +export QMT_EXECUTION_MODE=paper +export QMT_DRY_RUN_ONLY=true +export QMT_PAPER_ADMISSION_INPUT_SHA256='' +python3 scripts/preflight_qmt_runtime.py --paper-admission +``` + +The command loads the strategy contract and hashes the local input. It does not call a QMT SDK or provider, read credentials, create orders, or evaluate a broker account. The word `paper` here names an offline check, not a broker paper-trading connection. ## Disabled-target lifecycle validation -QMT has no configured broker runtime or live credentials. The weekday `Runtime Target Lifecycle` workflow therefore runs only the deterministic preflight and fixture-backed dry-run smoke, then publishes a sanitized central status of `disabled` / `dry_run`. A completed dry-run with weights blocked by the deterministic risk gate is also a passing no-order validation: the platform and its safety boundary both worked. It does **not** mean that QMT is deployed, connected to miniQMT, paper-enabled, or live-enabled. A preflight or dry-run failure is published as `attention`; no status can change the target state or submit an order. +The weekday `Runtime Target Lifecycle` workflow runs deterministic preflight and a fixture-backed dry-run for a fixed disabled target. It publishes `disabled` / `dry_run` status. A completed cycle whose target weights are empty because of the risk gate is a successful no-order check; a preflight or dry-run failure is reported as `attention`. These reports do not change target settings, establish a broker connection, or submit orders. ## HTTP endpoints -- `GET /probe` — health + active profile -- `GET /profiles` — platform profile matrix -- `GET|POST /dry-run` — evaluate strategy and return target weights + order previews +| Method | Path | Response | +|---|---|---| +| `GET` | `/probe` | Health, active profile, and dry-run setting. | +| `GET` | `/profiles` | Platform profile matrix. | +| `GET`, `POST` | `/dry-run` | Strategy target weights and order previews using local inputs. | ## Related repositories +- [QuantPlatformKit](https://github.com/QuantStrategyLab/QuantPlatformKit) - [CnEquityStrategies](https://github.com/QuantStrategyLab/CnEquityStrategies) - [CnEquitySnapshotPipelines](https://github.com/QuantStrategyLab/CnEquitySnapshotPipelines) - [QuantRuntimeSettings](https://github.com/QuantStrategyLab/QuantRuntimeSettings) + +## Repository layout + +```text +application/ offline broker adapter and dry-run cycle +data/fixtures/ sample market-history and snapshot inputs +scripts/ preflight and local smoke commands +tests/ automated tests +main.py Flask HTTP entrypoint +``` + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md). Documentation follows the [QuantStrategyLab documentation style guide](https://github.com/QuantStrategyLab/.github/blob/main/docs/STYLE_GUIDE.md). + +## Security + +See [SECURITY.md](SECURITY.md) for private vulnerability reporting. Do not put credentials or account identifiers in issues, examples, or logs. + +## License + +[MIT](LICENSE). diff --git a/README.zh-CN.md b/README.zh-CN.md index cbd943d..22bd3a8 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,66 +1,131 @@ # QmtPlatform -A 股量化平台层,基于 `QuantPlatformKit` 和 `CnEquityStrategies` 构建,对接 **miniQMT / QMT**。 +[English](README.md) | 简体中文 -当前范围为**仅干跑**:评估策略目标并预览订单,不向券商提交实盘;任何 non-dry-run 请求均会返回 `blocked`,不会被报告为 `submitted`。 +面向 miniQMT / QMT 的 A 股量化平台层,基于 `QuantPlatformKit` 和 `CnEquityStrategies` 构建。 -## QSL 架构角色 +## 状态 -- **层级**:`执行平台`。 -- **职责**:QMT / miniQMT A 股执行运行时。 -- **事实源/归属**:QMT runtime 控制和 A 股平台集成。 -- **消费对象**:CnEquityStrategies、QuantPlatformKit、QuantRuntimeSettings、market-history 输入。 -- **禁止事项**:承载策略研究逻辑或发布 snapshot artifacts。 +实验性项目。当前实现离线评估策略并预览订单。本项目不构成投资建议,也不保证任何交易结果。 -## 离线 paper-admission(不是券商 paper) +## 简介 -`--paper-admission` 是确定性的本地配置门槛,不连接 miniQMT/QMT paper 账户。它必须同时满足: +QmtPlatform 提供 QMT 平台集成层。它从 `CnEquityStrategies` 加载策略配置,读取本地历史行情,并基于模拟投资组合评估目标权重。`QuantPlatformKit` 提供共享运行组件与策略契约,`QuantRuntimeSettings` 提供运行目标定义。 -- `QMT_EXECUTION_MODE=paper`; -- `QMT_DRY_RUN_ONLY=true`; -- 预先记录的 SHA-256 与固定的 `QMT_MARKET_HISTORY_PATH` 输入一致。 +## 不适用范围 -该命令只加载策略契约并计算本地输入摘要;不会调用 QMT SDK/provider、读取凭据、创建订单或读取券商账户,也不代表系统已经具备 broker-paper 或 live 能力。 - -```bash -export QMT_EXECUTION_MODE=paper -export QMT_DRY_RUN_ONLY=true -export QMT_PAPER_ADMISSION_INPUT_SHA256=5612a923290ed9fb779ce39613c5ea875ee68f69bf2aade0358761f2b86b3afb -python3 scripts/preflight_qmt_runtime.py --paper-admission -``` - -## 支持 dry-run 策略 - -| Profile | 输入模式 | -|---|---| -| `cn_industry_etf_rotation` | `market_history`(主轨,runtime_enabled) | -| `cn_industry_etf_rotation_aggressive` | `market_history`(可选目标,live_candidate) | - -`cn_dividend_quality_snapshot`、`cn_index_etf_tactical_rotation` 等 research-only profile 不会进入 QMT runtime 配置;只有在 `CnEquityStrategies` 中完成提级后才允许启用。 +本仓库不实现策略研究,也不发布快照产物。它没有 miniQMT / QMT 券商连接。离线券商适配器对非 dry-run 的订单请求返回 `blocked`,不会将其报告为 `submitted`。 ## 快速开始 +需要 Python 3.11 或更高版本及 Git。在仓库根目录运行以下命令。安装包时会使用 `pyproject.toml` 声明的依赖版本。 + ```bash python3 -m pip install -e '.[test]' +python3 -m pytest -q tests + +unset RUNTIME_TARGET_JSON export STRATEGY_PROFILE=cn_industry_etf_rotation export QMT_DRY_RUN_ONLY=true +export QMT_EXECUTION_MODE=dry_run export QMT_MARKET_HISTORY_PATH=data/fixtures/market_history.sample.csv + python3 scripts/preflight_qmt_runtime.py python3 main.py +``` + +在另一个终端查询本地服务: + +```bash curl http://127.0.0.1:8080/probe +curl http://127.0.0.1:8080/profiles +curl http://127.0.0.1:8080/dry-run +``` + +以下 smoke 脚本使用固定样本运行本地策略周期,无需启动 HTTP 服务: + +```bash +python3 scripts/smoke_cn_industry_etf_rotation_dry_run_e2e.py +python3 scripts/smoke_cn_industry_etf_rotation_aggressive_dry_run_e2e.py +``` + +## 配置 + +以 [`.env.example`](.env.example) 为 dry-run 配置参考,在 shell 中导出相应值;入口程序读取环境变量。预检命令检查所选策略及所需输入路径,不访问券商凭据。 + +| 变量 | 是否必需 | 默认值 | 用途 | +|---|---|---|---| +| `STRATEGY_PROFILE` | 未设置 `RUNTIME_TARGET_JSON` 时必需 | 无 | QMT 已启用的策略配置 ID。 | +| `QMT_DRY_RUN_ONLY` | 否 | `true` | 保持为 `true`;预检拒绝 `false`,HTTP dry-run 接口始终使用 dry-run 设置。 | +| `QMT_EXECUTION_MODE` | 否 | `dry_run` | 仅在离线 paper-admission 检查中设为 `paper`;该值不会建立券商连接。 | +| `QMT_PAPER_ADMISSION_INPUT_SHA256` | 使用 `--paper-admission` 时必需 | 无 | 预先记录的固定历史行情输入的 SHA-256 摘要。 | +| `QMT_MARKET_HISTORY_PATH` | 历史行情策略必需 | 无 | 包含 `date,symbol,close` 列的本地 CSV 路径。 | +| `RUNTIME_TARGET_JSON` | 否 | 无 | 来自 `QuantRuntimeSettings` 的 JSON 运行目标;优先于 `STRATEGY_PROFILE`。 | +| `PORT` | 否 | `8080` | HTTP 端口;Flask 入口绑定 `0.0.0.0`。 | + +## 支持的 dry-run 策略 + +| 策略配置 | 输入模式 | 用途 | +|---|---|---| +| `cn_industry_etf_rotation` | `market_history` | 主要策略。 | +| `cn_industry_etf_rotation_aggressive` | `market_history` | 可选策略,目标波动率为 25%。 | + +未设置 `RUNTIME_TARGET_JSON` 时,可通过 `STRATEGY_PROFILE=cn_industry_etf_rotation_aggressive` 选择可选策略。运行目标示例见 [QuantRuntimeSettings](https://github.com/QuantStrategyLab/QuantRuntimeSettings/blob/main/examples/targets/qmt/industry_etf_aggressive_dry_run.example.json)。 + +可用策略由 `CnEquityStrategies` 的策略目录和 QMT 启用清单决定。QMT 运行配置不接受 `cn_dividend_quality_snapshot`、`cn_index_etf_tactical_rotation` 等仅供研究的策略配置。 + +## 离线 paper-admission 检查 + +`--paper-admission` 检查本地配置和固定输入文件。它要求 `QMT_EXECUTION_MODE=paper`、`QMT_DRY_RUN_ONLY=true`,且预先记录的 SHA-256 摘要与 `QMT_MARKET_HISTORY_PATH` 一致。 + +配置策略和输入路径后,将 `` 替换为预先记录的摘要: + +```bash +export QMT_EXECUTION_MODE=paper +export QMT_DRY_RUN_ONLY=true +export QMT_PAPER_ADMISSION_INPUT_SHA256='' +python3 scripts/preflight_qmt_runtime.py --paper-admission ``` -`.env.example` 是当前 dry-run 配置模板;preflight 只校验 profile 与输入文件路径,不读取或写入账号、密码、token。 +该命令加载策略契约并计算本地输入摘要,不调用 QMT SDK 或服务提供方,不读取凭据、创建订单或评估券商账户。这里的 `paper` 表示离线检查,不代表券商模拟交易连接。 ## 已停用目标的生命周期验证 -QMT 当前没有配置券商运行面或实盘凭据。工作日定时的 `Runtime Target Lifecycle` 只运行确定性预检和基于 -固定样本行情的 dry-run smoke,然后向统一管理端发布脱敏的 `disabled` / `dry_run` 状态。dry-run 已完成、 -但被确定性风控拦截为空权重,也属于通过:平台与安全边界都在正常工作。它不表示 QMT 已部署、已连接 miniQMT、 -已启用 paper 或实盘。预检或 dry-run 真正失败才会发布为 `attention`;任何状态都不能改变目标开关或提交订单。 +工作日运行的 `Runtime Target Lifecycle` 工作流为固定的已停用目标执行确定性预检和基于样本的 dry-run,并发布 `disabled` / `dry_run` 状态。若周期已完成,但风控检查使目标权重为空,视为成功完成无订单检查;预检或 dry-run 失败则报告为 `attention`。这些报告不会修改目标设置、建立券商连接或提交订单。 + +## HTTP 接口 + +| 方法 | 路径 | 响应 | +|---|---|---| +| `GET` | `/probe` | 健康状态、当前策略和 dry-run 设置。 | +| `GET` | `/profiles` | 平台策略配置矩阵。 | +| `GET`、`POST` | `/dry-run` | 基于本地输入计算的策略目标权重和订单预览。 | + +## 相关仓库 + +- [QuantPlatformKit](https://github.com/QuantStrategyLab/QuantPlatformKit) +- [CnEquityStrategies](https://github.com/QuantStrategyLab/CnEquityStrategies) +- [CnEquitySnapshotPipelines](https://github.com/QuantStrategyLab/CnEquitySnapshotPipelines) +- [QuantRuntimeSettings](https://github.com/QuantStrategyLab/QuantRuntimeSettings) + +## 仓库结构 + +```text +application/ 离线券商适配器和 dry-run 周期 +data/fixtures/ 历史行情和快照样本输入 +scripts/ 预检和本地 smoke 命令 +tests/ 自动化测试 +main.py Flask HTTP 入口 +``` + +## 参与贡献 + +见 [CONTRIBUTING.md](CONTRIBUTING.md)。文档遵循 [QuantStrategyLab 文档风格指南](https://github.com/QuantStrategyLab/.github/blob/main/docs/STYLE_GUIDE.md)。 + +## 安全 -详见 [README.md](README.md)(英文)。 +私下报告安全漏洞的方法见 [SECURITY.md](SECURITY.md)。请勿在 issue、示例或日志中填写凭据或账户标识。 ## 许可证 -详见 [LICENSE](LICENSE)。 +[MIT](LICENSE)。