09 — Continuation Patterns

Ascending Triangle#

BullishHeuristic1 min read
◆ The PatternFlat resistance + rising lows = buyers pressing higher

The Ascending Triangle has a flat resistance level and a rising lower trendline. Buyers are willing to pay increasingly higher prices. When resistance finally breaks, the measured move equals the triangle's height at its widest point.

Target = Breakout + Height of triangle base
Usually read as bullish — but published success rates vary, so wait for a close above resistance.
// Ascending Triangle — flat top, rising lows
Key insight: Each touch of resistance weakens it — like repeatedly hitting a wall. The rising lows show buyers becoming more aggressive with each dip.
Pattern bridge: Rising lows against a flat ceiling — pressure building. Same dynamic as optimizer momentum accumulating against a loss plateau.
Worked example

Three swing highs at 110 — a flat ceiling — and rising swing lows at 100, 104 and 107. Day 27 closes at 114, above the ceiling. The widest part is 110 − 100 = 10, so the target is 110 + 10 = 120.

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
095
4110
8100
12110
16104
20110
24107
27114
Where it misleads
  • The ceiling can hold; rising lows do not guarantee a break, and a close back under the ceiling after a break is a common failure.
  • “Flat” needs a tolerance (1% here), and which triangles you find depends on it.
  • Bulkowski’s counts show ascending triangles also break downward a meaningful share of the time.
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)
top, rises = highs.iloc[-3:], lows.iloc[-3:]
flat_top = (top.max() - top.min()) / top.mean() < 0.01
rising = rises.is_monotonic_increasing
height = top.mean() - rises.iloc[0]
breakout = c.iloc[-1] > top.max()
target = top.mean() + 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
  • 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

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