Market Structure
All plugins

Plugin libraryMarket structure

Plugin

Market Structure

Confirmed swing highs and lows without repainting, the trend they form (HH and HL or LH and LL), and the last break of structure and change of character.

IndicatorNo networkDesktop onlyv1.0.0

About

A swing high is a bar whose high is strictly above the highs of the length bars before it and the length bars after it; a swing low is the same with lows, strictly below. Equal highs or lows on either side make no swing. A swing is confirmed only when its length right hand bars have closed, and it is reported on that confirming bar, never earlier, so the indicator never redraws: what it says at a bar uses that bar and the ones before it only. A swing therefore always arrives length bars late.

Each new swing high is labelled HH (above the previous swing high), LH (below) or EH (equal); each swing low HL, LL or EL. The trend (value) is 1 when the last high is HH and the last low is HL, -1 when they are LH and LL, and 0 for any other mix.

A close above the last confirmed swing high, or below the last confirmed swing low, breaks structure; each swing level can be broken once, and wicks do not count. A break in the direction of the current bias, or the very first break, is a break of structure (BOS). A break against the bias is a change of character (CHoCH) and turns the bias. At most one break per bar: a close above the last high and below the last low at once (only possible when that low sits above that high) counts as the break up.

Parameters

NameTypeDefaultRange or optionsDescription
lengthint3min 1, max 50Bars on each side of a swing. A swing is confirmed, and reported, this many bars after its own bar.

Use it in a strategy

pythonms = ctx.plugin_indicator("market_structure", "structure", {"length": 3})
if ms is not None and ms.bias is not None:
    # A break of structure up while the swings make HH and HL: long.
    if ms.bos == 1 and ms.value == 1:
        ctx.signal("LONG")
    # A change of character down: out.
    elif ms.choch == -1:
        ctx.signal("EXIT")

What it provides

valueValueThe trend, the same as `trend`: 1 (HH and HL), -1 (LH and LL), 0 (mixed). None until there are two swing highs and two swing lows.
biasValueThe direction of the last break: 1 after a break up, -1 after a break down. None until the first break.
last_highValueThe price of the last confirmed swing high, and `last_high_time` the time of its bar. None until the first one.
last_lowValueThe price of the last confirmed swing low, and `last_low_time` the time of its bar. None until the first one.
high_labelValue"HH", "LH" or "EH" for the last swing high against the one before; `low_label` is "HL", "LL" or "EL". None until there are two.
high_confirmedValueTrue on the bar that confirms a swing high, `length` bars after it; `low_confirmed` the same for a swing low. None during warm up.
bosValue1 or -1 on the bar of a break of structure up or down, else 0; `bos_level` keeps the level of the last one. None during warm up.
chochValue1 or -1 on the bar of a change of character up or down, else 0; `choch_level` keeps the level of the last one. None during warm up.

When values are known

A swing is known length bars after its own bar, at the close of the confirming bar; breaks are known at the close of the breaking bar. Nothing reported is ever changed by later bars. Warm up: the first 2 x length bars report None.

Limits

  • Swings arrive length bars late by design. A chart tool that marks a swing on its own bar is looking ahead; this one does not.
  • Strict comparisons: a double top with exactly equal highs makes no swing high.
  • BOS and CHoCH have many definitions in trading literature. This one uses closes against the last confirmed swing only; other tools may mark different bars.
  • A plugin indicator is not drawn on the chart and is not available in Blocks, Pine, Rust or C#; it runs on the run's own instrument only.
OrionQuant