22 — Structural Analysis

Trendlines#

DiagonalHeuristic1 min read
◆ The PatternConnecting swing points — the direction of price flow

Trendlines connect swing lows in an uptrend (ascending support) or swing highs in a downtrend (descending resistance). A valid trendline touches at least 3 points. The more touches and the longer the line, the more significant its break.

≥3 touches = valid · Steeper = less sustainable · Break = signal
Draw trendlines from body to body (closes not wicks) for more reliable levels, though both methods have advocates.
// Trendline construction — connecting swings
Key insight: Trendlines that are too steep are unsustainable — an angle depends on how the chart is scaled, so there is no “right” slope — but steeper trendlines do break sooner and are replaced by shallower ones.
Pattern bridge: Drawing a line through successive highs or lows is literally linear regression — the same best fit computed in statistics.
Worked example

Swing lows at 100 (day 4) and 104 (day 12) define a line rising 0.5 a day. Projected to day 20 it gives 108, and the third low lands exactly there: the line held. On day 24 the line is at 110, and the close of 113 is above it.

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
0103
4100
8107
12104
16111
20108
24113
Where it misleads
  • Two points always make a line; only the third touch tests it, and which lows to connect is a judgement call.
  • Steep lines break quickly, and their breaks say little.
  • On growing assets a straight line on a price scale eventually breaks; a log scale gives a different line.
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)
(x1, y1), (x2, y2) = list(lows.iloc[:2].items())      # the first two rising lows
slope = (y2 - y1) / (x2 - x1)
line = lambda x: y1 + slope * (x - x1)
x3, y3 = lows.index[2], lows.iloc[2]                  # the third low tests the line
held = y3 >= line(x3) * 0.99
broken = c.iloc[-1] < line(len(c) - 1)
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)
  • Technical Analysis of the Financial Markets, J. J. Murphy, New York Institute of Finance, 1999

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

Linked from 2
← Previous
Support & Resistance
Open in the full reader, with the topic sidebar