# Research

One-shot analyses that produced the parameters the daily system runs on.

Adopted from `claude/scott-trading-patterns-nrodht` in reconciliation step 6.
**None of this is on the daily path** — nothing here runs on a schedule, and
the scanner does not import it. It is kept because it is the provenance of the
thresholds in `PARAMETERIZED_SIGNALS.md`.

| Script | Produces | Based on |
|---|---|---|
| `extract_scott_10year.py` | `scott_10year_extracted.json` | **Real data** — parses the 455 brokerage statement PDFs in `2016/`–`2026/` with `pdfplumber` |
| `extract_trading_patterns.py` | `scott_pattern_parameters.json` | The extracted trade history |
| `analyze_scott_history.py` | Summary statistics | The extracted trade history |
| `backtest_10year.py` | The 52.8% / 1.81 figures | **Simulated data** — see below |

## The backtest is a Monte Carlo simulation, not a backtest

This matters, because its output is quoted across the documentation as
validation of the strategy.

`backtest_10year.py` does not replay historical prices. It **generates** them:

```python
random_shock = random.gauss(0, 1)
daily_price_change = daily_return + (daily_vol * random_shock)
current_price *= (1 + daily_price_change)
```

The walk starts from five hardcoded `INITIAL_PRICES` and uses hardcoded
`ANNUAL_RETURNS` and `ANNUAL_VOLATILITY`. No market data is read.

Entries are not signal-driven either. They are chosen at random:

```python
if random.random() < entry_prob and len(self.open_positions) < 7:
    symbol = random.choice(symbols)
```

`backtest_10year.py` contains **zero** references to `signal_engine` or to the
five entry conditions. The simulated trades were never selected by the rules
the system actually applies.

### What that means for the headline numbers

> "Validated on 2-year backtest with 214 executed trades"
> "Proven track record: 52.8% win rate, 1.81x profit factor"
> — `PARAMETERIZED_SIGNALS.md`

Those figures describe **randomly-timed entries on a randomly-generated price
series**. They are a property of the simulation's parameters, not evidence
about the strategy. Re-running with a different random seed produces different
numbers.

The repository is partly candid about this already: the committed results file
is named `backtest_trades_synthetic.csv`.

### What is and is not supported

**Supported.** The signal *parameters* — the 1.5x volume threshold, the 2–3%
pullback band, the +40%/−20% exits — are distilled from 455 real brokerage
statements spanning a decade of Scott's actual trading. That extraction is
genuine and the PDFs are in the repository.

**Not supported.** Any claim that those parameters have been *validated*,
*backtested*, or shown to produce a 52.8% win rate. No test against real
historical prices exists in either branch.

These figures are currently repeated in at least eight places, including
`index.html`, `SCOTT_STRATEGY_PLAYBOOK.md`, `SYSTEM_STATUS.md` and
`COMPLETE_SYSTEM_SUMMARY.md`. Correcting that wording is a decision for the
strategy's author, not a code change — but it should be made before the
numbers are shown to anyone deciding whether to trade this.

### What a real backtest would need

Historical daily bars for the universe (the same Stooq/Yahoo fetchers
`update_prices.py` already uses), replayed through
`signal_engine.check_entry_signals` and `check_exit_signals`, with entries
taken only where the signals actually fire. That is a meaningful piece of work
and it does not exist yet in either branch.
