| name | ashare-sop-l3-stock-resonance |
| description | L3 stock resonance & risk control engine for the A-share SOP. Use to score individual stocks against buy/sell rules, apply theme state gates, and output 候选观察 or 风控观察 alerts with cooling mechanism. |
| version | 1.1.0 |
| author | Hermes Agent |
| license | MIT |
| metadata | {"hermes":{"tags":["a-share","sop","stock-scoring","risk-control","l3","buy-sell-rules"],"related_skills":["a-share-theme-structure-sop","ashare-sop-l2-theme-engine","ashare-sop-l4-execution-review"]}} |
A-Share SOP L3 — Stock Resonance & Risk Control Engine
Overview
This is the L3 tier of the A-share theme structure SOP engine (v1.7+). Within the theme context from L2, it screens individual stocks using explicit buy/sell scoring rules with numerical thresholds, applies theme-state gates, and outputs "候选观察" or "风控观察" alerts.
Precondition: L2 state must NOT be 退潮期 (all candidates blocked). If L2=分歧/分化期, core pool requires buy_score ≥ 3.
Load this skill when screening individual stocks or building intraday alerts — with L2 context loaded.
Engine Position
L1 (宏观环境) → L2 (题材/阶段/池) → L3 (本模块: 个股打分/风控) → feeds → L4 (执行复盘)
Stock Pool Hierarchy (from L2)
L3 operates on 3 layers per active theme:
| Pool | Description |
|---|
| 核心股池 (Core) | Top 3 by turnover, highest consecutive boards, or market-recognized leaders |
| 分支/补涨股池 (Branch/Laggard) | Medium turnover; technical pattern shows "回踩趋势" or "密集区突破" |
| 风险风向标 (Risk Anchor) | High-volatility names strongly correlated with the theme, or names with huge prior gains |
Theme State Gating
| L2 State | Core Pool | Branch/Laggard Pool |
|---|
| 退潮期 | 清空所有候选, 强制风控观察 | Same — no buy candidates |
| 分歧/分化期 | buy_score ≥ 3 | Normal rules |
| 启动/发酵期 or 高潮/主升期 | Normal rules | Normal rules |
Buy Candidate Rules (buy_score)
Each satisfied rule increments buy_score by 1:
| # | Rule | Condition |
|---|
| 1 | 突破20日高点且放量 | current_price > 20D_high × 1.002 AND est_turnover / 5D_avg_turnover ≥ 1.25 |
| 2 | 重新站上5日线并放量 | current_price > MA5 AND prev_close < prev_MA5 AND est_turnover / 5D_avg_turnover ≥ 1.10 |
| 3 | 价格位于5/10日线上方且走强 | current_price > MA5 > MA10 AND intraday_change ≥ +0.8% |
| 4 | 异常放量上行 | est_turnover / 20D_avg_turnover ≥ 1.8 AND intraday_change > 0 |
| 5 | 刷新20日高点 | current_price ≥ 20D_high |
Output Condition
Must satisfy BOTH:
buy_score ≥ 2
buy_score ≥ sell_score + 1 (more buy reasons than sell reasons)
→ Output: 候选观察
Risk Control Rules (sell_score)
Each satisfied rule increments sell_score by 1:
| # | Rule | Condition |
|---|
| 1 | 跌破10日低点且放量 | current_price < 10D_low × 0.998 AND est_turnover / 5D_avg_turnover ≥ 1.20 |
| 2 | 跌破5日线且跌幅扩大 | current_price < MA5 AND intraday_change ≤ -1.5% |
| 3 | 相对昨收回撤超3% | intraday_change ≤ -3.0% |
| 4 | 异常放量下行 | est_turnover / 20D_avg_turnover ≥ 1.8 AND intraday_change < -1.0% |
Output Condition
sell_score ≥ 2 → Output: 风控观察
Cooling Mechanism
- Per stock, same direction (buy candidate / risk alert): minimum 20-minute cooldown between alerts.
- This prevents signal flooding during volatile consolidation periods.
- Apply at the notification layer (intraday monitor, Discord alerts, cron outputs).
Data Sources for L3 Computation
python3 /Users/gordon8018/.hermes/scripts/sop_enrich.py --codes sh600584,sz300750
npx -y westock-data-skillhub@1.0.3 asfund <codes>
python3 /Users/gordon8018/.hermes/scripts/td_kline_fetcher.py --codes <codes> --days 120
Implementation Status
The buy_score/sell_score rules are validated against 2026 H1 TDengine K-line data. See references/backtest-2026h1-findings.md for full results.
- ✅ Factor scoring:
factor_scorer.py v1.2 computes a different 5-factor scorecard (板块宽度/个股承接/量能健康/席位/资金/风险扣分) from KDJ/WR/BOLL, ATR, MainNetFlow, 龙虎榜 seats, 北向资金, 250D position
- ✅ K-line indicators:
sop_enrich.py computes MA5/MA10/MA20, 20D high/low, 10D low from TDengine K-line data
- ✅ L3 buy_score/sell_score backtest:
scripts/backtest_l3_rules.py validates all 9 rules against 2026 H1 daily K-line (6,839 stocks, 119 trading days). Signals show statistically significant positive excess returns across all horizons (D1–D20, t > 4.9). Critical findings documented below.
- ✅ Cooling: Must be enforced at the intraday monitor / notification layer
When building the L3 scorer:
- Use
sop_enrich.py for MA5/MA10/MA20 and 20D/10D high/low
- Use
westock-data asfund or tick-based estimates for turnover ratios
- Use TDengine
stock.kline for the 120-day lookback window
- Integrate with existing cron pipeline: consume L2
hypothesis_queue → score → append to pool output
Backtest Validation (2026 H1)
Full backtest script: scripts/backtest_l3_rules.py. Key findings from 2026-01–2026-07 (63 signal days):
| Metric | D1 | D3 | D5 | D10 |
|---|
| Signal mean | +0.10% | +0.41% | +0.42% | +1.22% |
| Signal median | -0.35% | -0.32% | -0.59% | -0.20% |
| Win rate | 45.3% | 47.0% | 46.4% | 48.9% |
| Universe mean | -0.04% | -0.03% | -0.16% | -0.48% |
| Excess (α) | +0.14% | +0.44% | +0.58% | +1.71% |
| t vs random | +4.95 | +8.59 | +8.37 | +16.27 |
buy_score gradient (validated)
| buy_score | N | D1 | D3 | D5 |
|---|
| 2 | 18,454 | +0.06% | +0.34% | +0.37% |
| 3 | 3,249 | +0.22% | +0.66% | +0.59% |
| 4 | 216 | +1.40% | +2.08% | +2.21% |
Rule effectiveness (which rules actually fire)
| Rule | Universe trigger rate | In signals |
|---|
| R1: 突破20D高且放量 | 0.00% 🔴 | 0.0% |
| R2: 重站5日线且放量 | 6.49% | 43.9% |
| R3: 5/10线上方走强 | 15.36% | 89.7% |
| R4: 异常放量上行 | 5.04% | 66.4% |
| R5: 刷新20D高点 | 1.04% | 16.7% |
Limit-up dependency (critical)
Limit-up stocks (day change ≥ 9.5%) account for 22.3% of signals but drive nearly all alpha:
- Limit-up signals: D1=+1.03%, D10=+2.92%
- Non-limit-up signals: D1=-0.16%, D10=+0.74%
Without the limit-up tail, L3 signals have no edge at D1/D3. The strategy functions as a limit-up continuation screener in practice.
Standard Output Format
## L3 个股打分
| 标的 | 角色 | buy_score | sell_score | 净分 | 输出 |
|------|------|:---------:|:----------:|:----:|------|
| XX股 | 核心 | 3 | 0 | +3 | 候选观察 ✅ |
| YY股 | 分支 | 2 | 1 | +1 | 候选观察 ✅ |
| ZZ股 | 核心 | 1 | 2 | -1 | — |
| WW股 | 风险 | 0 | 3 | -3 | 风控观察 ⚠️ |
## L3 输出汇总
- 候选观察:X 只
- 风控观察:Y 只
- 冷却中:Z 只
Common Pitfalls
- Not gating by L2 state: Never output buy candidates when L2=退潮期, regardless of individual scores.
- Not applying cooling: A volatile stock in consolidation can produce rapid alternating buy/sell signals. 20-min cooldown is mandatory. Backtest confirms: days with >500 signals showed consistently poor D1 returns (6/8 negative).
- Computing MA values intraday: MA5/MA10 use daily closes. For intraday rules, estimate current MA with today's current price replacing today's close.
- Using stale turnover estimates: "预计全天成交额" should use intraday tick volume extrapolation. Don't use yesterday's full-day turnover as today's estimate.
- Missing the buy_score ≥ sell_score + 1 condition: A stock with buy_score=2 and sell_score=2 should NOT output 候选观察 — the signals cancel out.
- R1 (突破20D高且放量) is DEAD: The condition
close > 20D_high × 1.002 AND volume ≥ 1.25×5D_avg fired ZERO times in 2026 H1 across 6,839 stocks. In A-shares with ±10% daily limits, exceeding 20D_high by 0.2% while maintaining heavy volume is structurally impossible outside of limit-up gaps. Consider replacing with close ≥ 20D_high × 0.995 or removing R1 entirely.
- Limit-up dependency: 22.3% of signals are limit-up stocks (day change ≥ 9.5%), and they drive nearly all alpha. Non-limit-up signals have D1 = -0.16% → essentially noise. This means the L3 rules function as a limit-up continuation screener in practice — not as a general momentum/breakout detector. Do not interpret L3 signals as standalone buy candidates outside the limit-up context.
- Highly right-skewed returns: Mean returns are positive but median returns are negative at every horizon. The strategy relies on a few large winners (~10% of signals) to offset many small losers. This makes stop-loss discipline absolutely critical — without it, the strategy will bleed out.
- Signal concentration is a red flag: Days with >500 signals (top 12% of days by signal count) showed poor D1 returns (6/8 negative). High signal count = indiscriminate triggering. Prefer days with focused, high-quality signals.
- Market regime matters less than expected: Signals on down-market days actually performed better at D1/D3 (mean-reversion), while up-market signals performed better at D10+ (trend continuation). L1 gating to "多头趋势 only" may hurt short-term returns.