Strategies we backtested trendline breakout

Tested by BacktestingMax

Trendline breakout strategy backtest

Does the trendline breakout strategy make money?

Mostly no: it lost money in 18 of the 30 backtests we ran. On 4-hour charts, it made money on 8 of the 10 markets, but the gains were small. The trendline breakout strategy buys when a candle closes above a falling line, called a down-trendline, drawn through the last two swing highs (peaks). It sells short (sells first, to profit if price falls) when a candle closes below a rising line, called an up-trendline, drawn through the last two swing lows (dips). We tested these basic rules from 2014 to 2025, with trading costs, on 10 markets (6 currency pairs, gold and 3 stock indices), each on 15-minute, 1-hour and 4-hour charts. On 1-hour charts, the strategy made money on 4 of the 10 markets. On 15-minute charts, it lost money on all 10: before trading costs, the average trade made close to zero, and the costs turned that into a loss. We also split the test in two, to see if the strategy kept working in the newer years. Only 5 tests made money in both 2014–2021 and 2022–2025, and 3 of them were on 4-hour charts. Of 3 common changes we tried, a 200 EMA trend filter did best. With this filter, the strategy only buys when the breakout candle closes above the 200 EMA (a moving average of the last 200 candles), and only sells when the breakout candle closes below the 200 EMA. With the filter, 8 tests made money in both periods, compared with 5. But over the whole test, the strategy with the filter still made money in 12 of 30 tests, the same as with the basic rules.

30 backtests 2014–2025 Trading costs included Tested 12 October 2026

Where it worked 30 backtests
Made money
12
of 30 tests, with the basic rules
Made money in both periods
5
2014–2021 and again 2022–2025
Best backtest
+71%
Nasdaq 100, 1-hour chart: account growth 2014–2025
With a 200 EMA trend filter
8
tests made money in both periods, compared with 5 with the basic rules

Made money in both periods

  • EUR/USD, 4-hour
  • GBP/USD, 4-hour
  • USD/JPY, 1-hour
  • Gold, 4-hour
  • Nasdaq 100, 1-hour

Lost money on every market

  • 15-minute charts

The results

Results on every market

Each box shows one backtest of the trendline breakout with the basic rules, from 2014 to 2025, after trading costs: the % result, and a small chart of the account balance. The solid line is the account balance and the dashed line is the starting balance. Green results made money; red results lost money. Under each result: whether it made money in both 2014–2021 and 2022–2025, or passed all four of our checks (see "How a test passes" further down).

Market 15-minute 1-hour 4-hour
EUR/USD −97% Lost money. Account down 90% by Nov 2021 −26% Lost money +32% Passed all four checks
GBP/USD −91% Lost money. Account down 90% by Jul 2025 −42% Lost money +63% Made money in both periods
USD/JPY −72% Lost money +14% Made money in both periods +22% Made money overall, lost in one period
AUD/USD −94% Lost money. Account down 90% by Feb 2022 −39% Lost money −40% Lost money
USD/CAD −96% Lost money. Account down 90% by Aug 2023 −68% Lost money −21% Lost money
GBP/JPY −97% Lost money. Account down 90% by Nov 2020 +25% Made money overall, lost in one period +13% Made money overall, lost in one period
Gold −62% Lost money −30% Lost money +25% Made money in both periods
S&P 500 −94% Lost money. Account down 90% by Oct 2023 −9% Lost money +2% Made money overall, lost in one period
Nasdaq 100 −90% Lost money. Account down 90% by Nov 2022 +71% Made money in both periods +46% Made money overall, lost in one period
DAX −63% Lost money +7% Made money overall, lost in one period +6% Made money overall, lost in one period
All the numbers, test by test
Market Chart Trades Win rate Profit factor Result Max drawdown 2014–2021 2022–2025 Monte Carlo drawdown Trading costs
EUR/USD 15-minute 3,253 31.6% 0.85 −97.2% −97.4% −89.3% −73.9% −98.0% $4,676
EUR/USD 1-hour 756 33.3% 0.94 −25.7% −49.5% −34.0% +12.7% −54.0% $1,698
EUR/USD 4-hour 219 38.8% 1.22 +32.0% −10.7% +9.2% +20.8% −20.5% $370
GBP/USD 15-minute 3,030 33% 0.91 −91.4% −92.8% −61.4% −77.7% −94.7% $9,435
GBP/USD 1-hour 761 32.2% 0.90 −41.9% −44.9% −22.7% −24.8% −60.2% $1,803
GBP/USD 4-hour 244 41.4% 1.37 +63.2% −18.1% +48.0% +10.3% −17.7% $481
USD/JPY 15-minute 3,137 34.2% 0.97 −71.9% −87.1% −45.6% −48.3% −86.9% $17,973
USD/JPY 1-hour 864 34.8% 1.02 +14.1% −22.2% +9.6% +4.1% −45.0% $2,487
USD/JPY 4-hour 200 37% 1.15 +22.0% −22.4% +33.9% −8.9% −21.0% $274
AUD/USD 15-minute 3,361 33.6% 0.90 −94.4% −95.1% −89.7% −45.4% −96.5% $10,468
AUD/USD 1-hour 819 33% 0.90 −38.6% −53.8% −38.5% −0.2% −59.5% $1,993
AUD/USD 4-hour 222 26.1% 0.66 −39.8% −40.6% −35.8% −6.3% −46.8% $316
USD/CAD 15-minute 3,095 32.7% 0.90 −95.9% −96.6% −85.2% −72.3% −97.2% $10,428
USD/CAD 1-hour 822 30.3% 0.76 −68.1% −68.3% −59.2% −21.9% −75.3% $1,836
USD/CAD 4-hour 261 31.4% 0.88 −20.5% −28.1% −8.5% −13.1% −37.5% $520
GBP/JPY 15-minute 3,589 33% 0.82 −97.4% −97.8% −91.2% −70.9% −98.2% $6,812
GBP/JPY 1-hour 879 36.4% 1.04 +25.0% −27.2% +35.6% −7.8% −44.1% $4,580
GBP/JPY 4-hour 145 37.2% 1.16 +12.6% −12.4% −5.4% +19.1% −18.7% $252
Gold 15-minute 3,261 35.4% 0.95 −61.6% −74.9% −67.1% +16.8% −83.3% $15,413
Gold 1-hour 828 33.9% 0.91 −29.7% −51.2% −48.3% +35.9% −54.5% $2,154
Gold 4-hour 232 37.5% 1.17 +25.4% −12.0% +20.8% +3.8% −21.3% $628
S&P 500 15-minute 2,795 32.1% 0.84 −94.1% −95.1% −84.6% −61.7% −96.1% $6,340
S&P 500 1-hour 722 34.5% 0.98 −9.4% −27.9% +12.3% −19.4% −48.3% $2,216
S&P 500 4-hour 228 34.6% 1.02 +2.2% −16.7% −8.0% +11.1% −28.0% $319
Nasdaq 100 15-minute 3,216 33.7% 0.83 −90.1% −92.4% −88.7% −12.7% −94.1% $8,089
Nasdaq 100 1-hour 765 36.5% 1.11 +70.8% −22.9% +26.6% +34.9% −36.5% $3,061
Nasdaq 100 4-hour 235 39.6% 1.26 +46.4% −16.4% +58.4% −7.6% −18.0% $535
DAX 15-minute 2,760 35.1% 0.93 −63.3% −81.7% −71.2% +27.2% −89.9% $3,618
DAX 1-hour 811 34.4% 1.01 +6.8% −23.4% +25.1% −14.6% −44.4% $1,146
DAX 4-hour 226 35% 1.04 +5.6% −21.3% +8.4% −2.6% −23.9% $174

Profit factor is the money won divided by the money lost. Above 1 means the test made money. Max drawdown is the biggest fall from the highest balance. 2014–2021 and 2022–2025 show the result in each period on its own. Monte Carlo drawdown: we shuffled the trades into a random order 1,000 times; in 95% of those runs, the worst drawdown was this number or less. Result is the change in the account, with the risk of each trade set to 1% of the account at that time.

The account balance

The best test and the middle test

Best test Nasdaq 100, 1-hour chart +70.8% from 2014 to 2025
Middle test (median): half of the 30 did better, half did worse EUR/USD, 1-hour chart −25.7% from 2014 to 2025

What we found

What the 30 backtests show

  1. On 15-minute charts, the trendline breakout lost money on all 10 markets. The change in the account went from −61.6% (gold) to −97.4% (GBP/JPY). In 7 of the 10 tests, the account was down more than 90% from its starting balance at some point. Before trading costs, the average 15-minute trade made close to zero. The trading costs took about 7% of the money each trade risked, on average, and those costs turned the result into a loss.

  2. On 4-hour charts, the strategy made money on 8 of the 10 markets. Only AUD/USD and USD/CAD lost money. 3 of the 8 made money in both 2014–2021 and 2022–2025: EUR/USD, GBP/USD and gold. EUR/USD on 4-hour charts also passed all four of our checks (see 'How a test passes' further down). But the gains were small: after trading costs, the average 4-hour trade made 5.6% of the money it risked. On 1-hour charts, the results were weaker: 4 of 10 tests made money, and 2 of them made money in both periods: USD/JPY and the Nasdaq 100. The best backtest was the Nasdaq 100 on 1-hour charts: the account grew 70.8% from 2014 to 2025, and at one point it was 22.9% below its highest balance.

  3. The stop-loss goes at the most recent swing low (the most recent swing high for a sell), so its distance from the entry changes from trade to trade. Trades with the stop-loss close to the entry lost the most. We sorted all the trades of the basic rules into three groups by that distance, measured in ATR (average true range: the size of an average candle). R is the risk of one trade: the money it loses if the stop-loss is hit, which is 1% of the account. With the stop-loss less than 2 ATR away, every 100 trades lost 9.5R after trading costs. With the stop-loss 2 to 3 ATR away, every 100 trades lost 2.6R. With the stop-loss 3 ATR or more away, every 100 trades lost 2.4R. In all three groups, about the same share of trades won: 33.5% to 34.0%. The results were different mostly because of the trading costs (see the chart below). Breakouts of steep trendlines lost more too: steep lines more often had a nearby swing low.

  4. On 4-hour charts, trades often stayed open for days or weeks, because the stop-loss and the 2R take-profit were often far from the entry. Half of the trades on 4-hour charts lasted less than 4.4 days, and half lasted longer. 36% of the 4-hour trades stayed open more than a week. The longest, a USD/JPY buy from March 2020, stayed open 579 days. The trades that stayed open more than a week made 302.5R in total, and all the shorter trades together lost 179.0R. So the 4-hour profit came from the trades that stayed open more than a week. Our test includes trading costs (the spread: the gap between the buy price and the sell price), but not the overnight fee (swap) that most brokers charge for each night a trade stays open. Those long trades would usually pay the most in overnight fees, so a real account would likely make less than this backtest.

  5. Two common changes did not help on 4-hour charts. Waiting for the next candle to also close beyond the line cut the average result of a 4-hour trade from 0.056R (the 5.6% above) to 0.007R, and 6 of 10 tests made money with it, compared with 8 with the basic rules. Removing the 2R take-profit, and holding each buy until a candle closed below an up-trendline (each sell until a candle closed above a down-trendline), made less money on 4-hour charts. The average trade fell from 0.056R to 0.008R, and 5 of the 10 tests made money, compared with 8. The winning trades were smaller: 1.54R on average, compared with 1.87R with the take-profit (see the comparison below).

Stop-loss distance

Trades with the stop-loss close to the entry lost the most

This chart sorts all 41,736 trades from the 30 tests with the basic rules, from 2014 to 2025, into three groups by the distance from the entry to the stop-loss. The distance is measured in ATR: the size of an average candle over the last 14 candles. Each bar shows the result per 100 trades, in R, after trading costs. For example, −9.5R means that every 100 trades lost 9.5 times the amount risked on one trade.

  • Stop-loss less than 2 ATR away14,672 trades, 33.5% won, trading costs: 10.4% of the money risked, on average −9.5R
  • 2 to 3 ATR away11,892 trades, 34.0% won, trading costs: 4.3% of the money risked, on average −2.6R
  • 3 ATR or more away15,172 trades, 33.5% won, trading costs: 2.5% of the money risked, on average −2.4R

On each market, every trade pays the same trading cost in price (the spread: the gap between the buy price and the sell price), however far away the stop-loss is. When the stop-loss is close to the entry, the spread is a bigger share of the distance to the stop-loss, so the trading cost takes a bigger share of the money risked. Before trading costs, all three groups were close to zero: from +0.1R to +1.7R per 100 trades. The trades with the stop-loss less than 2 ATR away did worst on each of the three timeframes (15-minute, 1-hour and 4-hour charts), and in both 2014–2021 and 2022–2025. On 4-hour charts, the result per 100 trades was −2.5R with the stop-loss less than 2 ATR away, +7.4R with the stop-loss 2 to 3 ATR away, and +11.8R with the stop-loss 3 ATR or more away. On 4-hour charts, 37.9% of the trades with the stop-loss 3 ATR or more away won, compared with 33.2% of the trades with the stop-loss less than 2 ATR away. We also sorted all the trades into three groups of the same size by how steep the trendline was: how far the line moved per candle, compared with ATR. In the steepest third, half of the stop-losses were closer than 1.7 ATR, and every 100 trades lost 7.8R. In the flattest third, half of the stop-losses were closer than 3.3 ATR, and every 100 trades lost 3.6R. We did not test skipping the trades with a nearby stop-loss as a separate version.

Take profit or hold?

On 4-hour charts, removing the 2R take-profit made the winning trades smaller

These numbers use all the trades from the 10 tests on 4-hour charts, from 2014 to 2025, after trading costs. R is the amount a trade risks: 1% of the account. The basic rules take profit at 2R. The version with no take-profit exits a buy when a candle closes below an up-trendline, and exits a sell when a candle closes above a down-trendline.

Average winning trade, with the 2R take-profit (the basic rules)
+1.87R
35.8% of the 2,212 trades won.
Average winning trade, with no take-profit
+1.54R
32.8% of the 3,252 trades won.
Average trade, with the 2R take-profit
+0.056R
This average includes winners and losers. 8 of the 10 tests made money.
Average trade, with no take-profit
+0.008R
This average includes winners and losers. 5 of the 10 tests made money.

In the version with no take-profit, 1,982 of the 3,252 trades closed when the opposite trendline broke (the up-trendline for a buy), 1,268 closed at the stop-loss, and 2 were still open when the test ended. Only 12.5% of the trades that closed at the opposite trendline made 2R or more. The middle trade of that group (half made more, half made less) made almost nothing: +0.06R. 53 trades in that group made 5R or more (the biggest made 30.4R), but there were too few of them to beat the 2R take-profit. The version with no take-profit made more trades, because its trades closed sooner, and the rules skip any breakout while a trade is open. With the 2R take-profit, the winning trades made a little less than 2R on average. Each trade pays trading costs, and the position size is rounded down to a size the broker allows, so a trade can risk, and win, a little less than planned.

The strategy

What the trendline breakout is

A trendline is a straight line on a chart through two or more swing highs or swing lows. A swing high is a peak: a candle whose high is higher than the highs of the candles around it. A swing low is the opposite: a low point, a candle whose low is lower than the lows of the candles around it. When price is falling, each new swing high is often lower than the one before, so a line through the last two swing highs slopes down. Traders call it a down-trendline. While the fall continues, price stays below the down-trendline. When price is rising, a line through two rising swing lows slopes up: an up-trendline. A trendline breakout is a candle that closes above a down-trendline or below an up-trendline. The trendline breakout strategy trades these breakouts. A common way to trade it: buy when a candle closes above a down-trendline, because the fall may be over. Sell short (sell first, to profit if price falls) when a candle closes below an up-trendline.

Swing points
A candle with a higher high, or a lower low, than the 5 candles on each side
Trendline
Through the last two swing highs if the newer one is lower (a down-trendline), or through the last two swing lows if the newer one is higher (an up-trendline)
Entry
After the first candle that closes beyond the line, the trade opens at the next candle's open
Stop-loss
The most recent swing low for a buy, the most recent swing high for a sell
Take-profit
2R: twice the distance from the breakout candle's close to the stop-loss
Risk per trade
1% of the account

The rules we tested

  1. Find the swing points. A swing high is a candle whose high is higher than the highs of the 5 candles before it and the 5 candles after it. A swing low is a candle whose low is lower than the lows of the 5 candles on each side. A swing point is only known 5 candles later, so the test only uses it after those 5 candles have closed.
  2. Draw a down-trendline through the last two swing highs, if the newer one is lower than the older one, and extend it to the right. The line is drawn when the second swing high becomes known. The test does not use the line if a candle already closed above it between the first swing high and the moment the line is drawn. Each new swing high ends the old line. If the new swing high is lower than the one before, a new line goes through these two. If it is higher, there is no down-trendline until the next swing high.
  3. Buy when a candle closes above the down-trendline. Each line gives one signal: the first close above it. The trade opens at the next candle's open.
  4. Put the stop-loss at the most recent swing low. If that swing low is at or above the breakout candle's close, skip the trade.
  5. Take profit at 2R. On the chart, 1R is the distance from the breakout candle's close to the stop-loss. A loss of that size costs 1% of the account. So the take-profit is 2 times that distance above the close.
  6. Sell short in the opposite case. Draw an up-trendline through the last two swing lows, if the newer one is higher. Sell when a candle closes below it, put the stop-loss at the most recent swing high, and take profit at 2R below the close.
  7. Only one trade is open at a time. If a trade was still open at any time during the breakout candle, the test skips that breakout, and that trendline gives no more signals. If the same candle closes above the down-trendline and below the up-trendline, there is no trade.
  8. Size every trade so that a loss at the stop-loss costs 1% of the account. The size uses the distance from the breakout candle's close to the stop-loss. The size is rounded down to a size the broker allows, so a trade can risk a little less than 1%. If even the smallest size the broker allows would risk more than 1%, the test skips the trade.

The method

How we tested it

The test

Markets
EUR/USD, GBP/USD, USD/JPY, AUD/USD, USD/CAD, GBP/JPY, Gold, S&P 500, Nasdaq 100 and DAX
Charts
15-minute, 1-hour and 4-hour candles
Dates
January 2014 to December 2025
Account
$10,000, risking 1% of the account on each trade
Trading costs
Included. Every trade pays that market's normal trading cost: the spread, which is the gap between the buy price and the sell price.

How a test passes

We call a test passed only if it meets all four checks. A strategy can make money in one backtest and still fail one of these checks.

  • At least 100 trades. With fewer trades, a good result could be luck.
  • It made money from 2014 to 2021 and again from 2022 to 2025. This shows whether the strategy kept working in the newer years, not only in the older ones.
  • A profit factor (the money won divided by the money lost) of at least 1.2 from 2022 to 2025, after trading costs.
  • In 95% of 1,000 random shuffles of the trades, the account must not fall more than 30% from its highest point.

Improvements

Can the trendline breakout be improved?

We tried three changes traders often make to the trendline breakout strategy. Each change makes a new version of the strategy, and the table shows the basic rules and the three changed versions. The changes are: only buying when the breakout candle closes above the 200 EMA and only selling when the breakout candle closes below the 200 EMA, waiting for a second close beyond the line, and removing the 2R take-profit to hold each trade until the opposite trendline breaks. We ran each version on the same 30 tests. To pick the best change, we looked only at 2014–2021: the change that made money in the most tests won. If two changes tied, the one with the better middle test won. Then we checked it on 2022–2025, the years we did not use to pick it. A change picked on the same years it is judged on almost always looks better than it is.

Version Made money 2014–2021years used to pick the best version Made money 2022–2025years not used to pick it Made money in both periods Passed all four checks
The basic rules: the first close beyond the line The rules in 'The rules we tested' above, with nothing changed. 11 of 30middle test −28.4% 11 of 30middle test −7.7% 5 1
With a 200 EMA trend filterBest on 2014–2021 The 200 EMA is a moving average of the last 200 candles that gives more weight to recent candles. Only buy when the breakout candle closes above the 200 EMA, and only sell short when the breakout candle closes below the 200 EMA. So the strategy only buys when a fall may be over and the bigger trend is up, and only sells when a rise may be over and the bigger trend is down. 11 of 30middle test −9.9% 14 of 30middle test −6.9% 8 3
Wait for a second close beyond the line Don't trade the first close above the down-trendline. Buy only if the next candle also closes above the line, and then buy at the open of the following candle. The stop-loss is still the most recent swing low, and 1R and the 2R take-profit are measured from the second candle's close. For a sell, do the opposite. On daily charts, some traders call this the two-day rule. 10 of 30middle test −20.4% 11 of 30middle test −10.1% 6 3
No take-profit: hold until the opposite trendline breaks Remove the 2R take-profit. Exit a buy when a candle closes below an up-trendline (the rule that opens a sell in the basic rules), and exit a sell when a candle closes above a down-trendline. The trade closes at the next candle's open. The stop-loss is still the most recent swing low (the most recent swing high for a sell). The break that closes a trade does not open a new one. 11 of 30middle test −29.2% 11 of 30middle test −8.1% 5 1

Only a little. The best change, the 200 EMA trend filter, made money in both periods in 8 tests instead of 5. But over the whole test, the strategy with the filter still made money in 12 of 30 tests, the same as with the basic rules, and it still lost money on all 10 markets on 15-minute charts. In 2014–2021, the years we used to pick the best change, the basic rules made money in 11 of 30 tests, and no change did better. The 200 EMA trend filter and the version with no take-profit both made money in 11. The middle test (half of the 30 did better, half did worse) broke the tie: −9.9% with the filter, compared with −29.2% with no take-profit and −28.4% with the basic rules. So we picked the filter. In 2022–2025, the years we kept for the check, 14 of 30 tests made money with the filter, compared with 11 with the basic rules. The middle test was −6.9% with the filter, compared with −7.7% with the basic rules. 6 of the 8 tests that made money in both periods with the filter were on 4-hour charts: EUR/USD, GBP/USD, USD/JPY, gold, the S&P 500 and the Nasdaq 100. The filter skipped 23% of the trades: 32,101 instead of 41,736.

Passed all four checks with a 200 EMA trend filter

  • USD/JPY, 4-hour
  • S&P 500, 4-hour
  • Nasdaq 100, 1-hour

Questions

Questions traders ask

Does the trendline breakout strategy work?

Mostly no. In our backtest from 2014 to 2025, with trading costs, the strategy's basic rules (with none of our changes) made money in 12 of 30 tests: 10 markets, each on 15-minute, 1-hour and 4-hour charts. 8 of those 12 were on 4-hour charts. Only 5 tests made money in both 2014–2021 and 2022–2025: EUR/USD, GBP/USD and gold on 4-hour charts, and USD/JPY and the Nasdaq 100 on 1-hour charts. Even on 4-hour charts, the gains were small: the average trade made 5.6% of the money it risked.

What is the best timeframe for trendline breakouts?

In our test, 4-hour charts did best: the strategy made money on 8 of 10 markets, more than on any other timeframe. It made money on 4 of 10 markets on 1-hour charts, and on none of the 10 on 15-minute charts. On 15-minute charts, the trading costs took about 7% of the money each trade risked, on average, and that turned the result into a loss. We also tested daily charts, but with the basic rules, the strategy made only 29 to 52 trades per market from 2014 to 2025. That is fewer than the 100 trades we need to judge a test, so daily charts are not in the results.

Is a trendline breakout better than a support and resistance breakout?

In our tests, the trendline breakout made money on more markets than the support and resistance breakout, on 1-hour and 4-hour charts. We also backtested a support and resistance breakout on the same 10 markets, from 2014 to 2025, with the same 2R take-profit as the trendline breakout. Resistance is a narrow band of prices where rising prices stopped and turned down before, and support is a band where falling prices stopped and turned up. The support and resistance breakout buys on a close above resistance and sells on a close below support. On 1-hour charts, the support and resistance breakout lost money on all 10 markets, while the trendline breakout made money on 4. On 4-hour charts, the support and resistance breakout made money on 5 of 10 markets, and the trendline breakout on 8. The support and resistance test used 1-hour, 4-hour and daily charts, so we can't compare 15-minute charts. The two tests also put the stop-loss in different places, so this compares the two strategies as we tested them, not only the two kinds of line.

Should you wait for a second candle to close above the trendline?

Not in our test. With the basic rules, the strategy buys after the first close above the line. When it waited for the next candle to close above the line too, the strategy made money in 9 of 30 tests, compared with 12 with the basic rules. On 4-hour charts, the average trade fell from 0.056R to 0.007R (R is the amount a trade risks: 1% of the account), and 6 of 10 tests made money instead of 8. Over all 30 tests, it made money in both 2014–2021 and 2022–2025 in 6 tests, compared with 5 with the basic rules, and 3 tests passed all four of our checks with it, compared with 1. But it made money in fewer tests overall, and on 4-hour charts its average trade was much smaller.

The strategy code we ran

This is the exact code from the BacktestingMax strategy engine. Paste it into the strategy editor in the app to run it on any market.

class TrendlineBreakout(Strategy):
    """Trendline breakout, drawn the way most traders draw it, plus three changes traders make.
    Swing points. A swing high is a candle whose high is higher than the highs of the 5 candles
    before it and the 5 candles after it, so it is only known 5 candles later. A swing low is
    the mirror image.
    The lines. A down-trendline runs through the last two swing highs, when the newer one is
    lower, and is extended to the right. It is drawn when the second swing high is confirmed,
    and only if no candle since the first swing high closed above it. Each new swing high
    replaces the line: through the last two swing highs if they fall, no line if they rise.
    An up-trendline is the mirror image, through the last two swing lows when the newer one
    is higher.
    Standard (all switches off): buy when a candle closes above the down-trendline. Each line
    gives one signal, its first close above. The stop-loss is the most recent swing low (no
    trade if it is not below the close) and the take-profit is 2 times the risk (2R). Sell
    short on the first close below the up-trendline, stop at the most recent swing high, 2R.
    Size so the stop costs 1% of the account. One trade at a time: a break while a trade is
    open is skipped, and that line is used up.
    The changes, one at a time:
      trend     = 1   only buy when the breakout candle closes above the 200 EMA, only sell
                      when it closes below it
      confirm   = 1   wait for a second close beyond the line; enter after that candle, with
                      the stop and the 2R target measured from its close
      exit_line = 1   no take-profit: a buy stays open until the next close below an
                      up-trendline (the sell signal) or its stop-loss; sells mirror this
    """
    params = {"pivot_bars": Param(type=int, default=5, min=2, max=20),
              "target_r": Param(type=float, default=2.0, min=0.5, max=10.0),
              "trend": Param(type=int, default=0, min=0, max=1),
              "confirm": Param(type=int, default=0, min=0, max=1),
              "exit_line": Param(type=int, default=0, min=0, max=1)}
    lookback = 1000
    def init(self, ctx):
        n = ctx.params.pivot_bars
        self.ph = ctx.pivot_high(source=ctx.high, left=n, right=n)
        self.pl = ctx.pivot_low(source=ctx.low, left=n, right=n)
        self.ema = ctx.ema(source=ctx.close, period=200)
        self.highs = []          # (bar index, price) of the last two swing highs
        self.lows = []           # the same for swing lows
        self.down = None         # the live down-trendline: (bar 1, price 1, bar 2, price 2)
        self.up = None           # the live up-trendline
        self.pending = None      # confirm version: (side, line) waiting for the second close
    @staticmethod
    def level(line, i):
        """The line's price on bar i: through both swing points, extended to the right."""
        b1, p1, b2, p2 = line
        return p2 + (p2 - p1) / (b2 - b1) * (i - b2)
    def new_line(self, ctx, pivots, falling):
        """The line through the last two swing points, if they fall (highs) or rise (lows) and
        no candle since the first one closed beyond it. Otherwise None."""
        if len(pivots) < 2:
            return None
        (b1, p1), (b2, p2) = pivots[-2], pivots[-1]
        if (falling and p2 >= p1) or (not falling and p2 <= p1):
            return None
        line = (b1, p1, b2, p2)
        i = ctx.bar_index
        for k in range(1, i - b1):  # the candles from b1 + 1 to the one before this one
            c = ctx.close[k]
            if c is None:
                break
            lv = self.level(line, i - k)
            if (falling and c > lv) or (not falling and c < lv):
                return None
        return line
    def enter(self, ctx, side):
        entry = ctx.close[0]
        p = ctx.params
        if side > 0:
            stop = self.lows[-1][1] if self.lows else None
            if not ctx.gate("stop_below_close", stop is not None and stop < entry):
                return
            tp = None if p.exit_line == 1 else entry + p.target_r * (entry - stop)
            ctx.buy(size=ctx.size_by_risk_pct(0.01, stop=stop, entry=entry), sl=stop, tp=tp,
                    tag="trendline_break_long")
        else:
            stop = self.highs[-1][1] if self.highs else None
            if not ctx.gate("stop_above_close", stop is not None and stop > entry):
                return
            tp = None if p.exit_line == 1 else entry - p.target_r * (stop - entry)
            ctx.sell(size=ctx.size_by_risk_pct(0.01, stop=stop, entry=entry), sl=stop, tp=tp,
                     tag="trendline_break_short")
    def on_bar(self, ctx):
        p = ctx.params
        i = ctx.bar_index
        # Read the swing points on every candle, before any return.
        hi, lo = self.ph.value, self.pl.value
        ema = self.ema.value
        if hi is not None:
            self.highs = (self.highs + [(i - p.pivot_bars, hi)])[-2:]
            self.down = self.new_line(ctx, self.highs, True)
        if lo is not None:
            self.lows = (self.lows + [(i - p.pivot_bars, lo)])[-2:]
            self.up = self.new_line(ctx, self.lows, False)
        # Did this candle close beyond a live line? Each line gives one signal, then it is used up.
        c0 = ctx.close[0]
        down, up = self.down, self.up
        buy = down is not None and c0 > self.level(down, i)
        sell = up is not None and c0 < self.level(up, i)
        if buy:
            self.down = None
        if sell:
            self.up = None
        pending, self.pending = self.pending, None
        pos = ctx.position
        if pos is not None:
            # exit_line version: the opposite break closes the trade (at the next candle's open).
            if p.exit_line == 1 and ((pos.is_long and sell) or (pos.is_short and buy)):
                ctx.close_position()
            return
        # Confirm version: the candle after the breakout must close beyond the line too.
        if pending is not None:
            side, line = pending
            beyond = c0 > self.level(line, i) if side > 0 else c0 < self.level(line, i)
            if ctx.gate("second_close_beyond_line", beyond):
                self.enter(ctx, side)
                return
        if buy and sell:
            return  # one candle closed beyond both lines: no clear direction, no trade
        if not ctx.gate("close_breaks_trendline", buy or sell):
            return
        side = 1 if buy else -1
        if p.trend == 1:
            with_trend = ema is not None and (c0 > ema if side > 0 else c0 < ema)
            if not ctx.gate("with_200_ema_trend", with_trend):
                return
        if p.confirm == 1:
            self.pending = (side, down if side > 0 else up)
            return
        self.enter(ctx, side)

Your turn

Test the trendline breakout yourself

Change the settings, the market or the stop-loss and see the result in seconds. Ask the BacktestingMax AI: Backtest a trendline breakout on the Nasdaq 100, 1-hour chart, with the stop-loss at the last swing low, and skip trades where that stop-loss is less than 2 ATR away.

Try it free in BacktestingMax

Free account. No credit card needed.

See every strategy we tested Browse strategies shared by traders

Backtest on historical data with trading costs, run by BacktestingMax. Past results do not guarantee future results, and nothing here is financial advice. Updated 12 October 2026.