Skip to content

Commit fac2a46

Browse files
authored
Merge branch 'main' into agent/enable-dependabot-automation
2 parents ad417ba + 6f8e03f commit fac2a46

24 files changed

Lines changed: 993 additions & 342 deletions

.env.example

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,3 @@ STRATEGY_PROFILE=cn_industry_etf_rotation
33
ACCOUNT_PREFIX=QMT
44
ACCOUNT_REGION=CN
55
QMT_MARKET_HISTORY_PATH=data/fixtures/market_history.sample.csv
6-
QMT_FEATURE_SNAPSHOT_PATH=data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv
7-
QMT_FEATURE_SNAPSHOT_MANIFEST_PATH=data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv.manifest.json

.github/workflows/ci.yml

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,39 +20,14 @@ jobs:
2020
id: quant-platform-kit-ref
2121
run: |
2222
set -euo pipefail
23-
ref="main"
24-
for candidate in "${GITHUB_HEAD_REF:-}" "${GITHUB_BASE_REF:-}"; do
25-
if [ -n "$candidate" ] && git ls-remote --exit-code --heads https://github.com/QuantStrategyLab/QuantPlatformKit.git "$candidate" >/dev/null 2>&1; then
26-
ref="$candidate"
27-
break
28-
fi
29-
done
23+
ref="$(grep -Eo 'QuantPlatformKit\.git@[0-9a-f]+' pyproject.toml | head -n1 | sed 's/.*@//')"
3024
echo "ref=${ref}" >> "$GITHUB_OUTPUT"
3125
3226
- name: Resolve CnEquityStrategies ref
3327
id: cn-equity-strategies-ref
3428
run: |
3529
set -euo pipefail
36-
ref="main"
37-
for candidate in "${GITHUB_HEAD_REF:-}" "${GITHUB_BASE_REF:-}"; do
38-
if [ -n "$candidate" ] && git ls-remote --exit-code --heads https://github.com/QuantStrategyLab/CnEquityStrategies.git "$candidate" >/dev/null 2>&1; then
39-
ref="$candidate"
40-
break
41-
fi
42-
done
43-
echo "ref=${ref}" >> "$GITHUB_OUTPUT"
44-
45-
- name: Resolve CnEquitySnapshotPipelines ref
46-
id: cn-equity-snapshot-pipelines-ref
47-
run: |
48-
set -euo pipefail
49-
ref="main"
50-
for candidate in "${GITHUB_HEAD_REF:-}" "${GITHUB_BASE_REF:-}"; do
51-
if [ -n "$candidate" ] && git ls-remote --exit-code --heads https://github.com/QuantStrategyLab/CnEquitySnapshotPipelines.git "$candidate" >/dev/null 2>&1; then
52-
ref="$candidate"
53-
break
54-
fi
55-
done
30+
ref="$(grep -Eo 'CnEquityStrategies\.git@[0-9a-f]+' pyproject.toml | head -n1 | sed 's/.*@//')"
5631
echo "ref=${ref}" >> "$GITHUB_OUTPUT"
5732
5833
- name: Checkout QuantPlatformKit
@@ -69,13 +44,6 @@ jobs:
6944
ref: ${{ steps.cn-equity-strategies-ref.outputs.ref }}
7045
path: external/CnEquityStrategies
7146

72-
- name: Checkout CnEquitySnapshotPipelines
73-
uses: actions/checkout@v6
74-
with:
75-
repository: QuantStrategyLab/CnEquitySnapshotPipelines
76-
ref: ${{ steps.cn-equity-snapshot-pipelines-ref.outputs.ref }}
77-
path: external/CnEquitySnapshotPipelines
78-
7947
- name: Setup Python
8048
uses: actions/setup-python@v6
8149
with:
@@ -86,7 +54,7 @@ jobs:
8654
set -euo pipefail
8755
python -m pip install --upgrade pip
8856
python -m pip install -e '.[test]' ruff
89-
python -m pip install --no-deps -e external/QuantPlatformKit -e external/CnEquityStrategies -e external/CnEquitySnapshotPipelines
57+
python -m pip install --no-deps -e external/QuantPlatformKit -e external/CnEquityStrategies
9058
9159
- name: Run ruff
9260
run: python -m ruff check . --extend-exclude external
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Codex PR Review
2+
3+
on:
4+
pull_request_target:
5+
types: [opened, synchronize, reopened]
6+
7+
permissions:
8+
contents: read
9+
id-token: write
10+
issues: write
11+
pull-requests: write
12+
13+
concurrency:
14+
group: codex-pr-review-${{ github.event.pull_request.number }}
15+
cancel-in-progress: true
16+
17+
jobs:
18+
review:
19+
uses: QuantStrategyLab/AIAuditBridge/.github/workflows/codex_pr_review.yml@main
20+
with:
21+
caller_concurrency_key: pr-${{ github.event.pull_request.number || github.run_id }}
22+
allow_unconfigured_backend: false
23+
api_fallback_enabled: "false"
24+
direct_api_primary_enabled: "false"
25+
secrets:
26+
CODEX_AUDIT_SERVICE_URL: ${{ secrets.CODEX_AUDIT_SERVICE_URL }}
27+
permissions:
28+
contents: read
29+
id-token: write
30+
issues: write
31+
pull-requests: write

.github/workflows/codex_review_gate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ permissions:
2323
pull-requests: read
2424

2525
concurrency:
26-
group: codex-review-gate-${{ github.event.pull_request.number }}
26+
group: codex-review-gate-${{ github.event.pull_request.number }}-${{ github.event_name }}
2727
cancel-in-progress: true
2828

2929
jobs:

README.md

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
# QmtPlatform
22

3+
4+
## QSL architecture role
5+
6+
- **Layer**: `runtime-platform`.
7+
- **Responsibility**: QMT / miniQMT A-share execution runtime.
8+
- **Owns**: QMT runtime controls and A-share platform integration.
9+
- **Consumes**: CnEquityStrategies, QuantPlatformKit, QuantRuntimeSettings, market-history inputs.
10+
- **Must not**: own strategy research logic or publish snapshot artifacts.
11+
312
A-share quant platform layer for **miniQMT / QMT**, built on `QuantPlatformKit` and `CnEquityStrategies`.
413

514
Current scope is **dry-run first**: evaluate strategy targets and preview orders without submitting to the broker.
615

7-
## Supported profiles (P0)
16+
## Supported dry-run profiles
817

918
| Profile | Input mode |
1019
|---|---|
1120
| `cn_industry_etf_rotation` | `market_history` (**主轨,runtime_enabled**) |
12-
| `cn_industry_etf_rotation_aggressive` | `market_history` (**optional target,vol25%**) |
13-
| `cn_dividend_quality_snapshot` | `feature_snapshot` (requires snapshot path) |
14-
| `cn_index_etf_tactical_rotation` | `market_history` (legacy / research_backtest_only) |
21+
| `cn_industry_etf_rotation_aggressive` | `market_history` (**optional target,live_candidate**) |
22+
23+
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`.
1524

1625
## Quick start
1726

@@ -25,6 +34,7 @@ export STRATEGY_PROFILE=cn_industry_etf_rotation
2534
export QMT_DRY_RUN_ONLY=true
2635
export QMT_MARKET_HISTORY_PATH=data/fixtures/market_history.sample.csv
2736

37+
python3 scripts/preflight_qmt_runtime.py
2838
python3 main.py
2939
curl http://127.0.0.1:8080/probe
3040
curl http://127.0.0.1:8080/dry-run
@@ -43,35 +53,9 @@ curl http://127.0.0.1:8080/dry-run
4353

4454
Runtime target example: `QuantRuntimeSettings/examples/targets/qmt/industry_etf_aggressive_dry_run.example.json`
4555

46-
### Legacy index ETF tactical rotation (research only)
47-
48-
```bash
49-
export STRATEGY_PROFILE=cn_index_etf_tactical_rotation
50-
export QMT_MARKET_HISTORY_PATH=data/fixtures/market_history.sample.csv
51-
python3 main.py
52-
```
53-
54-
### Dividend quality snapshot (feature snapshot)
55-
56-
```bash
57-
python3 -m pip install --no-deps -e ../CnEquitySnapshotPipelines
58-
59-
# Regenerate fixtures (uses sample factor CSV; sets as_of to today)
60-
python3 scripts/build_fixtures.py
61-
62-
export STRATEGY_PROFILE=cn_dividend_quality_snapshot
63-
export QMT_DRY_RUN_ONLY=true
64-
export QMT_FEATURE_SNAPSHOT_PATH=data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv
65-
export QMT_FEATURE_SNAPSHOT_MANIFEST_PATH=data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv.manifest.json
66-
67-
python3 main.py
68-
curl http://127.0.0.1:8080/dry-run
69-
```
70-
7156
End-to-end smoke (stage/build/run):
7257

7358
```bash
74-
python3 scripts/smoke_cn_dividend_quality_dry_run_e2e.py
7559
python3 scripts/smoke_cn_industry_etf_rotation_dry_run_e2e.py
7660
python3 scripts/smoke_cn_industry_etf_rotation_aggressive_dry_run_e2e.py
7761
```
@@ -81,13 +65,11 @@ python3 scripts/smoke_cn_industry_etf_rotation_aggressive_dry_run_e2e.py
8165
| Variable | Default | Description |
8266
|---|---|---|
8367
| `QMT_DRY_RUN_ONLY` | `true` | When true, never submit live orders |
84-
| `STRATEGY_PROFILE` | required | Strategy profile id |
68+
| `STRATEGY_PROFILE` | required | QMT-enabled strategy profile id |
8569
| `QMT_MARKET_HISTORY_PATH` || CSV with `date,symbol,close` for direct strategies |
86-
| `QMT_FEATURE_SNAPSHOT_PATH` || Snapshot CSV for feature-snapshot strategies |
87-
| `QMT_FEATURE_SNAPSHOT_MANIFEST_PATH` || Snapshot manifest JSON (required for dividend quality) |
8870
| `RUNTIME_TARGET_JSON` || Optional runtime target override from QuantRuntimeSettings |
8971

90-
See `.env.example` and `CnEquityStrategies/docs/platform_integration.md`.
72+
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.
9173

9274
## HTTP endpoints
9375

README.zh-CN.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,41 @@
11
# QmtPlatform
22

3+
4+
## QSL 架构角色
5+
6+
- **层级**`执行平台`
7+
- **职责**:QMT / miniQMT A 股执行运行时。
8+
- **事实源/归属**:QMT runtime 控制和 A 股平台集成。
9+
- **消费对象**:CnEquityStrategies、QuantPlatformKit、QuantRuntimeSettings、market-history 输入。
10+
- **禁止事项**:承载策略研究逻辑或发布 snapshot artifacts。
11+
312
A 股量化平台层,基于 `QuantPlatformKit``CnEquityStrategies` 构建,对接 **miniQMT / QMT**
413

514
当前范围为**仅干跑**:评估策略目标并预览订单,不向券商提交实盘。
615

7-
## 支持策略
16+
## 支持 dry-run 策略
817

918
| Profile | 输入模式 |
1019
|---|---|
1120
| `cn_industry_etf_rotation` | `market_history`(主轨,runtime_enabled) |
12-
| `cn_industry_etf_rotation_aggressive` | `market_history`(可选目标,vol25%|
13-
| `cn_dividend_quality_snapshot` | `feature_snapshot`(需快照路径) |
14-
| `cn_index_etf_tactical_rotation` | `market_history`(旧版/research_backtest_only) |
21+
| `cn_industry_etf_rotation_aggressive` | `market_history`(可选目标,live_candidate|
22+
23+
`cn_dividend_quality_snapshot``cn_index_etf_tactical_rotation` 等 research-only profile 不会进入 QMT runtime 配置;只有在 `CnEquityStrategies` 中完成提级后才允许启用。
1524

1625
## 快速开始
1726

1827
```bash
1928
python3 -m pip install -e '.[test]'
2029
export STRATEGY_PROFILE=cn_industry_etf_rotation
2130
export QMT_DRY_RUN_ONLY=true
31+
export QMT_MARKET_HISTORY_PATH=data/fixtures/market_history.sample.csv
32+
python3 scripts/preflight_qmt_runtime.py
2233
python3 main.py
2334
curl http://127.0.0.1:8080/probe
2435
```
2536

37+
`.env.example` 是当前 dry-run 配置模板;preflight 只校验 profile 与输入文件路径,不读取或写入账号、密码、token。
38+
2639
详见 [README.md](README.md)(英文)。
2740

2841
## 许可证

data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv.manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"manifest_type": "feature_snapshot",
88
"row_count": 4,
99
"snapshot_as_of": "2026-06-27",
10-
"snapshot_path": "/Users/lisiyi/Projects/QmtPlatform/data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv",
10+
"snapshot_path": "data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv",
1111
"snapshot_sha256": "ba00a43b18ca204a53f6f657774b2964bc196a6727f329d0f9dd242f36d1cedd",
1212
"source_project": "CnEquitySnapshotPipelines",
1313
"strategy_profile": "cn_dividend_quality_snapshot"

data/fixtures/dividend_quality/release_status_summary.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@
3232
},
3333
"display_name": "CN Dividend Quality Snapshot",
3434
"generated_at": "2026-06-27T16:20:38.124005+00:00",
35-
"manifest_path": "/Users/lisiyi/Projects/QmtPlatform/data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv.manifest.json",
36-
"ranking_path": "/Users/lisiyi/Projects/QmtPlatform/data/fixtures/dividend_quality/cn_dividend_quality_snapshot_ranking_latest.csv",
35+
"manifest_path": "data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv.manifest.json",
36+
"ranking_path": "data/fixtures/dividend_quality/cn_dividend_quality_snapshot_ranking_latest.csv",
3737
"release_status": "ready",
3838
"row_count": 4,
3939
"signal_description": "cn dividend quality regime=risk_on breadth=100.0% target_stock=100.0% selected=3 top=601088(0.44), 600519(0.11), 000001(-0.55)",
4040
"snapshot_as_of": "2026-06-27",
41-
"snapshot_path": "/Users/lisiyi/Projects/QmtPlatform/data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv",
41+
"snapshot_path": "data/fixtures/dividend_quality/cn_dividend_quality_snapshot_factor_snapshot_latest.csv",
4242
"source_project": "CnEquitySnapshotPipelines",
4343
"status_description": "regime=risk_on | breadth=100.0% | target_stock=100.0%",
4444
"strategy_profile": "cn_dividend_quality_snapshot"

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ authors = [{ name = "QuantStrategyLab" }]
1313
dependencies = [
1414
"flask>=3.0",
1515
"pandas>=2.0",
16-
"quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@e86554b",
17-
"cn-equity-strategies @ git+https://github.com/QuantStrategyLab/CnEquityStrategies.git@357dba7e8896a7f488a484d4a3eea33894708ab9",
16+
"quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@69a0256934d081b5ef309a885384b9eb9f62cf90",
17+
"cn-equity-strategies @ git+https://github.com/QuantStrategyLab/CnEquityStrategies.git@12c0cd4801060fcb2f9452ffd9a7f48df446ddd0",
1818
]
1919

2020
[project.optional-dependencies]
@@ -23,6 +23,7 @@ test = ["pytest>=8"]
2323
[tool.setuptools]
2424
py-modules = [
2525
"main",
26+
"runtime_preflight",
2627
"runtime_config_support",
2728
"strategy_loader",
2829
"strategy_registry",

qsl.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[qsl]
2+
repo = "QmtPlatform"
3+
tier = "runtime"
4+
upgrade_ring = "ring_d"
5+
allow_legacy = false
6+
enforce_bundle = true
7+
8+
[qsl.requires]
9+
quant_platform_kit = "69a0256934d081b5ef309a885384b9eb9f62cf90"
10+
cn_equity_strategies = "12c0cd4801060fcb2f9452ffd9a7f48df446ddd0"
11+
12+
[qsl.compat]
13+
bundle = "2026.07.3"

0 commit comments

Comments
 (0)