Skip to content
All strategies

Strategies

SuperMind 反包 Screen on A-Share Large Caps: Close Re-Crosses Above MA20 While MA20 > MA120 Within 10 Sessions of a Five-MA Squeeze (32 pre-2016 CNEQ large caps, 1-DAY, long-only, next-open fills, 15-session clock + 8% stop)

Outcome: Abandoned

SuperMindFanbaoMaSqueezeCneqPanel

Outcome Summary

The Research Lead turned a SuperMind A-share 反包 screen (an MA20 re-cross in an MA20 > MA120 uptrend after a five-MA squeeze) into a long-only test on 32 CNEQ large caps with standard exits and sizing. After a sizing fix in iteration 1, the backtest review sent it to optimization despite a thin edge and a large shortfall against the equal-weight basket. Optimization lifted per-trade returns to 0.62% with a 10.2% drawdown, but walk-forward OOS Sharpe was only 0.20, results swung across windows and years, and the strategy was positive in just 4 of 9 calendar years. The analyst abandoned it after 2 iterations on that hard year-consistency failure, and it never reached risk review or paper trading.

Hypothesis

Derived by the Research Lead from 同花顺 SuperMind / 神盾局量子研究部, '(iwencai量化)反包_、20日均线大于120日均线、至少5根均线重合的股票' (https://quant.10jqka.com.cn/view/article/28986, sections '最终的选股逻辑' and 'python代码参考'): the source gives three screen conditions and no exits, sizing or universe, so this is a distilled test, not the author's strategy. KEPT FROM THE SOURCE: (1) SMA20 > SMA120 (short trend leads the long trend); (2) 'at least 5 moving averages coincide'; (3) 反包 = after a short pullback the stock rises again, which the source code……Show moreShow less

Derived by the Research Lead from 同花顺 SuperMind / 神盾局量子研究部, '(iwencai量化)反包_、20日均线大于120日均线、至少5根均线重合的股票' (https://quant.10jqka.com.cn/view/article/28986, sections '最终的选股逻辑' and 'python代码参考'): the source gives three screen conditions and no exits, sizing or universe, so this is a distilled test, not the author's strategy. KEPT FROM THE SOURCE: (1) SMA20 > SMA120 (short trend leads the long trend); (2) 'at least 5 moving averages coincide'; (3) 反包 = after a short pullback the stock rises again, which the source code defines as close[-1] > MA20[-1] and close[-2] < MA20[-2]. Source defaults 20/120 are the baseline. CORRECTED/CHOSEN BY THE RESEARCH LEAD: the source code's 'coincidence' test counts bars where float MA20 == MA120 exactly, which almost never fires and contradicts condition (1); we use the standard 均线粘合 reading with the five MAs the article itself suggests adding (5,10,20,30,60 simple MAs): the squeeze holds on a session when (max - min of the five SMAs) / close <= squeeze_band (baseline 3%), and it must have held on at least one of the last squeeze_window (baseline 10) sessions including the signal day. Exits (15-session clock, regime exit, 8% protective stop), sizing and the universe are our standard choices. The source's iwencai '市值小于100亿' line is a template placeholder with no market data link here and is not used; its QR-code image (S2) failed to load and was not read. Market: the source screens Chinese A-shares, so the test runs on CNEQ (SSE/SZSE, CASH, long-only, ~0.05%/side blended incl. sell-side stamp duty, 2 bp half spread, data from 2018-01). UNIVERSE (fixed before any return was looked at): the 32 largest names in config/cn_equities_universe.txt that were listed before 2016 and have bars from 2018-01: 600519, 601318, 600036, 601398, 601939, 601988, 601288, 600000, 600016, 601166, 601328, 600030, 601688, 601601, 601628, 600276, 600887, 000858, 000568, 000333, 000651, 600690, 002415, 002475, 002594, 601012, 601899, 600309, 600585, 600900, 000063, 002230 (all .CNEQ). SURVIVORSHIP CAVEAT: the platform holds no point-in-time CSI index membership for CNEQ, so this basket is chosen from today's large caps; the bias is limited by requiring pre-2016 listings (no post-sample IPOs) but not removed, and the analyst should compare against an equal-weight buy-and-hold of the same 32 names over the same window. Prior art differs: the abandoned SuperMind '60开头/KDJ金叉/五均线收敛' run tested 5 stocks with a KDJ trigger and KDJ exit (61 trades); this uses the MA20 re-cross trigger, the MA20>MA120 regime and a 32-name panel for an adequate sample. Execution: decisions on the daily close; market orders fill at the next session's open (next_open_fill, supported). 100-share board lots (A-share rule; entries round down). The 8% protective stop is a submit_stop_order on the session venue (stop_order_session_venue, supported): it rests from the next open and a gap through it fills at the open. Known modeling gaps: T+1 is respected by construction (no same-day exits), the ±10% daily price limit is not enforced by the engine.

premise_falsified: The failed gate is the enforced year-consistency floor. With the final parameters (squeeze_band 0.031, hold_sessions 11), the strategy was positive in only 4 of 9 calendar years (44% vs 60%). That is a hard failure, so neither promotion nor labelled paper observation is allowed. Fees are not the cause: the average trade is 0.62% against the 0.15% CNEQ floor, PF is 1.37 over 421 trades, and drawdown is 10.2% against the pre-registered 25%. The edge is weak and does not persist. Pooled……Show moreShow less

premise_falsified: The failed gate is the enforced year-consistency floor. With the final parameters (squeeze_band 0.031, hold_sessions 11), the strategy was positive in only 4 of 9 calendar years (44% vs 60%). That is a hard failure, so neither promotion nor labelled paper observation is allowed. Fees are not the cause: the average trade is 0.62% against the 0.15% CNEQ floor, PF is 1.37 over 421 trades, and drawdown is 10.2% against the pre-registered 25%. The edge is weak and does not persist. Pooled walk-forward OOS Sharpe is 0.20 (t 0.42 vs a hurdle of 2.54). Only 6 of 12 outer windows were positive, swinging between -3.7 and +4.0, and the inner PBO was mostly above 0.6. 2024 alone carries 54% of the profit, and the walk-forward's choice of squeeze band kept moving (unstable). The holdout (2025-26, 91 trades, Sharpe 0.95) is consistent with the OOS but not significant. Against the equal-weight basket of the same names, alpha was about 0 and the information ratio -0.35, and the executed-signal IC was -0.01 (noise). I see no specific change that would make the years consistent without refitting the same history, and each rewrite would raise the lineage hurdle. Insufficient significance alone is not the reason for this verdict. It covers the Research Lead's distilled MA20 re-cross plus five-MA squeeze test on 32 CNEQ large caps, not the source author's screen, which specified no exits, sizing or universe.

Implementation

Unchanged 32-stock CNEQ daily MA re-cross/squeeze panel with next-open entries, 15-session/regime exits and 8% protective stops. Entry caps now use each stock’s own bar and quantities are rounded down to 100-share lots after capping.

Sizing-only implementation fix: the previous call supplied the expensive primary stock’s bar to every leg. _affordable_size uses max(supplied bar close, cached leg prices), incorrectly applying that primary price to cheaper names and creating similarly small odd-lot quantities. No candidate-count division appears in the cap; get_equity_mtm remains unchanged. Log equity, raw shares, cash-capped shares, margin-capped shares, final board lots and entry_diag per entry. All rules and previous_config values are preserved. No rerun was performed: average entry exposure, peak gross exposure and the equal-weight 32-name buy-and-hold comparison over the identical development window remain for the pipeline rerun; no benchmark result is claimed.

Verification Results

Optionally delay arming the stop until the first session close after the fill, so the stop is live from the following open. For example, place it in calculate_signal once _sessions_since(buf, pos.ts_opened) >= 1.

on_position_opened places the 8% reduce-only STOP_MARKET as soon as the next-open entry fills. If the engine matches that stop against the rest of the entry session's bar, the stop can close the position on the day it was bought. A-share T+1 forbids that, and the hypothesis says T+1 is respected by construction and that the stop rests from the next open. The trigger is 8% below the fill, so the stop is never crossed when placed. This only matters on an intraday drop of 8% or more on the entry day, and the ±10% price limit makes that rare.

No change required. Keep emulation_trigger unset.

The hypothesis names submit_stop_order. That helper only handles the primary instrument, so the code uses a raw order_factory.stop_market on each leg. That is an acceptable equivalent: the stop is reduce-only, uses GTC, has no emulation_trigger, is not crossed at placement, and is cancelled in on_position_closed. Whether a session that opens through the trigger fills at the open depends on the engine's session-stop setting (SF_SESSION_STOP_FILLS), not on this code.

Optional: no change needed for correctness.

When one name exits and another enters on the same close, the new entry is capped by cash before the exit proceeds settle at the next open. The new entry can therefore come out smaller than 12.5% of equity, or be skipped. This is a conservative under-deployment, not a correctness bug.

Keep it, as long as the base only uses it as a warm-up count.

min_bars_required() overrides the framework method; Layer 1 flags this as base_shadow. The override returns max(ma_long+2, 60+squeeze_window+1), which is consistent with the indicator needs and with the 170-bar warmup in the contract.

The source gives no exits. The 15-session clock and the regime exit are the Research Lead's choices, so the result measures that operationalization. The basket is built from today's large caps (survivorship bias is limited but not removed). The analyst should compare it with an equal-weight buy-and-hold of the same 32 names over the identical window, as the hypothesis requires. Per lesson L211, check that the realised average deployment per name is close to 12.5% x 0.97 of equity. The sizing change in this iteration targets that.

Backtest Review

Sharpe
0.33
Total return
17.16%
Max drawdown
16.81%
Trades
385
Win rate
47.0%
Profit factor
1.16

The sizing fix from iteration 1 worked. Median entry notional is 11,793 CNY (range 6,389 to 13,818), about 12% of equity. That matches position_fraction 0.125 x cash_buffer 0.97 with 100-share lots.

The trades match the hypothesis: 300 long-only trades on the 32-name panel. Most close at the 15-session clock (about 21 calendar days, 136 trades), and the rest close on the regime exit or the 8% stop. There are no shorts and no same-day round trips, so T+1 is respected.

The sample is adequate for a walk-forward: 300 closed trades over about 6.3 years of development data.

Per-trade economics clear the floor: average trade return is 0.33% against the CNEQ floor of 0.15%.

Risk is moderate: max drawdown is 16.8%, inside the 25% contract limit and well below the equal-weight basket's 39.8%. The worst loss was 1,601 CNY, about 1.6% of equity, on a stop gap of -13.9%. The largest position was about 14% of equity.

The edge is thin. PF is 1.10 (gross winners +86.9k vs losers -78.8k CNY), Sharpe 0.23, total return +9.0% (CAGR 1.4%), Calmar 0.08, and the longest drawdown lasted 1,359 days.

Benchmark (lesson 170 / QA concern): the equal-weight buy-and-hold of the same 32 names returned +79.5% over the same window, with a 39.8% drawdown. The strategy holds about 3 of 8 slots on average, roughly 35% of the time in the market. A basket scaled to that exposure would return about +28%, against the strategy's +9%. Drawdown is 0.42x the basket's, so this is not pure beta, but the strategy has not yet shown an edge over the basket.

Results swing by year: 2019 +12.9% and 2024 +17.0% carry the result, while 2018, 2022, 2023 and 2025 lose. One or two years carry most of the profit.

Survivorship bias: the basket is today's large caps, so the risk is limited but not removed.

Analysis

Fees are not the problem. The final parameters (squeeze_band 0.031, hold_sessions 11) average 0.62% per trade against the CNEQ floor of 0.15%, with PF 1.37 over 421 trades. Commissions are 4% of gross profit and modeled impact is 6.7%.

Risk is controlled. Drawdown is 10.2% against the pre-registered 25%. The worst realised loss is 1.42% of equity and the largest position is 12.3% of equity, both within the risk_control stop-loss route.

The holdout (Jan 2025 to Oct 2026, 91 trades) has Sharpe 0.95 and 4.7% drawdown. It is consistent with the walk-forward OOS (z +0.61) but not significant (t 1.25 vs a hurdle of 2.0).

The sensitivity sweep found no cliffs, and all 6 checkable pre-registered predictions were met.

HARD FAILURE (enforced, not waivable): the final parameters are positive in only 4 of 9 calendar years (44% vs the 60% floor). This rules out both promotion and labelled paper observation.

The walk-forward evidence is weak and swings in sign. Pooled outer OOS Sharpe is 0.20 (t 0.42 vs a lineage-adjusted hurdle of 2.54, DSR 0.45). Only 6 of 12 outer windows are positive, ranging from -3.7 to +4.0. The inner-training PBO is 0.37-0.98, mostly above 0.6.

The profit is concentrated: 2024 alone carries 54% of the PnL. The initial backtest lost money in 2018, 2022, 2023 and 2026, and lost in calm regimes (Sharpe -0.39).

Parameter stability is unstable. The walk-forward's choice of squeeze_band jumped between about 0.017 and 0.039 (dispersion 0.95), and hold_sessions is moderate. The deployed set sits on an optimum that moves from window to window.

There is little alpha against the equal-weight basket of the same names. The initial run had alpha 0.004, beta 0.16 and information ratio -0.35. The executed-signal diagnostic shows IC -0.01 (t -0.13), indistinguishable from noise.

The full-history Sharpe rose from 0.33 to 0.63 only after both tunables were fitted on the development data. The out-of-sample procedure did not reproduce that gain (0.20).

soft

inconclusive

hard failure

advisory only

IMPLEMENTATION FIX — the hypothesis is unchanged: make the code do what it already says. Do not add or change trading rules. IMPLEMENTATION FIX, sizing only. Change no rule, no fixed contract value and no parameter. (1) Find out why entry quantities do not equal _shares(): expected int(equity_mtm*0.125*0.97/price/100)*100 shares, about 12,000 CNY notional per name, but the ledger shows 44-174 shares (about 1,700 CNY average, almost all odd lots, and the same quantity across differently priced names on the same……Show moreShow less

IMPLEMENTATION FIX — the hypothesis is unchanged: make the code do what it already says. Do not add or change trading rules. IMPLEMENTATION FIX, sizing only. Change no rule, no fixed contract value and no parameter. (1) Find out why entry quantities do not equal _shares(): expected int(equity_mtm*0.125*0.97/price/100)*100 shares, about 12,000 CNY notional per name, but the ledger shows 44-174 shares (about 1,700 CNY average, almost all odd lots, and the same quantity across differently priced names on the same day). Log, per entry, get_equity_mtm(), the raw share count from _shares(), and the size after _affordable_size / margin_capped_size, then read entry_diag (capped / rounded counters). Check whether get_equity_mtm() returns a wrong-currency or wrong-scale value on CNEQ, or whether the affordability cap divides the cash among all candidate legs. (2) Enforce the 100-share board lot in the strategy itself, because the CNEQ venue config does not round (lot_size=1). Final order quantities must be whole multiples of lot_size after every cap: re-round after capping and skip the entry if less than one lot remains. (3) Acceptance check: on rerun, the average entry notional should be close to 12% of equity, peak gross exposure close to max_positions x 12% when 8 names are held, and every quantity a multiple of 100. Report the equal-weight 32-name buy-and-hold over the same window next to the result.

Iteration History

Handle on_order_rejected for these stops. A simple option is a close-based backstop in calculate_signal: exit at the next open if close <= avg_px_open*(1-stop_loss_pct) and no reduce-only stop is working on that leg.

The 8% protective stop is a raw reduce-only STOP_MARKET submitted in on_position_opened. This skips submit_stop_order's session-venue capability guard. With SF_SESSION_STOP_FILLS on, the same-price release tick puts the stop in the book before the entry bar is matched, which is correct. With the switch off, the guard does not fire. The stop then reaches the book only after the entry session's range has been matched. If that session closes more than 8% below the fill, the venue rejects the stop as already crossed, and the position stays unprotected until the time or regime exit. The trigger cannot be crossed when it is placed (8% below the fill at the open), so the code itself is not defective.

Optional: size from the cash available after the pending exits, or accept the conservative shrink.

Exits and new entries decided on the same close fill at the same next open. The entry's cash cap (base helper) is computed from free cash at submission, before the exit proceeds arrive. When the book is nearly full, a replacement entry can be shrunk or dropped. This changes the realised slot count slightly but does not change any rule.

None required.

min_bars_required overrides the framework method (static-analysis warning). It returns max(ma_long+2, 60+squeeze_window+1), which is consistent with what _features needs, so this looks deliberate and harmless.

Outcome Summary

Clearing the fee floor and drawdown limits is not enough: an MA re-cross/squeeze screen on large caps showed almost no alpha over a buy-and-hold of the same names and its profit was concentrated in a few years, so check year consistency and basket-relative alpha early, before spending iterations on tuning.

The analyst abandoned it after optimization on a hard, non-waivable gate: the final parameters were positive in only 4 of 9 calendar years (44% vs the 60% floor), which rules out both promotion and labelled paper observation. Supporting concerns were that 6 of 12 outer walk-forward windows were positive, 2024 produced 54% of the PnL, the chosen squeeze band moved between windows, and the executed-signal IC was -0.01 (noise).

A long-only daily screen on 32 pre-2016 Chinese A-share large caps (CNEQ), distilled from a SuperMind 反包 screen: buy when the close crosses back above MA20 while MA20 > MA120, within 10 sessions of a five-MA (5/10/20/30/60) squeeze; exit on a 15-session clock, a regime exit or an 8% stop.

The initial backtest returned +17.2% over 385 long trades (Sharpe 0.33, avg trade 0.43%, max drawdown 16.8%, alpha 0.004, information ratio -0.35 vs the equal-weight basket of the same names). After optimization (squeeze_band 0.031, hold_sessions 11) it made 0.62% per trade with PF 1.37 over 421 trades and a 10.2% drawdown, but pooled walk-forward OOS Sharpe was only 0.20 (t 0.42 vs a 2.54 hurdle) and the 2025-26 holdout Sharpe of 0.95 (t 1.25) was not significant.

Analysis

(iwencai量化)反包_、20日均线大于120日均线、至少5根均线重合的股票

Backtest and paper results are hypothetical. Trading involves risk of loss.