11 — Bilateral & Wedge

Symmetric Triangle#

BilateralHeuristic1 min read
◆ The PatternConverging trendlines, no bias — the market is deciding

The Symmetric Triangle has converging trendlines with lower highs and higher lows — the market is compressing, undecided. It can break either way. Most often continues the prior trend direction, but always wait for confirmation.

Target = Breakout point ± Width at base
Breakout typically occurs between 50-75% of the way to the apex. Breakouts too close to the apex often fail.
// Symmetric Triangle — converging to apex
Key insight: Volume should progressively decrease as the triangle tightens. The breakout direction becomes the prevailing trend — don't try to predict, react.
Pattern bridge: Both sides converge to a point of maximum compression. In ML, the bias-variance sweet spot sits at the convergence of two opposing forces.
Worked example

Highs falling (112, 108, 105) and lows rising (92, 96, 99), using swings over five bars. The widest part is 112 − 92 = 20. Day 21 closes at 107, above the last high, so the measured move is 107 + 20 = 127.

The example data

The turning points the daily closes run through, in straight lines between them; high and low are half a point either side of each bar.

DayClose
0100
3112
692
9108
1296
15105
1899
21107
Where it misleads
  • It has no direction until it breaks; reading the prior trend into it is a guess.
  • Edwards and Magee found breaks most reliable between half and three-quarters of the way to the apex; late breaks are weaker.
  • False breaks that fall back into the triangle are common.
In code
def swings(s, n=2):                     # a swing high (low) is the extreme of the 2n+1 bars around it
    w = s.rolling(2 * n + 1, center=True)
    return s[s == w.max()], s[s == w.min()]
c = df['close']
highs, lows = swings(c)
hi, lo = highs.iloc[-3:], lows.iloc[-3:]
symmetric = hi.is_monotonic_decreasing and lo.is_monotonic_increasing
height = hi.iloc[0] - lo.iloc[0]                     # the widest part
breakout = c.iloc[-1] > hi.iloc[-1]
target = c.iloc[-1] + height
Python, in your browser — edit the code and run it again

Assumes import numpy as np, import pandas as pd, and a DataFrame df with columns open, high, low and close for the data above.

Sources
  • Technical Analysis of Stock Trends, R. D. Edwards & J. Magee, 1948 (later editions revised by W. H. C. Bassetti)
  • Encyclopedia of Chart Patterns (2nd ed.), T. N. Bulkowski, Wiley, 2005 — success and failure rates from large counts of patterns

Last reviewed October 2026 · How this site checks its content · Report a mistake

Linked from 1
← Previous
Descending Triangle
Open in the full reader, with the topic sidebar