PINE LIBRARY

MarketStructure

Updated
Library "MarketStructure"
This library contains functions for identifying Lows and Highs in a rule-based way, and deriving useful information from them.

f_simpleLowHigh()
This function finds Local Lows and Highs, but NOT in order. A Local High is any candle that has its Low taken out on close by a subsequent candle (and vice-versa for Local Lows).
The Local High does NOT have to be the candle with the highest High out of recent candles. It does NOT have to be a Williams High. It is not necessarily a swing high or a reversal or anything else.
It doesn't have to be "the" high, so don't be confused.
By the rules, Local Lows and Highs must alternate. In this function they do not, so I'm calling them Simple Lows and Highs.
Simple Highs and Lows, by the above definition, can be useful for entries and stops. Because I intend to use them for stops, I want them all, not just the ones that alternate in strict order.
param - there are no parameters. The function uses the chart OHLC.
Returns boolean values for whether this bar confirms a Simple Low/High, and ints for the bar_index of that Low/High.

f_localLowHigh()
This function finds Local Lows and Highs, in order. A Local High is any candle that has its Low taken out on close by a subsequent candle (and vice-versa for Local Lows).
The Local High does NOT have to be the candle with the highest High out of recent candles. It does NOT have to be a Williams High. It is not necessarily a swing high or a reversal or anything else.
By the rules, Local Lows and Highs must alternate, and in this function they do.
param - there are no parameters. The function uses the chart OHLC.
Returns boolean values for whether this bar confirms a Local Low/High, and ints for the bar_index of that Low/High.

f_enhancedSimpleLowHigh()
This function finds Local Lows and Highs, but NOT in order. A Local High is any candle that has its Low taken out on close by a subsequent candle (and vice-versa for Local Lows).
The Local High does NOT have to be the candle with the highest High out of recent candles. It does NOT have to be a Williams High. It is not necessarily a swing high or a reversal or anything else.
By the rules, Local Lows and Highs must alternate. In this function they do not, so I'm calling them Simple Lows and Highs.
Simple Highs and Lows, by the above definition, can be useful for entries and stops. Because I intend to use them for trailing stops, I want them all, not just the ones that alternate in strict order.
The difference between this function and f_simpleLowHigh() is that it also tracks the lowest/highest recent level. This level can be useful for trailing stops.
In effect, these are like more "normal" highs and lows that you would pick by eye, but confirmed faster in many cases than by waiting for the low/high of that particular candle to be taken out on close,
because they are instead confirmed by ANY subsequent candle having its low/high exceeded. Hence, I call these Enhanced Simple Lows/Highs.
The levels are taken from the extreme highs/lows, but the bar indexes are given for the candles that were actually used to confirm the Low/High.
This is by design, because it might be misleading to label the extreme, since we didn't use that candle to confirm the Low/High..
param - there are no parameters. The function uses the chart OHLC.
Returns - boolean values for whether this bar confirms an Enhanced Simple Low/High
ints for the bar_index of that Low/High
floats for the values of the recent high/low levels
floats for the trailing high/low levels (for debug/post-processing)
bools for market structure bias

f_trueLowHigh()
This function finds True Lows and Highs.
A True High is the candle with the highest recent high, which then has its low taken out on close by a subsequent candle (and vice-versa for True Lows).
The difference between this and an Enhanced High is that confirmation requires not just any Simple High, but confirmation of the very candle that has the highest high.
Because of this, confirmation is often later, and multiple Simple Highs and Lows can develop within ranges formed by a single big candle without any of them being confirmed. This is by design.
A True High looks like the intuitive "real high" when you look at the chart. True Lows and Highs must alternate.
param - there are no parameters. The function uses the chart OHLC.
Returns - boolean values for whether this bar confirms an Enhanced Simple Low/High
ints for the bar_index of that Low/High
floats for the values of the recent high/low levels
floats for the trailing high/low levels (for debug/post-processing)
bools for market structure bias
Release Notes
v2

Updated:
f_simpleLowHigh(_high, _low, _close)
f_localLowHigh(_high, _low, _close)
f_enhancedSimpleLowHigh(_high, _low, _close)
f_trueLowHigh(_high, _low, _close)

Added the following parameters:
    _high (float): - the bar high price. Defaults to the chart high.
    _low (float): - the bar low price. Defaults to the chart low.
    _close (float): - the bar close price. Defaults to the chart close.

This allows you to supply custom OHLC values, for example, from a security() call to force a standard ticker.
Release Notes
v3
Fixes the case where a Low comes the very next candle after a High or vice-versa.
Release Notes
v4
Fixed a bug where in some cases pivots could be missed of the candle highs or lows kept increasing.
Release Notes
V5
Fixed an issue where the timeblock method of plotting a label in the future does not work if you plot it in the past.
As part of this fix, added label helper function and cleaned up superfluous variables for each exported function.
I spent ages looking for the problem in the structure logic, but it wasn't there!
Anyway, I left some of the debug that I used to examine the functions in the script, just commented out, for the interest of new Pine coders.
Release Notes
v6

Updated:
f_trueLowHigh(_high, _low, _close)

Fixed an issue where the wrong candle could be identified as the True Low if the lowest candle low occurred while the previous True High was waiting to be confirmed by a candle close, or vice-versa for True Highs.
This is basically THE main edge case with trying to implement rule-based alternating Highs and Lows: you can only confirm a High after a confirmed Low, but you have to start looking for it before that in order not to miss any.
I solved it here (touch wood) using arrays. When I wrote my first market structure indicator, arrays were not available in Pine.
You could perhaps do it with simple lines instead, but the solution occurred to me with arrays so here we are.
Hopefully, this logic should be robust.
Changes are tagged:
Release Notes
v7
Updated all functions to remove a typo of

instead of


This typo meant that the library worked fine on the current chart symbol, but could NOT be used for another symbol by passing in its high, low, and close.
Now it can. 🤞
Release Notes
v8
Added new outputs for `f_enhancedSimpleLowHigh()` and `f_trueLowHigh()`: `_trailingLow` and `_trailingHigh`.
These are useful mostly for illustrating how the functions work.
Note that you will need to update the calls to these functions to account for the new outputs, even if you don't use them.
Release Notes
v9

✅ Change to the internal logic of functions 3 and 4 to resolve issues with incorrect bullish and bearish bias.

✅ Minor changes to existing functions: dropped the outputs _trailingHigh, _trailingLow from Function 2.
I probably used them for debug at some point but I can't see a legitimate reason for them to be returned to the user.
Release Notes
v10
Minor changes to functions 3 and 4 to resolve issues with incorrect pivot levels in cases where the pivots come before the preceding pivots are confirmed.
dowtheoryhigherhighlowerlowmarket-structuremarketstructuretechindicator

Pine library

In true TradingView spirit, the author has published this Pine code as an open-source library so that other Pine programmers from our community can reuse it. Cheers to the author! You may use this library privately or in other open-source publications, but reuse of this code in a publication is governed by House rules.


Also on:

Disclaimer