# Stochastic oscillator 80/20 on GBPUSD, 15-minute bars - specification (RIP Backtest protocol v1.0 plus the 8 Oct 2026 rules)

Specification written and **frozen 2026-11-08 by Claude on the owner's instruction "Stochastic 80/20 full azi"** (the full test and the upload on the same day). The owner chose the strategy; this draft was frozen without a separate review of its text, before any stochastic value, signal or trade was computed. Once frozen, any change of a rule is documented and treated as a separate test; bugs may be fixed.

## Why this test, and what was looked at before
- **Chosen by the owner** on 2026-11-08 out of three intraday strategies never tested on GBPUSD on this site (stochastic 80/20, the London-open "Judas swing", the EMA 9/21 cross).
- **The rule as commonly taught:** George Lane's stochastic oscillator compares the close with the range of the last 14 bars. Above 80 the market is called overbought and below 20 oversold. The usual signals are %K leaving a zone (crossing back above 20 or below 80) and %K crossing %D inside a zone. Exits are taught in three ways: at the opposite zone, at a fixed multiple of the risk, or at the end of the session. The stop goes beyond the recent swing.
- **Earlier work:**
  - The Stochastic + RSI + MACD test on EURUSD (published, 6 variants). With these three variants the stochastic family has more than four, so the development bar is **t >= 2.5**.
  - On GBPUSD: the London breakout (published), the six-strategy FX study and the ADX study on 1-hour bars (published), and the classic pivot points on 15-minute bars (run 7 Nov 2026, article due 11 Nov 2026). No stochastic value has been computed on GBPUSD.

## Data
- **GBPUSD**, IC Markets MT4 demo, 1-minute bid history **2004-01-01 to 2026-09-28** (`fx_data.loadFx`), the file of the London breakout and pivot tests.
  - New York wall clock; minute stamps are close times. The clock and the level and jump scan were checked for those tests.
- **London time** is computed from New York time with each country's clock-change rules (the pivot engine's functions, checked by its self-test).
- **The forex day** runs from 17:00 to 17:00 New York.
- **Holes (rule 3):** the suspect gaps of `data_holes_gbpusd.json`.

## 15-minute bars and the oscillator
- On the clock: the bar ending at minute E (a multiple of 15 on the New York clock) holds the minutes stamped E-14 to E. Bars are one continuous series across days and weekends, as on a chart; a bar without minutes does not exist.
- **Slow stochastic (14, 3, 3)**, the setting of most charting platforms (MetaTrader's default is 5, 3, 3):
  - fast %K = 100 x (close - lowest low of the last 14 bars) / (highest high - lowest low of the last 14 bars); 50 if that range is zero;
  - %K = the 3-bar simple average of fast %K; %D = the 3-bar simple average of %K.
- A signal uses the **close of a completed bar**. The trade is entered at the **open of the first minute after the bar**.

## Signals (long and short, one position at a time)
- **Window:** signal bars ending between **08:15 and 16:00 London** on the calendar date of the forex day (London and the New York morning).
- **Zone exit signal (ZONE):** long when %K was at or below 20 on the previous bar and is above 20; short when it was at or above 80 and is below 80.
- **Cross signal (KD):** long when %K crosses above %D (previous bar %K <= %D, now %K > %D) while %D is below 20; short when %K crosses below %D while %D is above 80.
- **Stop:** 1 pip beyond the lowest low (long) or highest high (short) of the 14 bars that end with the signal bar. No trade if the entry is at or beyond the stop.
- **R** is the distance from the entry to the stop, in pips.
- After an exit, the next trade needs a signal bar that ends after the exit.

## Variants
1. **STO-ZONE:** zone exit signal; exit when %K reaches the opposite level at a bar close (80 or above for a long, 20 or below for a short), at the open of the next minute.
2. **STO-KD:** cross signal; the same exits as STO-ZONE.
3. **STO-2R:** zone exit signal; exit at a target of 2 R.

All variants also exit at the stop, and at the close of the last minute stamped at or before **16:59 New York**, before the daily rollover (no swap).
- Stops and targets are checked on 1-minute bars. A level that a minute opens beyond fills at that open. If the stop and the target are touched in one minute, the stop is taken.
- An exit by the oscillator is at the open of the first minute after the bar; if there is none before 16:59 New York, the trade closes at the day's last minute.

## Costs
- **1.5 pips per round trip**, as in the London breakout and pivot tests. Scenarios, reported but not gated: 1.0 and 2.5 pips.

## Periods, gates, control
- **Periods (by entry date):** development 2004 to 2012; validation 2013 to 2019; holdout 2020 to 2026-09-28, **already used** (the FX study, the London breakout, the pivot test).
- **Six gates per variant**, in pips per trade:
  1. validation profit factor >= 1.2;
  2. at least 50 trades in each period;
  3. development **t >= 2.5**;
  4. above the 95th percentile of the control;
  5. positive without the 10 best trades;
  6. holdout net positive (flagged as used).

  A variant with fewer than 30 trades is Inconclusive.
- **Control (moved entries):**
  - Every real trade keeps its London entry time, its direction, its stop distance in pips and its exit rule (the 2 R target distance, or the oscillator exit).
  - The trades of each eligible day (a day with at least one bar in the window) move together with it, by one random circular offset of whole eligible days (at least 5% of them).
  - On the new day each trade is entered at the market at the first minute at or after its London time, with the same distances, exits and costs. A trade that would start before the previous moved trade has closed is skipped, so there is still one position at a time.
  - 500 runs, seeds 1000 + run. Statistic: the average net pips per trade.
  - It asks whether the oscillator picks better moments than the same trades placed on other days.
- **Missing data (rule 3):** trades open across a suspect gap are reported, and every gate and verdict is recomputed without them.
- **Also reported:** how trades ended; the win rate with its Wilson interval; R and pips before and after costs; longs and shorts; results by year; trades per day; the cost scenarios.

## Engine and self-test (before the run)
- `stoch_lib.js`, the engine, which reuses the London time, data loading, rule-3 and walk functions of the pivot engine.
- `stoch_ref.js`, an independent re-implementation, written by a separate agent from this specification only, without the engine's code: its own London time from the time-zone database, its own bars, oscillator and walk.
- `stoch_selftest.js` checks:
  1. the oscillator against a hand calculation;
  2. hand-built series: each signal, the stop, both exits, the 16:59 close, a gap through the stop, the stop and the target in one minute, the next trade only after the exit;
  3. engine against reference, trade by trade, for the three variants on the real data;
  4. the control at offset 0 against the real trades.

## Before the article
Results go to the owner first; on the owner's instruction the article is written and uploaded the same day.

## Reading the result
"Buried" or "Inconclusive" mean a convincing edge was not demonstrated; neither is proof that none exists. One pair, one broker's history, one setting of the oscillator (14, 3, 3) and one session window.

### Run log
- 2026-11-08: frozen. sha256 of this file above the "### Run log" heading: 1d3fbc4259132d16098d83456da25f88c8b33a6c9e207afb5d4d4ff15c42525a.
- 2026-11-08, before the run: the reference (stoch_ref.js) was written by a separate agent from this specification and fx_data.js only (Opus, given one added reading before results: the oscillator values rounded to 1e-9, also in the engine). The first self-test run found one difference (STO-ZONE, 1 January 2004): the engine required the next signal bar's last present minute to come after the exit, while the specification says the bar must END after the exit; on a sparse holiday the bar ending 07:45 New York held only the exit minute. Fixed in the engine (the bar's end E must be later than the exit minute's stamp); the self-test then passed with 0 differences on all three variants (13,581, 14,455 and 11,466 trades). Note: the agent's report on its reference already gave the average gross and net pips a trade of the three variants before the self-test ran; no rule was changed after that.
- 2026-11-08: published as /posts/stochastic-oscillator-strategy-gbpusd/ on the owner's instruction (the same day). The day-trading guide gets it after the queued posts of 9-11 Nov 2026.
- 2026-11-08, after the run, from the review of the article: (a) the win count took floating-point noise for a win (2 STO-2R trades whose gross was exactly the 1.5-pip cost); a win now needs more than 1e-9 pips, and the run was repeated (the self-test first): only the STO-2R win rate changed (37.0% to 36.9%). (b) Clarification: besides this specification and fx_data.js, the reference's agent was given eight implementation facts, listed at the top of stoch_ref.js (among them the pip and cost, the data end, the forex day, the 16:59 exit minute, the rounding of levels to 1e-8 and of the oscillator to 1e-9, and that the entry minute's own range counts); none is a result.
- 2026-11-08, precision on the line above: the win counts changed by 4, 1 and 2 trades (STO-ZONE 5,822, STO-KD 4,514, STO-2R 4,236); at one decimal only the STO-2R rate changed.
- 2026-11-11, data fix: the GBPUSD history file's time stamps are one hour early in most weeks of 2004-2014 (all of 2004, about half of 2005) and in a few weeks a year since, mostly between the US and European clock changes (the US 08:30 New York releases spike at the minute stamped 07:31), found by the pre-publication review of the pivot points test on 2026-11-11. The October clock audit (clock_audit_fix.json, 11 Oct 2026) had already moved 576 of 1,205 GBPUSD weeks by +60 minutes for its own reruns, but this test read the uncorrected file: it relied on the clock check of the London breakout test (the hour of the week open), which cannot see this shift. Rerun with a corrected copy (gbp_clockfix.js: the October decisions applied unchanged, every week of the file matched against the audit; prices untouched): the self-test passed and engine = reference on every trade. Rules unchanged; results replaced (the run on the uncorrected clock is kept in stoch_out_v1_clock).
- 2026-11-11, on the clock fix: the October audit's decisions are applied unchanged; a later check found 7 weeks where its inherited move puts the 08:30 New York releases at 09:30 (2004-03-28, 2005-01-23, 2008-12-14, 2018-02-25, 2019-11-10, 2020-08-30 and 2020-09-06), holding 74 of the 13,743 trades of STO-ZONE; they are left as decided.
- 2026-11-11, evening, check after the pivots' Saturday-stub fix: piv_lib.load (which this test uses) now drops the minutes whose forex day is a Saturday, the last Friday hour that the clock fix moved past 17:00 New York. Rerun on the corrected file (stoch_ref, self-test, run): self-test PASSED; the data shrinks from 8,297,247 to 8,293,892 minutes and from 6,126 to 5,905 forex days, but the days with a bar in the signal window stay 5,903 and all three trade lists are byte-identical to the published run. Results unchanged; nothing on the page changes.
