03 — Reversal Patterns

Double Top#

Bearish — MHeuristic1 min read
◆ The PatternTwo peaks at the same level — the "M" formation

The Double Top forms when price hits resistance twice and fails to break through. The two peaks form an "M" shape. Breakdown below the trough between peaks (the neckline) confirms the bearish reversal.

Target = Neckline − (Peak − Neckline)
The two peaks don't need to be identical — a difference of ~3% is acceptable. Time between peaks varies from weeks to months.
// Double Top — M formation
Key insight: The second peak often shows lower volume than the first — a sign that buying enthusiasm is fading even though price reaches the same level.
Pattern bridge: Two failed attempts at the same level — like a ReLU-clipped activation hitting a ceiling. In statistics, repeated failed tests at the same significance level tell you the effect isn’t there.
Worked example

Tops at 110 (day 6) and 109.5 (day 17), within 0.5% of each other, with a valley at 100 between. The pattern exists only once the price closes below the valley, as it does on day 22 (99). Measured move: 100 − (110 − 100) = 90.

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
090
6110
11100
17109.5
2299
2694
Where it misleads
  • Until the valley breaks it is just two similar highs, and in an uptrend those are often followed by a third, higher one.
  • How equal is “equal” is a choice (2% here); loosen it and double tops appear everywhere.
  • After the break the price often comes back to test the valley from below.
In code
def swings(s, n=3):                     # 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)
t1, t2 = highs.iloc[-2:]
valley = lows[(lows.index > highs.index[-2]) & (lows.index < highs.index[-1])].min()
is_dt = abs(t1 - t2) / max(t1, t2) < 0.02            # tops within 2%
target = valley - (max(t1, t2) - valley)
confirmed = c.iloc[-1] < valley
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
  • Encyclopedia of Chart Patterns (2nd ed.), T. N. Bulkowski, Wiley, 2005 — success and failure rates from large counts of patterns
  • Technical Analysis of Stock Trends, R. D. Edwards & J. Magee, 1948 (later editions revised by W. H. C. Bassetti)

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

Check yourself

1. Two peaks of similar height have formed. When is the double top complete?

Show answer

B. Two similar highs are common inside ordinary uptrends; the break of the valley is what separates a reversal from a pause.

2. What is the classic target after the break?

Show answer

B. Like other measured moves, it is a convention for planning, not a probability.

3. Why do traders insist on the break before acting?

Show answer

A. Confirmation trades a later entry for fewer false signals.

Linked from 1
← Previous
Inverse Head & Shoulders
Open in the full reader, with the topic sidebar