All posts
PublishedByEvidence recordSupport and resistanceHorizontal linesPrice actionBreakoutBacktestUSDJPY

Do Support and Resistance Lines Work? 5,184 Backtests

A horizontal line is drawn where price has already turned. Whether the number of turns matters, measured on USD/JPY against a placebo line and a reshuffled series.

A horizontal line at a price that has already turned is the first thing a discretionary trader draws and the one thing no oscillator describes. The reason it is supposed to work is plain: price stopped there before.

Put that in a form that can be measured and two questions fall out. One is a dose: if "it held three times" is the reason to trust the line, a line that held five times should hold better than one that held twice. The other is a control: what happens at a line drawn where nothing ever stopped?

Three results first.

One. The touch count did not matter. Splitting the bounce signals by how many times the line had already held gives 50.13% for three touches, 49.24% for four and 50.10% for five or more on the 15-minute long side.

Two. Price sits inside a line's tolerance on 41.40% to 65.75% of bars. Roughly one bar in two, which makes being at a level ordinary rather than special.

Three. Of the four settings that decide what counts as a line, the touch count moved the annual result least at 357.9 pips, against 1,000.9 for the tolerance band.

And one more thing turned up before any of that. The engine's horizontal-line condition had never taken a single trade. Two separate faults did it, and either alone was enough.

444750535650.1349.2450.15+15-min long50.2350.3450.25+15-min short50.6354.5452.05+Hourly long52.0349.3445.25+Hourly shortshare that closed the bounce's way ten bars later (%)
held 3 times4 times5 or morethe bold line is 50%
Share of bounces that closed in their favour ten bars later, grouped by how many times the line had already held. All six 15-minute bars land between 49.24% and 50.25%. The hourly short side falls as the count rises, from 52.04% to 45.24%.

The condition had never taken a trade

The first sweep for this article returned zero trades on all 2,592 runs. Two reasons.

The first was a missing ATR. The tolerance is set as a multiple of ATR rather than in pips, because two touches "at the same price" mean different things on gold and on EUR/USD. The engine keeps a list of which conditions need the 14-bar range computed, and the horizontal line was not on it. So the range handed to the level builder was empty, the tolerance band came out as zero, every swing was discarded before it could join a cluster, and the trading test sits behind a check that the band is above zero.

The second was a comparison that can never be true. Resistance is by construction the nearest line above the current close. The break reading asked whether the current close was above resistance. Support is by construction at or below the close, and the short side asked whether the close was below support. A break is a close through the line price was under a bar ago, so that is what it reads now.

Both faults present as a property of the market rather than of the code: the condition appears in the editor, the backtest runs, and the report says no trades. This is the fourth fault of that shape this series has found, after the session filter, the fair-value-gap drawing and the GMMA exit.

Every figure below is from after the fix.

What the line is built from

Four steps.

  1. Find the swings. A bar is a swing high if its high is the highest for the given number of bars on each side. Because the right-hand side is needed, a swing is only confirmed that many bars later.
  2. Cluster nearby prices. Two swings closer than the ATR tolerance are the same line, and the line's price moves to the average of what has touched it.
  3. Count the touches. How many swings joined the cluster.
  4. Offer only the lines that reach the minimum. The nearest one below the close is support, the nearest above is resistance.

Waiting for confirmation is the part that matters. A swing is not a swing until the bars to its right exist, so reading a level before then draws support from a low the tester has not seen. It is the most flattering bug a backtest can have.

Lines that fall outside the lookback are dropped, and not only for speed. "This line held three times" means three times inside the lookback. A price brushed once ten thousand bars ago no longer counts.

Support and resistance settings, and how they are read

This condition draws nothing on the chart. It exists inside the backtester, so what follows is about numbers rather than about lines on a screen.

SettingDefaultWhat it does
ReadingBounceBounce (held at the line) or break (closed through it)
Minimum touches3How many clustered swings before the line is offered. Two is the floor
Tolerance0.5How close two swings must be to count as one line, in ATRs
Swing strength3Bars on each side that make a swing
Lookback200How far back a line may be drawn from

The two readings

Bounce buys when the bar's low reaches inside support's tolerance and the close finishes above support. It closes at the next line up. The sell side mirrors it at resistance.

Break buys when the close finishes above the resistance of the previous bar, and closes on the mirror break down through support.

Both open either side, so entry and exit share one rule set.

How this was measured

ItemValue
InstrumentUSD/JPY
Timeframes15-minute, 1-hour, 4-hour
Period1 January 2024 to 31 December 2025, with 2025 also split in halves
ReadingsBounce and break
Lookback100, 200, 400
Swing strength2, 3, 5, 8
Tolerance0.25, 0.5, 1.0 ATR
Minimum touches2, 3, 4
ControlsPrices 1.5, 2 and 3 ATRs off the line, and a reshuffled close series
Runs2 readings x 3 x 4 x 3 x 3 = 216, x 3 timeframes x 4 windows x 2 spreads = 5,184
Spread0.3 pips and 0
Lot size0.1
FillClose of the signal bar

Everything runs at a zero spread as well. The bounce reading trades more than a thousand times a year on the hourly chart, so a losing year has to be separable into "the line did not work" and "the round trips did it".

Price sits at a line on half the bars

Before judging the line, count how many exist and how often price reaches one. At the defaults: lookback 200, swing 3, tolerance 0.5 ATR, three touches.

TimeframeYearBarsSupport existsPrice inside the bandMedian touchesMax
15-minute202524,89381.28%59.90%438
15-minute202424,99986.72%58.20%424
Hourly20256,21685.52%65.75%523
Hourly20246,25084.24%52.64%415
4-hour20251,60085.50%61.63%515
4-hour20241,61684.90%41.40%38

Price is inside a line's tolerance on 41.40% to 65.75% of bars. "It reached a level" happens on roughly one bar in two.

The median touch count runs 3 to 5 and the maximum reaches 38 on the 15-minute chart in 2025. Lines are not scarce.

Does a line that held more times hold better

The dose. Bounce signals, split by how many times that line had already held, measured to the close ten bars later. The count is the engine's own, so nothing new is defined here. 2025:

TimeframeSideTouchesSignalsHit rateMean over 10 bars
15-minuteLong32,75950.13%-0.16 pips
15-minuteLong41,91149.24%-0.55 pips
15-minuteLong5 or more4,99650.10%-0.71 pips
15-minuteShort32,64050.23%+1.19 pips
15-minuteShort41,82550.25%-0.89 pips
15-minuteShort5 or more5,39050.20%+1.17 pips
HourlyLong364050.63%-0.01 pips
HourlyLong440254.48%+3.18 pips
HourlyLong5 or more1,80951.96%+0.72 pips
HourlyShort371152.04%+3.12 pips
HourlyShort444649.33%-1.22 pips
HourlyShort5 or more1,60745.24%-3.77 pips

All six 15-minute buckets land between 49.24% and 50.25%, which a coin also does. The hourly long side runs 50.63%, 54.48% and 51.96%, in no order. The short side runs 52.04%, 49.33% and 45.24%: falling as the count rises.

If "it stopped there before, so it will stop again" is the reason, the number of times it stopped should show up. It did not.

The same lines appear in a reshuffled series

Two controls.

The first is a line moved off the real one. The same test at prices 1.5, 2 and 3 ATRs above support, far enough that the tolerance bands cannot overlap. 2025:

TimeframeLineSignalsHit rateClose was this many ATRs above the line
15-minuteDrawn9,66649.94%0.49
15-minute+1.5 ATR2,74847.49%0.46
15-minute+2 ATR1,69547.67%0.49
HourlyDrawn2,85152.02%0.48
Hourly+1.5 ATR62450.48%0.46
Hourly+2 ATR41547.95%0.48
4-hourDrawn67953.31%0.51
4-hour+1.5 ATR17254.07%0.52
4-hour+2 ATR12245.08%0.51

The drawn line beat the offset line on hit rate in 13 of 18 comparisons. The distance at the moment of the signal does match: across the nine 2025 rows the close finished 0.48 to 0.51 ATRs above the drawn line and 0.46 to 0.54 above the offset ones.

What does not match is the count. The offset lines fire on 7.8% to 41.6% as many bars as the drawn one. Support is by construction the nearest line below the close, so price reaches it constantly; a line 1.5 ATRs higher is only reached on bars that travelled that far. The two sets are not the same size, so this control is not enough on its own.

The second is a reshuffled series. Every close-to-close change is kept exactly once and only the order is destroyed, so the drift, the volatility and the fat tails belong to the market. What does not survive is where price turned. A reshuffled bar has no wick, so both series are read on the close alone (the engine's bounce reads the low; these figures compare two series rather than report a traded rule).

TimeframeYearSeriesSignalsHit rateMean over 10 bars
15-minute2025Real5,56849.69%-0.45 pips
15-minute2025Reshuffled2,72050.04%-1.83 pips
Hourly2025Real1,63751.13%-0.51 pips
Hourly2025Reshuffled54247.23%-0.15 pips
4-hour2025Real37655.59%+7.53 pips
4-hour2025Reshuffled17252.91%+3.58 pips
15-minute2024Real5,55353.97%+0.80 pips
15-minute2024Reshuffled2,32849.44%-1.00 pips
Hourly2024Real1,17959.20%+5.17 pips
Hourly2024Reshuffled64252.80%+1.24 pips
4-hour2024Real24964.26%+26.49 pips
4-hour2024Reshuffled11436.84%-24.74 pips

The real series beat the reshuffled one on hit rate in 5 of 6 cells. Only the 15-minute chart in 2025 went the other way, at 49.69% against 50.04%.

So the order of the closes carries something. The real series' own hit rate still runs from 49.69% to 64.26%, though, and beating a reshuffle is not the same as surviving as a trade.

Trading both readings

108 settings, traded. Settings that ended the year with positive pips:

ReadingWindow15-minuteHourly4-hour
Bounce2025122157
Bounce2024497991
Break2025326130
Break2024499592

In 2024 the bounce reached 91 of 108 and the break 92 on the 4-hour chart. In 2025 the same cells are 57 and 30.

Requiring both years, and then all four windows including the two halves of 2025:

ReadingTimeframeBoth yearsAll four windows
Bounce15-minute115
BounceHourly197
Bounce4-hour5021
Break15-minute2310
BreakHourly5832
Break4-hour2311

The strongest cell is the hourly break at 58 of 108, and 32 across all four windows. The bounce's best is the 4-hour chart at 50 and 21.

Win rates and trade sizes at the defaults:

ReadingTimeframeYearTradesWin rateMean winMean lossAnnual pipsBars held
Bounce15-minute20256,37240.68%+11.11-8.56-3,544.05.0
BounceHourly20251,79944.41%+19.66-15.86-151.34.2
Bounce4-hour202426145.59%+63.49-33.52+2,794.67.9
Break15-minute20253,40728.29%+22.42-9.95-2,682.410.3
BreakHourly202593830.38%+43.26-18.05+542.89.3
Break4-hour202413138.93%+121.24-46.84+2,436.116.7

The break wins 25.45% to 31.08% of its trades and makes more than twice as much on a winner as it loses on a loser. The bounce wins 38.26% to 42.80% at a ratio of 1.3 to 1.9.

The bounce leans long

Between 66.06% and 67.73% of the bounce's trades are buys. For the break it is 50.01% to 50.19%.

The engine checks the long side first when a bar satisfies both. A bounce off support and a bounce off resistance can both be true on one bar, and the buy takes it every time. A rule that is symmetric by description trades long by construction. The inside-bar article found the same long bias for the same reason.

The setting that defines a line matters least

Each setting moved one at a time, with the median annual pips of every setting group containing that value. Hourly chart, 2025, median in brackets:

ReadingSettingProfitable count and median per value
BounceLookback100: 2/36 (-1,291.5) 200: 7/36 (-1,131.0) 400: 12/36 (-384.6)
BounceSwing strength2: 7/27 (-658.7) 3: 7/27 (-1,002.9) 5: 5/27 (-977.5) 8: 2/27 (-1,393.9)
BounceTolerance0.25: 15/36 (-315.4) 0.5: 3/36 (-1,316.3) 1.0: 3/36 (-1,049.7)
BounceMinimum touches2: 4/36 (-1,020.5) 3: 9/36 (-1,183.6) 4: 8/36 (-825.7)
BreakLookback100: 13/36 (-521.9) 200: 20/36 (+97.2) 400: 28/36 (+1,002.4)
BreakSwing strength2: 24/27 (+1,148.5) 3: 21/27 (+542.8) 5: 13/27 (-30.6) 8: 3/27 (-822.2)
BreakTolerance0.25: 20/36 (+261.3) 0.5: 18/36 (-36.0) 1.0: 23/36 (+286.1)
BreakMinimum touches2: 23/36 (+441.4) 3: 22/36 (+423.7) 4: 16/36 (-128.3)

How far each setting moves that median from end to end:

ReadingLookbackSwing strengthToleranceMinimum touches
Bounce906.9735.21,000.9357.9
Break1,524.31,970.7322.1569.7

For the bounce the touch count moves it least, at 357.9 pips. For the break it is second smallest at 569.7, behind the tolerance at 322.1.

The two that move it most are the break's swing strength (1,970.7) and lookback (1,524.3), and both improve in the direction that produces more lines. A swing strength of 2 makes almost every high and low a swing; a lookback of 400 keeps old lines alive.

This measurement cannot separate the lines working from the trade count rising. What it does show is that the settings which make a line more line-like, how many times it held and how close two touches must be, moved the result less than the settings that make more of them.

Last year's winner, this year

The setting with the highest annual pips in one year, run in the other, with its rank among the 216 (two readings by 108 definitions):

TimeframePicked inSettingPips that yearPips the other yearRankMedian that year
15-minute2024Break, 100/2/0.5/3+3,513.9+488.626th-1,531.7
15-minute2025Bounce, 100/5/0.5/4+2,194.7+2,983.44th-113.8
Hourly2024Break, 200/2/1.0/2+3,247.4+339.867th-394.6
Hourly2025Break, 400/2/0.25/4+2,323.4+377.2148th+1,033.2
4-hour2024Break, 200/8/1.0/3+3,237.1-1,205.0170th-314.8
4-hour2025Bounce, 400/8/1.0/4+2,569.7+1,463.477th+962.1

Four of the six beat the other year's median. The 15-minute chart held up in both directions, at 26th and 4th; the 4-hour 2024 pick fell to 170th.

The default setting moves just as far. The 4-hour bounce ranked 6th of 216 in 2024 with +2,794.6 pips and 72nd in 2025 with +278.8. The 4-hour break ranked 204th in 2025 at -1,883.7 and 15th in 2024 at +2,436.1. One setting, one timeframe, 6th and 72nd, 204th and 15th.

What the spread takes

A losing year can be the line failing or the round trips costing too much. Profitable counts at a zero spread first, then at 0.3 pips:

ReadingTimeframeYearProfitableMedianMedian trades
Bounce15-minute202494 → 49+1,339.7 → -99.14,738.5
BounceHourly202539 → 21-545.6 → -987.71,428.0
Bounce4-hour202561 → 57+224.9 → +154.8364.5
Bounce4-hour202493 → 91+912.5 → +845.2196.0
Break15-minute202557 → 32+172.7 → -760.32,739.5
BreakHourly202566 → 61+472.9 → +230.4751.5

The 15-minute bounce falls from 94 profitable settings to 49 on the spread alone in 2024, with the median going from +1,339.7 pips to -99.1. At a median 4,738.5 trades, the spread costs 1,421.5 pips.

On the 4-hour chart it falls from 93 to 91, because the median is 196 trades. Cost is trade count times spread, which this series finds every time.

Notes on scope

  • USD/JPY only, 2024 and 2025, on the 15-minute, 1-hour and 4-hour charts
  • Fills at the close, spreads of 0.3 pips and 0, 0.1 lots, no slippage
  • The condition draws nothing on the chart; these are lines computed inside the backtester
  • The offset control matches the signal-time distance but not the number of signals, and the reshuffled control reads both series on the close alone

Questions people ask

Does a line that has held more times hold better?
Not here. Splitting the bounce signals by the line's touch count gives 50.13% for three, 49.24% for four and 50.10% for five or more on the 15-minute long side; the short side stays between 50.20% and 50.25%. Of the four settings that define a line, the touch count moved the median year least.
Is it better to trade the bounce or the break?
By settings profitable in both years the break wins on the hourly chart, 58 of 108 against the bounce's 19. On the 4-hour chart it reverses: bounce 50, break 23. Win rates are 25.45% to 31.08% for the break and 38.26% to 42.80% for the bounce, so neither clears 50%.
Is price at a level a special state?
Not really. Price sits inside a line's tolerance band, half an ATR by default, on 41.40% to 65.75% of bars depending on the timeframe and the year. Roughly one bar in two.
How should the lookback and the swing strength be set?
For the break reading, a longer lookback and a smaller swing strength did better. On the hourly chart in 2025, a lookback of 100 left 13 of 36 settings profitable with a median of -521.9 pips; 400 left 28 and +1,002.4. A swing strength of 2 left 24 of 27 at +1,148.5 pips, and 8 left 3 at -822.2. Both changes make more lines, so this measurement cannot separate the lines working from the trade count rising.
Can I test horizontal lines in Formiq?
Yes. Enable the horizontal-line condition in the condition list and it takes the reading, lookback, swing strength, tolerance and minimum touch count. All 5,184 runs here were built that way. The chart has no way to draw these lines yet.

Formiq is a free browser-based FX terminal with replay practice and no-code backtesting. Open the chart or see what the free plan includes.