Files
signal-platform/docs/research/post-stop-reentry.md
T
dennisthiessen c9c6967c9c
Deploy / lint (push) Successful in 11s
Deploy / test (push) Successful in 1m18s
Deploy / deploy (push) Successful in 39s
chore: consolidate post-stop research artifacts
2026-07-17 20:46:21 +02:00

197 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Post-stop re-entry: daily policy study and production decision
## Decision
Use a **normal gate reset** after an initial-stop exit:
1. The initial stop always closes the trade. It is never cancelled because the
ticker still passes the gate.
2. Re-entry remains locked until a later full-universe daily scan observes the
ticker **failing** the production activation gate.
3. The lock remains in place until a subsequent daily scan observes a **fresh
qualification**.
4. Only then may the ticker return to the actionable setup list or be opened
through `create_trade`.
Trailing-stop, time, target, and manual exits do not start this state machine.
Scanner errors do not count as a gate failure. The two transitions are persisted
on the latest initial-stop `PaperTrade`, so neither a service call nor a restart
can bypass the rule.
Migration 022 applies the policy prospectively. Existing initial-stop rows are
grandfathered by marking both reset timestamps complete at their historical
`closed_at`; otherwise their new NULL columns would be mistaken for active
locks despite no scanner observations having existed. At runtime, only the
actual latest closed trade per ticker can start a lock, and only when that exit
was an initial stop. A newer trailing, time, target, or manual exit therefore
cannot revive an older stop episode.
This replaces the previously proposed fixed five-session lockdown. The normal
reset counts an unqualified stop-day close when that close is observed after the
stop. The stricter experiment, which required a failed close on a later session,
was not promoted as the research policy.
### Live scheduling boundary
The live daily pipeline runs the R:R scan **before** Outcome Eval. A trade that
is closed at its initial stop by that Outcome Eval—or by an intraday evaluation
after the full scan—was therefore still open when the day's gate observation
ran. Its stop-day state cannot establish the failure. The earliest possible
failure is the next successful full scan, and a fresh qualification requires a
subsequent full scan.
The study simulator closes positions before checking same-session re-entry
state, so its normal `gate_reset` arm can count the stop-day close. At this first
transition boundary, current live ordering is instead analogous to
`strict_gate_reset`. The distinction is material: the strict full-period row
recorded Sharpe 1.68, CAGR 44.8%, and 23.4% drawdown; its disjoint 2025+ row
recorded Sharpe 1.38, CAGR 32.9%, and 21.0% drawdown. The selected normal-reset
result (Sharpe 1.77) is therefore policy-study evidence, not exact live
scheduler-order parity. Changing that ordering would be a separate production
decision.
## Experiment design
Source: [`reports/daily_reentry_matrix.json`](../../reports/daily_reentry_matrix.json),
generated 2026-07-17.
| Input | Value |
|---|---|
| Snapshot | Production SQLite snapshot through 2026-07-02 |
| Period used by the all/5y rows | 2022-06-24 to 2026-07-02 |
| Tickers | 505 |
| Point-in-time candidate observations | 1,011,248 (492,850 long; 518,398 short) |
| Live-universe rank observations | 584,393 |
| Qualified candidates under `live_universe` ranking | 5,189 |
| Entry cadence | Daily |
| Selection and ordering | Production GTL gate; residual/high-vol 80/20 rank; long-only after ranking |
| Exit | 1.5× ATR initial stop; 3× ATR trailing stop; 30-session maximum hold |
| Portfolio | 10 positions; 1% risk per trade; $10,000 initial capital |
| Trading cost | 0.1% per side in the primary matrix; 0.10.3% robustness sweep |
| Holdout split | 2025-01-01 |
The expensive daily candidate replay was performed once. Every policy arm then
used the same candidates, prices, costs, position sizing, capacity, and exit
logic. `live_universe` ranks all eligible tickers once per session like the live
scanner. `backtest_legacy` retains the older candidate-only rank approximation as
a sensitivity check.
### Policies tested
| Arm | Rule after an initial stop |
|---|---|
| `immediate` | No memory; a same-day close re-entry is possible |
| `next_session` | Block only the stop session |
| `cooldown_2/3/5` | Re-entry allowed at wait-session N |
| `gate_reset` | Require a failed gate observation, then a later qualification; the stop-day close may establish the failure |
| `strict_gate_reset` | Ignore the stop-day failure; require a later failed close and then requalification |
| `gate_reset_improved` | Gate reset plus a higher new stop and non-weaker production rank |
| `two_session_confirmation` | Require two consecutive qualified post-stop closes |
## Primary result: production-like `live_universe` ranking
The available history is shorter than five years, so the report's `5y` and
`all` rows cover the same period.
| Policy | Total return | CAGR | Max DD | Sharpe | Trades | Win rate | Post-stop re-entries |
|---|---:|---:|---:|---:|---:|---:|---:|
| Immediate | 348.4% | 45.2% | 24.3% | 1.67 | 489 | 35.6% | 155 |
| Next session | 388.1% | 48.3% | 21.6% | 1.77 | 472 | 36.2% | 142 |
| Cooldown 2 | 343.5% | 44.8% | 23.4% | 1.68 | 472 | 35.8% | 146 |
| Cooldown 3 | 293.4% | 40.6% | 22.7% | 1.56 | 474 | 35.9% | 146 |
| Cooldown 5 | 250.8% | 36.6% | 22.2% | 1.47 | 473 | 35.9% | 145 |
| **Gate reset** | **388.1%** | **48.3%** | **21.6%** | **1.77** | **472** | **36.2%** | **142** |
| Strict gate reset | 342.7% | 44.8% | 23.4% | 1.68 | 471 | 35.9% | 144 |
| Gate reset + improved setup | 267.4% | 38.2% | 24.9% | 1.60 | 422 | 36.3% | 69 |
| Two-session confirmation | 296.1% | 40.8% | **17.6%** | 1.65 | 441 | **37.9%** | 96 |
At the production capacity, normal gate reset improved all four portfolio
objectives relative to immediate re-entry: higher total return, CAGR, and
Sharpe, with lower drawdown. The fixed five-session rule reduced churn but gave
up too many profitable re-entry opportunities.
`gate_reset` and `next_session` produced exactly the same executed portfolio in
the `live_universe` runs. Their rules are not equivalent. In this sample, the
portfolio-level candidate path happened to converge to the same trades. This is
evidence that blocking same-day re-entry helped; it does **not** isolate an
independent return premium for the reset condition itself.
## Disjoint 2025+ test window
These are separate books with entries on or after 2025-01-01. They are a useful
temporal sensitivity check, but not forward evidence: the policy was still
selected after the historical data existed.
| Policy | Total return | CAGR | Max DD | Sharpe | Trades |
|---|---:|---:|---:|---:|---:|
| Immediate | 64.1% | 39.3% | 19.6% | 1.55 | 181 |
| Next session | 68.5% | 41.8% | 19.2% | 1.66 | 183 |
| **Gate reset** | **68.5%** | **41.8%** | **19.2%** | **1.66** | **183** |
| Cooldown 5 | 52.7% | 32.7% | 19.8% | 1.43 | 175 |
| Strict gate reset | 52.9% | 32.9% | 21.0% | 1.38 | 181 |
| Two-session confirmation | 35.4% | 22.5% | **18.1%** | 1.02 | 183 |
The gate-reset result did not depend solely on the earlier training period: it
also beat immediate and the fixed five-session rule in the disjoint test book.
## Cost and capacity sensitivity
At the production capacity of 10, gate reset remained ahead of both immediate
and cooldown 5 as costs increased.
| Cost per side | Policy | Total return | CAGR | Max DD | Sharpe |
|---:|---|---:|---:|---:|---:|
| 0.1% | Immediate | 348.4% | 45.2% | 24.3% | 1.67 |
| 0.1% | **Gate reset** | **388.1%** | **48.3%** | **21.6%** | **1.77** |
| 0.1% | Cooldown 5 | 250.8% | 36.6% | 22.2% | 1.47 |
| 0.2% | Immediate | 296.3% | 40.8% | 25.2% | 1.54 |
| 0.2% | **Gate reset** | **333.0%** | **44.0%** | **22.9%** | **1.64** |
| 0.2% | Cooldown 5 | 209.9% | 32.5% | 23.4% | 1.33 |
| 0.3% | Immediate | 249.8% | 36.5% | 26.0% | 1.41 |
| 0.3% | **Gate reset** | **284.0%** | **39.7%** | **24.2%** | **1.51** |
| 0.3% | Cooldown 5 | 164.0% | 27.3% | 24.7% | 1.16 |
The capacity sweep is a real limitation, not a footnote:
| Capacity at 0.1% cost | Immediate Sharpe / CAGR / DD | Gate-reset Sharpe / CAGR / DD | Cooldown-5 Sharpe / CAGR / DD |
|---:|---|---|---|
| 5 | 1.33 / 31.9% / 16.8% | 1.37 / 32.8% / 17.5% | **1.46 / 35.8% / 18.3%** |
| **10 (production)** | 1.67 / 45.2% / 24.3% | **1.77 / 48.3% / 21.6%** | 1.47 / 36.6% / 22.2% |
| 15 | **1.66 / 44.8% / 24.3%** | 1.63 / 43.0% / **21.6%** | 1.33 / 32.8% / 22.2% |
The promotion is therefore specific to the actual 10-position production book.
At capacity 5, cooldown 5 ranked best; at capacity 15, immediate had slightly
higher return and Sharpe while gate reset retained the shallower drawdown. Do
not generalize the chosen rule to a differently sized portfolio without rerunning
the matrix.
## Legacy-rank sensitivity
The older candidate-only ranking approximation also favored normal gate reset
over immediate and cooldown 5, although `next_session` was slightly stronger.
| Policy | Total return | CAGR | Max DD | Sharpe | Trades |
|---|---:|---:|---:|---:|---:|
| Immediate | 357.4% | 45.9% | 17.9% | 1.73 | 480 |
| Next session | **421.5%** | **50.8%** | 18.5% | **1.86** | 466 |
| **Gate reset** | 408.3% | 49.8% | 18.3% | 1.84 | 464 |
| Cooldown 5 | 332.3% | 43.9% | 19.6% | 1.71 | 459 |
| Strict gate reset | 351.3% | 45.5% | 20.4% | 1.72 | 457 |
## Why gate reset was promoted
- It is tied to a new signal episode instead of an arbitrary elapsed time.
- At the production capacity, it beat immediate and five-session cooldown on
return, CAGR, drawdown, and Sharpe.
- The advantage survived costs of 0.2% and 0.3% per side and the disjoint 2025+
test book.
- It avoids cancelling a valid stop: the loss and transaction costs are always
realized before any later trade.
- It avoids the extra filters that weakened strict reset, improved-setup reset,
and two-close confirmation.
The correct interpretation is deliberately modest: **normal gate reset is the
best production rule among the tested policies for the current 10-position
book.** It is not proof that gate reset is a universal source of alpha. Forward
paper-trade monitoring is still the only genuinely new evidence.