- Strategy
- Buys when the price z-score closes back above -2 after being below it, and sells when it closes back below +2 after being above it, as long as ADX is not signalling a strong trend. The target is the moving average.
- Risk model
- 1% of balance per trade (configurable), ATR-based stop-loss on every order, one position at a time
What it does
The z-score expresses how far price is from its average in units of standard deviation. Z-Score Mean Reversion EA waits until price has been unusually far from its 20-bar mean and has started to come back, then trades toward that mean. An ADX filter keeps it out of strongly trending conditions, where stretched prices often keep stretching.
How it works
For each closed bar the EA calculates:
z = (close − SMA(20)) ÷ standard deviation of the close over 20 bars
On every new bar it compares the last two closed bars:
- Buy: z was below −2 on the older bar and is at or above −2 on the last closed bar.
- Sell: z was above +2 on the older bar and is at or below +2 on the last closed bar.
- ADX filter: if ADX(14) on the signal bar is above 25, the signal is skipped and logged.
- Stop-loss: 1.5 × ATR(14) from the entry price.
- Take-profit: the SMA(20) value of the signal bar.
- Reward check: if the mean is closer than 0.7 × the stop distance, the trade is skipped.
The z-score is the same quantity that Bollinger Bands display visually: a z-score of ±2 sits on 2-deviation bands. Waiting for the score to come back inside is what makes this a reversion entry rather than a fade of a running move.
How to use it
Ranging currency pairs and quiet sessions are the natural home for this logic. Start on H1 and look at how often ADX blocks signals; a lower ADX limit means fewer but more range-bound trades. Combine the idea with the lesson on support and resistance if you review the trades manually.
Settings
| Input | Default | What it changes |
|---|---|---|
| Mean and standard deviation period | 20 | Lookback of the z-score |
| Z-score threshold | 2.0 | How extreme the move must be |
| ADX filter / period / maximum | true / 14 / 25 | Avoids strong trends |
| ATR period / Stop-loss (x ATR) | 14 / 1.5 | Stop size |
| Min reward vs stop | 0.7 | Skips setups with a close target |
| Risk per trade / Fixed lots | 1.0% / 0 | Position sizing |
| Max spread (points) | 30 | Spread filter |
| Trading start / end hour | 7 / 20 | Server-time window |
| Break-even / Trailing | on / off | Stop management |
Limitations
Price distributions in markets have fat tails, so ±2 deviations are reached more often than a normal distribution suggests and can extend further. ADX is a lagging measure and may still read low when a new trend begins. The take-profit is fixed at the mean of the signal bar, which drifts as new bars arrive.
Before you run it live
Test it in the Strategy Tester on several symbols and on both quiet and volatile years, then on a demo account. Check that your broker's spread and stop level are small relative to the ATR stop. Use a small risk per trade. Past behavior does not guarantee future results.

