#1746 stop-rule comparison
The previous producer used an inclusive 20-session minimum close as structural support. A close cannot be strictly below a minimum that includes itself, so this branch of the stop rule never fired. Confirmed swing support fixes that definition; this experiment does not establish better investment performance.
Scope and provenance
The read-only capture contains 4,344,852 rows and 2,615 codes (2018-01-02 to 2026-09-24). Replay uses all 4,342,728 stock/ETF rows and 2,614 canonical stock-code capital sleeves, excluding exactly 2,124 non-tradable ^TWII index rows. All 18 TW/TWO listing transfers keep one continuous history and sleeve. There are 2,125 captured market sessions, no invalid adjusted bars and no zero/missing-volume bars. Five instruments never confirm a pivot/common entry.
Input SHA-256: 16824ebcafc13ba6fe779a67a7b165f12df96a0c210d7aa74c32296b43efaacd.
Runner SHA-256: 5eee3eef483999e01f8eae3ac2642700b828c5ec407060ca3ee795921e23c112.
Baseline producer: 6141a32e22ac64dd9491b0654a34bc02b88a8691.
Detailed outputs: engine-open summary, tradability-screened summary. They include execution/censor counts, 20-session MAE/MFE distributions, fees, and coverage. Large input/trade/event files are retained in task evidence rather than committed.
Rules and execution
- Actual old rule: same-day inclusive 20-close minimum. The previous-session minimum is reported separately as a sensitivity, not substituted for actual behavior.
- New rule: latest-by-date strict five-left/five-right adjusted low, available only after the fifth right session. All pre-range history is retained; no expiry or ATR fallback.
- Each code has NT$5,000,000, a 10% per-position cash cap and 1,000-share lots. Buy fee is 0.1425%; sell fee is 0.1425% plus 0.30% tax. These are the existing
BacktestConfigassumptions, applied uniformly, including ETFs. Cooldown is five global sessions; slippage is zero; Sharpe uses 1.5% annual risk-free rate. - The synthetic entry rule enters while flat at the earliest common eligible next-session open when price is not already below that rule's stop, and can re-enter after cooldown. It has no production entry ranker or historical action-advice holdings.
- A close-T decision executes only at the exact next global captured session's adjusted open. Missing/nonpositive opens are censored without retry. The screened sensitivity also blocks zero/missing volume and every single-price O=H=L=C bar. This screen is not a lower-bound return and cannot prove fillability without queue, suspension and slippage data.
- Daily equity carries the last valid adjusted close across missing sessions. A valid executable global-final close liquidates; otherwise the position remains marked and open. This deliberately corrects the existing engine's entry-price fallback on missing sessions. Figures below are marked-equity returns, not fully liquidated proceeds.
Results
All-bar diagnostics are observations, not transactions: actual old rule 0 / 4,342,728 strict breaches; prior-known sensitivity 426,473 / 4,340,114 (9.8263%); confirmed swing 724,729 / 4,282,259 (16.9240%). For swing, 718,620 have an eligible next open and 6,109 are censored.
| Execution | Stop rule | Stops | Marked return | CAGR | Sharpe | Max drawdown | Terminal open positions |
|---|---|---|---|---|---|---|---|
| engine | Actual old rule | 0 | 19.1400% | 2.0273% | 0.238 | 5.4646% | 258 |
| engine | Prior-known sensitivity | 157,200 | 8.3731% | 0.9258% | -0.586 | 1.6622% | 204 |
| engine | Confirmed swing | 96,019 | 8.4572% | 0.9348% | -0.574 | 1.7164% | 204 |
| conservative | Actual old rule | 0 | 19.1364% | 2.0270% | 0.237 | 5.4650% | 337 |
| conservative | Prior-known sensitivity | 153,956 | 8.3111% | 0.9192% | -0.593 | 1.6627% | 276 |
| conservative | Confirmed swing | 94,696 | 8.3748% | 0.9260% | -0.584 | 1.7153% | 266 |
For actual swing-stop trades, compare net stop-sale proceeds against selling the same shares at the close of the 20th subsequent ticker session. A missing/incomplete horizon is censored. This is a terminal hold-versus-sell counterfactual; it does not include subsequent re-entry opportunity or equal a strategy P&L difference.
| Execution | Complete 20-session exits | Continued fall | Rebound | Avoided loss NT$ | Missed rebound NT$ | Net advantage NT$ |
|---|---|---|---|---|---|---|
| engine | 94,762 | 46,238 (48.79%) | 47,370 (49.99%) | 1,574,999,020 | 1,955,389,898 | -380,390,877 |
| conservative | 93,457 | 45,580 (48.77%) | 46,764 (50.04%) | 1,552,188,897 | 1,936,735,667 | -384,546,770 |
The swing rule lowers drawdown but also lowers return against the non-triggering old stop in this isolated policy. Missed rebounds exceed avoided losses in both execution assumptions. This supports correcting the stop's meaning, not a claim that the new stop improves strategy returns.
There is no point-in-time listing master: 867 histories start late and 259 end early. Equal capital is allocated across the captured universe, cash is idle outside observed histories, and the result is full-period cash-weighted. Terminal stale marks may be unrealizable; survivorship-free or fully tradable performance is not established.
Reproduce
From investment-agent/backend, with the captured gzip CSV and an output directory outside source:
python scripts/compare_swing_stop_rules.py \
--input /path/to/ohlc-20260928.csv.gz --output-dir /tmp/swing-stop-study \
--start 2018-01-01 --end 2026-09-24 --execution-mode engine \
--require-hash 16824ebcafc13ba6fe779a67a7b165f12df96a0c210d7aa74c32296b43efaacd
python scripts/compare_swing_stop_rules.py \
--input /path/to/ohlc-20260928.csv.gz --output-dir /tmp/swing-stop-study \
--start 2018-01-01 --end 2026-09-24 --execution-mode conservative --policy-only \
--require-hash 16824ebcafc13ba6fe779a67a7b165f12df96a0c210d7aa74c32296b43efaacd
The runner docstring specifies CSV columns and a read-only capture query. --max-codes is only a smoke scope and never changes the market calendar. Focused tests verify causal pre-range pivots, listing transfers, missing-session marks, invalid/final-bar behavior, and the old rule's impossible strict breach. No shared database write or live trade is part of this study.