Markets › FX · GBPUSD spot (broker data), 15-minute bars from 1-minute data
Stochastic Oscillator Strategy on GBP/USD: the 80/20 Rule Backtested on 15-Minute Bars
The classic overbought and oversold rule of the stochastic oscillator (14, 3, 3), traded three common ways on GBP/USD 15-minute bars from 2004 to 2026, with costs and a control.
Buried · No proven edgeOverbought, oversold, 39,686 times. About zero before costs.
Variants tried: 3 · Passed every gate: 0 · Holdout opened: yes (already used)
Short answer: not in our test. The stochastic oscillator (14, 3, 3) on GBP/USD 15-minute bars, traded the common 80/20 ways (buy when it leaves the zone below 20, sell when it leaves the zone above 80, or the %K/%D cross inside a zone), made about nothing before costs from 2004 to 2026, between -0.06 and +0.36 pips a trade, and lost between 1.14 and 1.56 pips a trade after 1.5 pips of costs, over 39,686 trades. All three versions were buried.
00The verdict in three lines
- The stochastic 80/20 rule: buy when the oscillator leaves the oversold zone below 20, sell when it leaves the overbought zone above 80. We tested it on GBP/USD 15-minute bars from January 2004 to September 2026, during London and the New York morning, in three common versions, with 1.5 pips of costs a trade, every trade closed before 17:00 New York, and rules, gates and a control fixed before the run.
- None of the three versions passed. Before costs they made between -0.06 and +0.36 pips a trade over 39,686 trades; after costs they lost between 1.14 and 1.56 pips a trade overall, and they lost money in each of the three periods (0.29 to 1.91 pips a trade).
- Picking the moments was not shown to help either. The best version, the zone exit, ranked at the 88th percentile of the same trades placed on other days at the same London time (95 needed), and the %K/%D cross ranked at the 29th.
01The rule
The oscillator: George Lane's stochastic. On 15-minute bars, fast %K = 100 × (close − lowest low of the last 14 bars) / (highest high − lowest low of the last 14 bars); %K is its 3-bar average and %D the 3-bar average of %K. This is the slow stochastic (14, 3, 3) of most charting platforms (MetaTrader's default is 5, 3, 3). Above 80 is called overbought, below 20 oversold. The three versions below are the common textbook ways of trading it.
Signals: from bars ending 08:15 to 16:00 London, at the bar's close; the trade is entered at the open of the next minute, one position at a time. Stop: 1 pip beyond the lowest low (long) or highest high (short) of the 14 bars of the signal. Every trade is closed at the latest at 16:59 New York, before the daily rollover.
- STO-ZONE: buy when %K rises back above 20, sell when it falls back below 80; out when %K reaches the other zone (80 for a long, 20 for a short), at the next minute's open.
- STO-KD: buy when %K crosses above %D while %D is below 20, sell when it crosses below while %D is above 80; the same exits.
- STO-2R: the zone signal, out at a target of twice the risk.
The stochastic family has been tested before on this site (the Stochastic + RSI + MACD test on EUR/USD, 6 versions), so the development t-statistic needed is 2.5.
02Data and costs
Data: GBP/USD 1-minute bid prices from a broker's MetaTrader history (IC Markets), January 2004 to 28 September 2026, the file of our London breakout test, with its clock corrected: in most weeks of 2004 to 2014 and in a few weeks a year since its time stamps were one hour early (the US data releases at 08:30 New York show up at 07:30), and this page was rerun on the corrected file on 11 Nov 2026 (gbp_clockfix.js; 7 of the 576 moved weeks look doubtful on a later check (under 1% of the trades) and were left as decided; see Corrections). 15-minute bars are built from it on the clock. London time comes from New York time with both countries' clock changes. The prices are not republished. Costs: 1.5 pips a round trip, as in our London breakout test (our six-strategy and ADX studies on 1-hour bars used 1 pip); results with 1 and 2.5 pips are in the data notes. No swap: every trade is closed before the rollover.
Engine check: the trades were computed twice. Our engine (stoch_lib.js) and an independent re-implementation (stoch_ref.js), written by a separate AI agent from the frozen specification, the data loader and a few implementation facts we gave it (listed at the top of that file), without our engine's code, with its own London clock from the time-zone database, its own bars, oscillator and trade walk, agree on all 39,686 trades. stoch_selftest.js also checks the oscillator against a hand calculation, hand-built stops, targets and exits, and the control (stoch_selftest_result.txt). Its first run found one difference, an engine reading of a rule on a sparse holiday, which was fixed before the run; the agent's report had already shown the average results, and no rule was changed (see the run log).
03Results
Results in pips. The 95% range is the Wilson interval for the win rate. The drawdown is on closed trades; every position is closed the same day.
| Variant | Version | Trades | Net after costs | Net per trade | Gross per trade | Net per trade in R | Winners (95% range) | Profit factor | Drawdown on closed trades | Verdict |
|---|---|---|---|---|---|---|---|---|---|---|
| STO-ZONE | %K leaves the zone; out at the opposite zone | 13,743 | -16,698 pips | -1.21 | +0.29 | -0.073 R | 42.2% (41% to 43%) | 0.90 | -16,757 pips | Buried |
| STO-KD | %K crosses %D in the zone; out at the opposite zone | 14,316 | -22,377 pips | -1.56 | -0.06 | -0.137 R | 30.5% (30% to 31%) | 0.86 | -22,382 pips | Buried |
| STO-2R | %K leaves the zone; out at 2 R | 11,627 | -13,245 pips | -1.14 | +0.36 | -0.078 R | 36.7% (36% to 38%) | 0.92 | -13,837 pips | Buried |
Cumulative net result by month, in pips.
By period
| Variant | Development 2004-2012 (trades) | Validation 2013-2019 (trades) | Holdout* 2020 to Sep 2026 (trades) | Development t | Validation PF |
|---|---|---|---|---|---|
| STO-ZONE | -3,372 pips (5,142) | -7,056 pips (4,270) | -6,270 pips (4,331) | -1.28 | 0.85 |
| STO-KD | -8,363 pips (5,377) | -7,732 pips (4,366) | -6,282 pips (4,573) | -3.41 | 0.83 |
| STO-2R | -1,257 pips (4,388) | -5,148 pips (3,655) | -6,839 pips (3,584) | -0.46 | 0.89 |
* The holdout was already used: these years had been seen in our earlier GBP/USD tests, so its result cannot count as clean out-of-sample evidence.
04How the trades ended
| Variant | Out at the other zone | Target 2 R | Stopped | Closed at 16:59 NY | Median R, pips | Before costs, per trade | Costs, per trade | After costs, per trade |
|---|---|---|---|---|---|---|---|---|
| STO-ZONE | 42.3% | – | 54.6% | 3.1% | 20.00 | +0.014 R | 0.087 R | -0.073 R |
| STO-KD | 29.4% | – | 67.9% | 2.8% | 14.00 | -0.002 R | 0.134 R | -0.137 R |
| STO-2R | – | 26.7% | 58.2% | 15.1% | 20.20 | +0.008 R | 0.086 R | -0.078 R |
The zone version reached the other zone on 42.3% of its trades and was stopped on 54.6%. Its median risk was 20.00 pips, and the 1.5 pips of costs averaged 0.087 R a trade (more on trades with a tight stop); the result before costs, +0.014 R, was not enough to cover them. With a target of twice the risk, a trade needs to win about one time in three to break even before costs; the 2 R version reached its target on 26.7% of its trades and closed 15.1% at the end of the day.
05By year
| Year | STO-ZONE trades | STO-ZONE net | STO-KD trades | STO-KD net | STO-2R trades | STO-2R net |
|---|---|---|---|---|---|---|
| 2004 | 543 | -1,706 pips | 557 | -1,789 pips | 489 | -1,134 pips |
| 2005 | 526 | -1,271 pips | 529 | -1,585 pips | 478 | -1,186 pips |
| 2006 | 521 | -1,018 pips | 534 | -1,260 pips | 455 | -1,066 pips |
| 2007 | 541 | -456 pips | 552 | -1,190 pips | 468 | +159 pips |
| 2008 | 580 | +1,577 pips | 637 | -610 pips | 482 | +1,627 pips |
| 2009 | 620 | +238 pips | 677 | -1,193 pips | 520 | +434 pips |
| 2010 | 615 | -132 pips | 677 | -382 pips | 496 | +277 pips |
| 2011 | 589 | +397 pips | 628 | +745 pips | 489 | +773 pips |
| 2012 | 607 | -1,000 pips | 586 | -1,100 pips | 511 | -1,141 pips |
| 2013 | 625 | -688 pips | 636 | -1,416 pips | 544 | -1,593 pips |
| 2014 | 618 | -1,220 pips | 602 | -1,392 pips | 529 | -355 pips |
| 2015 | 585 | -1,169 pips | 623 | -962 pips | 513 | -1,414 pips |
| 2016 | 604 | +169 pips | 597 | +845 pips | 505 | +32 pips |
| 2017 | 604 | -1,304 pips | 597 | -1,748 pips | 522 | -452 pips |
| 2018 | 622 | -1,315 pips | 681 | -1,408 pips | 520 | +37 pips |
| 2019 | 612 | -1,529 pips | 630 | -1,650 pips | 522 | -1,403 pips |
| 2020 | 646 | -1,006 pips | 684 | -988 pips | 534 | -593 pips |
| 2021 | 667 | -1,626 pips | 678 | -1,623 pips | 547 | -2,026 pips |
| 2022 | 627 | -500 pips | 674 | -1,071 pips | 512 | -246 pips |
| 2023 | 652 | -1,039 pips | 712 | -620 pips | 547 | -798 pips |
| 2024 | 635 | -163 pips | 656 | +53 pips | 526 | -566 pips |
| 2025 | 632 | -1,319 pips | 680 | -1,509 pips | 528 | -1,406 pips |
| 2026 | 472 | -616 pips | 489 | -525 pips | 390 | -1,205 pips |
2026 runs to 28 September. Out of 23 years, the zone version made money in 4 (2008, 2009, 2011, 2016), the cross version in 3 (2011, 2016, 2024) and the 2 R version in 7 (2007, 2008, 2009, 2010, 2011, 2016, 2018).
06Longs, shorts and the best trades
| Variant | Longs: trades / before costs | Shorts: trades / before costs | 10 best trades, net | Net without them |
|---|---|---|---|---|
| STO-ZONE | 6,993 / +3,059 pips | 6,750 / +858 pips | +2,108 pips | -18,806 pips |
| STO-KD | 7,335 / -1,026 pips | 6,981 / +123 pips | +2,011 pips | -24,388 pips |
| STO-2R | 5,979 / +3,632 pips | 5,648 / +564 pips | +2,126 pips | -15,371 pips |
07Is it the oscillator or the clock?
The benchmark is a moved-entry control: every trade keeps its London entry time, direction, stop distance and exit rule, and the trades of each day move together to another day by one random offset of at least 5% of the days. On the new day each trade is entered at the market at the same London time; a trade that would start before the previous one has closed is skipped, so the control has fewer trades. 500 runs with fixed seeds; the bar is the 95th percentile of the average net result per trade. It asks whether the oscillator picks better moments than the same trades on other days.
| Variant | Trades | Control trades (mean) | Real average per trade | Control median | Control 5th to 95th | Percentile (95 needed) |
|---|---|---|---|---|---|---|
| STO-ZONE | 13,743 | 11,796 | -1.21 | -1.49 | -1.83 to -1.12 | 88.0 |
| STO-KD | 14,316 | 12,360 | -1.56 | -1.44 | -1.76 to -1.11 | 28.6 |
| STO-2R | 11,627 | 9,750 | -1.14 | -1.44 | -1.88 to -0.94 | 84.8 |
The zone version did a little better than the median of the moved trades (-1.21 against -1.49 pips a trade), but not by enough to rule out luck; the cross version ranked below the median.
08The gates
| Variant | Trades | 1. PF ≥ 1.2 in validation | 2. ≥ 50 trades in each period | 3. t ≥ 2.5 on development | 4. Above the 95th percentile of the control | 5. Positive without the 10 best trades | 6. Holdout net positive (already used) |
|---|---|---|---|---|---|---|---|
| STO-ZONE | 13,743 | fail | pass | fail | fail | fail | fail |
| STO-KD | 14,316 | fail | pass | fail | fail | fail | fail |
| STO-2R | 11,627 | fail | pass | fail | fail | fail | fail |
09Verdict by variant
| Variant | Cause | Gates failed | Verdict |
|---|---|---|---|
| STO-ZONE | Costs | 1, 3, 4, 5, 6 | Buried |
| STO-KD | No proven edge | 1, 3, 4, 5, 6 | Buried |
| STO-2R | Costs | 1, 3, 4, 5, 6 | Buried |
The causes follow the protocol's definitions. Costs marks a result that was positive before costs and negative after: here the gross was close to zero (+0.29 and +0.36 pips a trade), so costs did not remove a demonstrated edge; they turned a result near zero into a loss. No proven edge marks the cross version, which lost even before costs. The headline cause is No proven edge. Buried means that a convincing edge was not shown here; it does not prove that none exists.
Not tested: other settings or levels, trend filters, other sessions, pairs or timeframes, position sizing.
TWhat this shows, and what to take into your own tests
What the results show
- Before costs the three versions made between -0.06 and +0.36 pips a trade, over 39,686 trades from 2004 to 2026: about zero.
- With 1.5 pips of costs a trade they lost between 1.14 and 1.56 pips a trade overall, and lost money in each of the three periods.
- The zone version ranked at the 88th percentile of the same trades placed on other days, the cross version at the 29th; 95 was needed.
What remains unknown
- Other settings: MetaTrader's 5, 3, 3, faster or slower oscillators, or 70/30 levels.
- A trend filter, such as taking only longs above a moving average, or other session hours.
- Other pairs and other timeframes.
Why it failed
The oscillator says where the close sits inside the range of the last 14 bars. On 15-minute GBP/USD that said almost nothing about the next move: the zone version won 42.2% of its trades and earned +0.29 pips a trade before costs. Two to three trades a day at 1.5 pips each is about 906 pips of costs a year for the zone version alone, and the result before costs (+0.29 pips a trade, about zero) could not pay for them.
What you can apply to your own tests
- Measure a signal before costs first: if it is near zero, a different exit is unlikely to save it; here neither exit did.
- Count the trades: a rule that trades two or three times a day needs a real edge of more than its cost on every trade.
- In this test overbought alone was not a useful sell signal: the zone version's shorts made +0.13 pips a trade before costs.
A note on the numbers: drawdown figures are measured on closed trades unless a table says it includes open losses. Open losses inside a trade are not counted in a closed-trade drawdown, so real account risk is higher, especially for systems with no stop. Backtests are not live trading.
FAQCommon questions
Does the stochastic oscillator strategy work?
Not in our test on GBP/USD 15-minute bars: the three versions made between -0.06 and +0.36 pips a trade before costs over 39,686 trades from 2004 to 2026, and the best ranked at the 88th percentile of the same trades placed on other days, where 95 was needed.
What is the 80/20 stochastic strategy?
A rule built on the stochastic oscillator, which shows where the close sits in the range of the last 14 bars, from 0 to 100. Above 80 the market is called overbought and below 20 oversold; traders buy when the oscillator rises back above 20 and sell when it falls back below 80, or use the cross of its two lines, %K and %D, inside those zones.
What is the win rate of a stochastic strategy?
In our test the zone version won 42.2% of its trades, the %K/%D cross 30.5% and the version with a 2R target 36.7%. A win rate below one half can still pay when the winners are bigger than the losers; here the result before costs was about zero, so none of these win rates paid for the costs.
What are the best stochastic settings?
We tested only the most common setting, 14, 3, 3, with the 80 and 20 levels, fixed before the run. We did not search for the best settings: picking the best of many settings after the fact finds patterns in past data that rarely last, which is why our protocol counts every version tried.
How was the stochastic strategy tested?
On 1-minute GBP/USD broker data from 2004 to 2026, with the file's clock corrected where it was one hour off (most weeks of 2004 to 2014 and in a few weeks a year since), 15-minute bars built on the clock, signals during London and the New York morning, every trade closed before 17:00 New York, 1.5 pips of costs a trade, rules written and dated before the data was run, results split into development, validation and holdout periods, a control that places the same trades on other days at the same London time as the benchmark, and every variant reported. Read the protocol.
10Check our arithmetic
stoch_spec.md
stoch_lib.js · stoch_ref.js · stoch_selftest.js · stoch_run.js
control_audit_lib.js · em_lib.js · fx_data.js · gh_lib.js · hourly_lib.js · ma_lib.js · piv_lib.js · rb_lib.js · rsi2_protocol.js
stoch_selftest_result.txt · stoch_results.txt · stoch_summary.json · gbp_clockfix.js · clock_audit_fix.json · gbp_clockfix_result.txt · stoch_results_v1_clock.txt
To rerun it: put your own MT4 GBPUSD1.hst in ./history/ (or set MT4_HISTORY to its folder), run node gbp_clockfix.js <folder> (it reads clock_audit_fix.json, the decisions of our October 2026 clock audit), then set MT4_HISTORY=<folder> and run node stoch_ref.js, node stoch_selftest.js and node stoch_run.js. Code provenance: our own code; the re-implementation was written for this test by an AI agent working only from the specification. No third-party source code is used or published.
11Data notes
Suspect gaps (rule 3). A trade is flagged if it was open across a suspect gap in the data. Removing them changes no verdict. The gap list was made on the uncorrected clock, so in the weeks moved by the clock fix its windows sit one hour early; this can only change which few trades the check removes, and no verdict depends on it.
| Variant | Trades | Flagged and removed | Net per trade, pips | Verdict |
|---|---|---|---|---|
| STO-ZONE | 13,743 | 30 | -1.21 → -1.23 | Buried → Buried |
| STO-KD | 14,316 | 29 | -1.56 → -1.58 | Buried → Buried |
| STO-2R | 11,627 | 49 | -1.14 → -1.16 | Buried → Buried |
Costs. The average net result per trade, in pips, with other costs (the gates use 1.5 pips):
| Variant | 1 pip | 1.5 pips (used) | 2.5 pips |
|---|---|---|---|
| STO-ZONE | -0.71 | -1.21 | -2.21 |
| STO-KD | -1.06 | -1.56 | -2.56 |
| STO-2R | -0.64 | -1.14 | -2.14 |
Even at 1 pip a trade every version loses money: the result before costs, at most +0.36 pips a trade, is less than 1 pip. The versions traded about 604, 629 and 511 times a year, so at 1.5 pips the costs came to about 767 to 944 pips a year.
12Corrections
11 Nov 2026, data correction: the GBP/USD file's time stamps were one hour early in most weeks of 2004 to 2014 and in a few weeks a year since, found by the review of a later GBP/USD test. Our October 2026 clock audit had already flagged these weeks, but this test read the uncorrected file. We reran it with the same rules on the corrected file: 39,686 trades instead of 39,502; net per trade STO-ZONE -1.32 to -1.21, STO-KD -1.63 to -1.56, STO-2R -1.35 to -1.14 pips; control percentiles 80.0 to 88.0, 23.0 to 28.6, 67.0 to 84.8; before costs STO-ZONE +0.18 to +0.29, STO-KD -0.13 to -0.06, STO-2R +0.15 to +0.36 pips a trade; win rates 42.9% to 42.2%, 31.2% to 30.5%, 36.9% to 36.7%; years in profit 3 to 4, 2 to 3, 4 to 7; the trade count in the epitaph changed with them. Every variant still passes one gate of six, the causes are unchanged, and every verdict is still Buried. The first run's results are published as stoch_results_v1_clock.txt.