XauLabs Swing PointsENGLISH
What it does
It marks confirmed swing highs and swing lows, labels each one relative to the previous one of the same type — HH, HL, LH, LL — and connects them with a zigzag. That labelled sequence is the raw material of every structure-based method: HH + HL is the skeleton of an uptrend, LH + LL the skeleton of a downtrend, anything mixed is no man's land.
How it works (full method)
Confirmation. A swing high is confirmed only when the highs of the N bars before AND the N bars after are all lower (mirrored for swing lows). N is user-defined, default 7, range 5–21.
Labelling. On confirmation, the new swing high is compared to the previous confirmed swing high: higher gives HH, lower gives LH. The first one, with no predecessor, is labelled H. Swing lows are compared to previous swing lows: HL or LL, first one labelled L. Highs are never compared to lows.
Zigzag. Each confirmed pivot is joined to the previous confirmed pivot by a straight line, regardless of type. The result is the chart's skeleton with the intermediate noise removed.
Two levels of structure. Major structure uses the main sensitivity and is the default view. An optional minor structure, with its own smaller sensitivity (default 3), plots the internal waves inside each major leg. It is off by default: the skeleton first, the ripples afterwards. Reading a minor swing as if it were a major one is the most common way to end up flipping bias several times a day.
No repainting
Labels appear N bars after the extreme they mark, are drawn at the true historical position of that extreme, and never move or disappear afterwards. What history shows is what would have been visible live. The confirmation delay is the cost, and it is stated rather than hidden.
On-chart output
HH / HL / LH / LL labels on every confirmed major pivot.
Zigzag connecting major pivots.
Optional minor pivot dots.
A badge in the top-right corner showing the two most recent readings, with selectable text size.
Two alert conditions: major swing high confirmed, major swing low confirmed.
Suggested use
Start on H4. Read the badge: HH · HL means the bullish skeleton is intact. Structure has to be read on one sensitivity, applied consistently — not on whichever swing supports the trade you already want to take.
This is an educational structure-reading tool. It gives no buy or sell signals and makes no performance claim. Trading involves substantial risk of loss.
FRANÇAIS
Ce que fait l'indicateur
Il marque les sommets et creux de swing confirmés, étiquette chacun par rapport au précédent du même type — HH, HL, LH, LL — et les relie par un zigzag. Cette séquence étiquetée est la matière première de toute méthode structurelle : HH + HL forme le squelette d'une tendance haussière, LH + LL celui d'une tendance baissière, tout ce qui est mixte est une zone grise.
Comment il fonctionne (méthode complète)
Confirmation. Un sommet n'est confirmé que si les N bougies avant ET les N bougies après ont toutes un plus haut inférieur (symétrique pour les creux). N est réglable, 7 par défaut, plage 5–21.
Étiquetage. À la confirmation, le nouveau sommet est comparé au sommet confirmé précédent : plus haut donne HH, plus bas donne LH. Le premier, sans prédécesseur, est étiqueté H. Les creux sont comparés aux creux : HL ou LL, le premier étiqueté L. Un sommet n'est jamais comparé à un creux.
Zigzag. Chaque pivot confirmé est relié au pivot confirmé précédent par une droite, quel que soit son type. On obtient le squelette du graphique, débarrassé du bruit intermédiaire.
Deux niveaux de structure. La structure majeure utilise la sensibilité principale : c'est la vue par défaut. Une structure mineure optionnelle, avec sa propre sensibilité plus courte (3 par défaut), trace les vagues internes de chaque jambe majeure. Elle est désactivée par défaut : le squelette d'abord, les vagues ensuite. Lire un swing mineur comme s'il était majeur est la façon la plus courante de changer de biais cinq fois par jour.
Aucun repaint
Les étiquettes apparaissent N bougies après l'extrême qu'elles marquent, sont tracées à la vraie place historique de cet extrême, et ne bougent ni ne disparaissent ensuite. Ce que montre l'historique est ce qui aurait été visible en direct. Le délai de confirmation est le prix à payer, et il est affiché plutôt que masqué.
Affichage
Étiquettes HH / HL / LH / LL sur chaque pivot majeur confirmé.
Zigzag reliant les pivots majeurs.
Points de pivots mineurs, optionnels.
Un badge dans le coin supérieur droit affichant les deux dernières lectures, avec taille de texte réglable.
Deux conditions d'alerte : sommet majeur confirmé, creux majeur confirmé.
Utilisation suggérée
Commencer en H4. Lire le badge : HH · HL signifie que le squelette haussier est intact. La structure se lit sur une seule sensibilité, appliquée avec constance — pas sur le swing qui arrange le trade qu'on a déjà envie de prendre.
Outil éducatif de lecture de structure. Il ne donne aucun signal d'achat ou de vente et ne formule aucune promesse de performance. Le trading comporte un risque de perte important. Indicator

MTF SMC / ICT Market State Engine# MTF SMC / ICT Market State & Reversal Dashboard
A multi-timeframe market-structure dashboard designed for traders using **Smart Money Concepts (SMC), ICT, liquidity and price-action analysis**.
The indicator combines structural information across **1D, 4H, 15M and 1M** into a single compact dashboard, helping traders identify the current **directional bias, market stage, liquidity condition and potential reversals** without having to manually compare multiple timeframes.
### What the Dashboard Shows
For each timeframe, the dashboard displays:
* **Bias** — Bullish, Bearish or Neutral
* **Structure** — HH/HL, LH/LL, BOS, MSS or CHOCH
* **Market Stage** — Accumulation, Liquidity Build, Manipulation, Confirmed Shift, Expansion, Retracement, Continuation, Exhaustion, Distribution or Reversal
* **Liquidity** — BSL, SSL, EQH, EQL and recently swept liquidity
* **Reversal State** — Normal, Reversal Warning, Reversal Developing or Confirmed Reversal
* **Structural Confidence** — Low, Medium or High
### Multi-Timeframe Bias
The indicator treats each timeframe according to its role in the market hierarchy:
**1D → Macro Bias**
**4H → Primary/Intraday Bias**
**15M → Setup & Market Structure**
**1M → Execution Structure**
This allows the indicator to distinguish between a genuine trend reversal and a simple lower-timeframe retracement.
For example:
**1D Bullish → 4H Bullish → 15M Bearish → 1M Bearish**
may be classified as:
> **HTF BULLISH / LTF RETRACEMENT**
rather than incorrectly changing the overall bias to bearish.
### Reversal Detection
The indicator does not treat every liquidity sweep or MSS as a confirmed reversal.
Reversal conditions progress through four stages:
**Normal → Reversal Warning → Reversal Developing → Confirmed Reversal**
A stronger reversal requires multiple structural factors such as:
* Liquidity sweep
* Displacement
* MSS/CHOCH
* Protected high/low violation
* Structural follow-through
This helps separate **liquidity manipulation and retracement** from an actual change in market structure.
### Market-State Engine
Rather than displaying disconnected SMC signals, the indicator interprets them as part of a market cycle:
**Accumulation → Liquidity Build → Manipulation → Confirmed Shift → Expansion → Retracement → Continuation → Exhaustion → Reversal**
The purpose is to answer four key questions:
> **What is the market direction?**
> **What stage is the market currently in?**
> **Where is the relevant liquidity?**
> **Is the market continuing, retracing or beginning a reversal?**
### Designed for SMC / ICT Traders
The indicator is intended as a **market-analysis and decision-support tool**, not an automatic trading system.
It does not attempt to predict future price or provide guaranteed buy/sell signals. Instead, it organizes multi-timeframe structural information into a clear framework so traders can make more consistent discretionary decisions.
**Primary workflow:**
**1D Bias → 4H Structure → 15M Setup → 1M Confirmation → Liquidity → Market Stage → Reversal Status**
Indicator

MTF Daily Bias DashboardOverview
The "MTF Daily Bias Dashboard" is a streamlined, non-intrusive utility designed specifically for Smart Money Concepts (SMC) and Inner Circle Trader (ICT) methodologies. Multi-timeframe analysis is the backbone of finding high-probability setups, but constantly switching between charts to check the higher-timeframe narrative can lead to missed lower-timeframe entries.
This indicator solves that problem by providing a clean, customizable on-chart dashboard that displays real-time, objective market bias across three different timeframes simultaneously.
Core Features
Objective Bias Detection: Bias is determined mechanically using a customizable Exponential Moving Average (EMA) and price action closes, removing emotion and guesswork from your directional bias.
Multi-Timeframe Synchronization: By default, it tracks the Daily (1D), 4-Hour (4H), and 15-Minute (15m) timeframes, giving you a complete top-down narrative at a glance.
Non-Repainting Logic: The multi-timeframe data is pulled securely, ensuring that historical signals remain accurate and current data does not repaint past the current candle formation.
Dynamic Visual Dashboard: A color-coded table (Green for Bullish, Red for Bearish) provides immediate visual confirmation of market alignment.
How It Works
The indicator evaluates the current price action against your chosen baseline (EMA).
Bullish (Green):Price closes above the EMA, and the current candle closes higher than the previous candle.
Bearish (Red): Price closes below the EMA, and the current candle closes lower than the previous candle.
Confluence: When all three timeframes show the same color, you have high-probability directional alignment, perfect for looking for lower-timeframe sweeps, order blocks, or fair value gaps in the direction of the trend.
Customization & Settings
Timeframes: Fully adjustable inputs allow you to change the three monitored timeframes to fit your specific trading model (e.g., Weekly/Daily/1H or 4H/1H/5m).
Dashboard Positioning: You can move the dashboard to any corner of your chart to ensure it never obstructs current price action.
Trend Logic: Adjust the EMA length used to calculate the bias to make the indicator more or less sensitive to recent price action.
Who is this for?
This tool is ideal for SMC, ICT, and pure price action traders who rely on the daily narrative but execute on intraday timeframes. It keeps you aligned with the macro trend while you focus on micro executions. Indicator

Killzones EUR/GBP - Manuel De Jesus Leiva// This source code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// © tradeforopp
//@version=6
indicator("Killzones EUR/GBP - Manuel De Jesus Leiva", "Killzones EUR/GBP - Manuel De Jesus Leiva", true, max_labels_count = 500, max_lines_count = 500, max_boxes_count = 500)
// ---------------------------------------- Constant Functions --------------------------------------------------
get_line_type(_style) =>
switch _style
"Solid" => line.style_solid
"Dotted" => line.style_dotted
"Dashed" => line.style_dashed
get_size(x) =>
switch x
"Auto" => size.auto
"Tiny" => size.tiny
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
"Huge" => size.huge
get_table_pos(pos) =>
switch pos
"Bottom Center" => position.bottom_center
"Bottom Left" => position.bottom_left
"Bottom Right" => position.bottom_right
"Middle Center" => position.middle_center
"Middle Left" => position.middle_left
"Middle Right" => position.middle_right
"Top Center" => position.top_center
"Top Left" => position.top_left
"Top Right" => position.top_right
// ---------------------------------------- Constant Functions --------------------------------------------------
// ---------------------------------------- Inputs --------------------------------------------------
var g_SETTINGS = "Settings"
max_days = input.int(1000, "Session Drawing Limit", 1, tooltip = "Only this many drawings will be kept on the chart, for each selected drawing type (killzone boxes, pivot lines, open lines, etc.). Set to 200 for ~6 months of sessions.", group = g_SETTINGS)
tf_limit = input.timeframe("60", "Timeframe Limit", tooltip = "Drawings will not appear on timeframes greater than or equal to this", group = g_SETTINGS)
gmt_tz = input.string('America/New_York', "Timezone", options = , tooltip = "Note GMT is not adjusted to reflect Daylight Saving Time changes", group = g_SETTINGS)
lbl_size = get_size(input.string('Normal', "Label Size", options = , tooltip = "The size of all labels", group = g_SETTINGS))
txt_color = input.color(color.black, "Text Color", tooltip = "The color of all label and table text", group = g_SETTINGS)
use_cutoff = input.bool(false, "Drawing Cutoff Time", inline = "CO", tooltip = "When enabled, all pivots and open price lines will stop extending at this time", group = g_SETTINGS)
cutoff = input.session("1800-1801", "", inline = "CO", group = g_SETTINGS)
var tf_limit_is_equal_or_more_chart_tf = timeframe.in_seconds('') <= timeframe.in_seconds(tf_limit)
var g_KZ = "Killzones"
// General Killzone Settings
show_kz = input.bool(true, "Show Killzone Boxes", inline = "KZ", group = g_KZ)
show_kz_text = input.bool(false, "Display Text", inline = "KZ", group = g_KZ)
box_transparency = input.int(70, "Box Transparency", 0, 100, group = g_KZ)
text_transparency = input.int(50, "Text Transparency", 0, 100, group = g_KZ)
// ==================== KILLZONE 01 ====================
use_kz01 = input.bool(true, "00:00-01:00", inline = "KZ01", group = g_KZ)
kz01_txt = input.string("00-01", "", inline = "KZ01", group = g_KZ)
kz01 = input.session("0000-0100", "", inline = "KZ01", group = g_KZ)
kz01_color = input.color(color.blue, "", inline = "KZ01", group = g_KZ)
// ==================== KILLZONE 02 ====================
use_kz02 = input.bool(true, "01:00-02:00", inline = "KZ02", group = g_KZ)
kz02_txt = input.string("01-02", "", inline = "KZ02", group = g_KZ)
kz02 = input.session("0100-0200", "", inline = "KZ02", group = g_KZ)
kz02_color = input.color(color.blue, "", inline = "KZ02", group = g_KZ)
// ==================== KILLZONE 03 ====================
use_kz03 = input.bool(true, "02:00-03:00", inline = "KZ03", group = g_KZ)
kz03_txt = input.string("02-03", "", inline = "KZ03", group = g_KZ)
kz03 = input.session("0200-0300", "", inline = "KZ03", group = g_KZ)
kz03_color = input.color(color.blue, "", inline = "KZ03", group = g_KZ)
// ==================== KILLZONE 04 ====================
use_kz04 = input.bool(true, "03:00-04:00", inline = "KZ04", group = g_KZ)
kz04_txt = input.string("03-04", "", inline = "KZ04", group = g_KZ)
kz04 = input.session("0300-0400", "", inline = "KZ04", group = g_KZ)
kz04_color = input.color(color.blue, "", inline = "KZ04", group = g_KZ)
// ==================== KILLZONE 05 ====================
use_kz05 = input.bool(true, "04:00-05:00", inline = "KZ05", group = g_KZ)
kz05_txt = input.string("04-05", "", inline = "KZ05", group = g_KZ)
kz05 = input.session("0400-0500", "", inline = "KZ05", group = g_KZ)
kz05_color = input.color(color.blue, "", inline = "KZ05", group = g_KZ)
// ==================== KILLZONE 06 ====================
use_kz06 = input.bool(true, "05:00-06:00", inline = "KZ06", group = g_KZ)
kz06_txt = input.string("05-06", "", inline = "KZ06", group = g_KZ)
kz06 = input.session("0500-0600", "", inline = "KZ06", group = g_KZ)
kz06_color = input.color(color.blue, "", inline = "KZ06", group = g_KZ)
// ==================== KILLZONE 07 ====================
use_kz07 = input.bool(true, "06:00-07:00", inline = "KZ07", group = g_KZ)
kz07_txt = input.string("06-07", "", inline = "KZ07", group = g_KZ)
kz07 = input.session("0600-0700", "", inline = "KZ07", group = g_KZ)
kz07_color = input.color(color.blue, "", inline = "KZ07", group = g_KZ)
// ==================== KILLZONE 08 ====================
use_kz08 = input.bool(true, "07:00-08:00", inline = "KZ08", group = g_KZ)
kz08_txt = input.string("07-08", "", inline = "KZ08", group = g_KZ)
kz08 = input.session("0700-0800", "", inline = "KZ08", group = g_KZ)
kz08_color = input.color(color.blue, "", inline = "KZ08", group = g_KZ)
// ==================== KILLZONE 09 ====================
use_kz09 = input.bool(true, "08:00-09:00", inline = "KZ09", group = g_KZ)
kz09_txt = input.string("08-09", "", inline = "KZ09", group = g_KZ)
kz09 = input.session("0800-0900", "", inline = "KZ09", group = g_KZ)
kz09_color = input.color(color.blue, "", inline = "KZ09", group = g_KZ)
// ==================== KILLZONE 10 ====================
use_kz10 = input.bool(true, "09:00-10:00", inline = "KZ10", group = g_KZ)
kz10_txt = input.string("09-10", "", inline = "KZ10", group = g_KZ)
kz10 = input.session("0900-1000", "", inline = "KZ10", group = g_KZ)
kz10_color = input.color(color.blue, "", inline = "KZ10", group = g_KZ)
// ==================== KILLZONE 11 ====================
use_kz11 = input.bool(true, "10:00-11:00", inline = "KZ11", group = g_KZ)
kz11_txt = input.string("10-11", "", inline = "KZ11", group = g_KZ)
kz11 = input.session("1000-1100", "", inline = "KZ11", group = g_KZ)
kz11_color = input.color(color.blue, "", inline = "KZ11", group = g_KZ)
// ==================== KILLZONE 12 ====================
use_kz12 = input.bool(true, "11:00-12:00", inline = "KZ12", group = g_KZ)
kz12_txt = input.string("11-12", "", inline = "KZ12", group = g_KZ)
kz12 = input.session("1100-1200", "", inline = "KZ12", group = g_KZ)
kz12_color = input.color(color.blue, "", inline = "KZ12", group = g_KZ)
// ==================== KILLZONE 13 ====================
use_kz13 = input.bool(true, "12:00-13:00", inline = "KZ13", group = g_KZ)
kz13_txt = input.string("12-13", "", inline = "KZ13", group = g_KZ)
kz13 = input.session("1200-1300", "", inline = "KZ13", group = g_KZ)
kz13_color = input.color(color.blue, "", inline = "KZ13", group = g_KZ)
// ==================== KILLZONE 14 ====================
use_kz14 = input.bool(true, "13:00-14:00", inline = "KZ14", group = g_KZ)
kz14_txt = input.string("13-14", "", inline = "KZ14", group = g_KZ)
kz14 = input.session("1300-1400", "", inline = "KZ14", group = g_KZ)
kz14_color = input.color(color.blue, "", inline = "KZ14", group = g_KZ)
// ==================== KILLZONE 15 ====================
use_kz15 = input.bool(true, "14:00-15:00", inline = "KZ15", group = g_KZ)
kz15_txt = input.string("14-15", "", inline = "KZ15", group = g_KZ)
kz15 = input.session("1400-1500", "", inline = "KZ15", group = g_KZ)
kz15_color = input.color(color.blue, "", inline = "KZ15", group = g_KZ)
// ==================== KILLZONE 16 ====================
use_kz16 = input.bool(true, "15:00-16:00", inline = "KZ16", group = g_KZ)
kz16_txt = input.string("15-16", "", inline = "KZ16", group = g_KZ)
kz16 = input.session("1500-1600", "", inline = "KZ16", group = g_KZ)
kz16_color = input.color(color.blue, "", inline = "KZ16", group = g_KZ)
// ==================== KILLZONE 17 ====================
use_kz17 = input.bool(true, "16:00-17:00", inline = "KZ17", group = g_KZ)
kz17_txt = input.string("16-17", "", inline = "KZ17", group = g_KZ)
kz17 = input.session("1600-1700", "", inline = "KZ17", group = g_KZ)
kz17_color = input.color(color.blue, "", inline = "KZ17", group = g_KZ)
// ==================== KILLZONE 18 ====================
use_kz18 = input.bool(true, "17:00-18:00", inline = "KZ18", group = g_KZ)
kz18_txt = input.string("17-18", "", inline = "KZ18", group = g_KZ)
kz18 = input.session("1700-1800", "", inline = "KZ18", group = g_KZ)
kz18_color = input.color(color.blue, "", inline = "KZ18", group = g_KZ)
// ==================== KILLZONE 19 ====================
use_kz19 = input.bool(true, "18:00-19:00", inline = "KZ19", group = g_KZ)
kz19_txt = input.string("18-19", "", inline = "KZ19", group = g_KZ)
kz19 = input.session("1800-1900", "", inline = "KZ19", group = g_KZ)
kz19_color = input.color(color.blue, "", inline = "KZ19", group = g_KZ)
// ==================== KILLZONE 20 ====================
use_kz20 = input.bool(true, "19:00-20:00", inline = "KZ20", group = g_KZ)
kz20_txt = input.string("19-20", "", inline = "KZ20", group = g_KZ)
kz20 = input.session("1900-2000", "", inline = "KZ20", group = g_KZ)
kz20_color = input.color(color.blue, "", inline = "KZ20", group = g_KZ)
// ==================== KILLZONE 21 ====================
use_kz21 = input.bool(true, "20:00-21:00", inline = "KZ21", group = g_KZ)
kz21_txt = input.string("20-21", "", inline = "KZ21", group = g_KZ)
kz21 = input.session("2000-2100", "", inline = "KZ21", group = g_KZ)
kz21_color = input.color(color.blue, "", inline = "KZ21", group = g_KZ)
// ==================== KILLZONE 22 ====================
use_kz22 = input.bool(true, "21:00-22:00", inline = "KZ22", group = g_KZ)
kz22_txt = input.string("21-22", "", inline = "KZ22", group = g_KZ)
kz22 = input.session("2100-2200", "", inline = "KZ22", group = g_KZ)
kz22_color = input.color(color.blue, "", inline = "KZ22", group = g_KZ)
// ==================== KILLZONE 23 ====================
use_kz23 = input.bool(true, "22:00-23:00", inline = "KZ23", group = g_KZ)
kz23_txt = input.string("22-23", "", inline = "KZ23", group = g_KZ)
kz23 = input.session("2200-2300", "", inline = "KZ23", group = g_KZ)
kz23_color = input.color(color.blue, "", inline = "KZ23", group = g_KZ)
// ==================== KILLZONE 24 ====================
use_kz24 = input.bool(true, "23:00-00:00", inline = "KZ24", group = g_KZ)
kz24_txt = input.string("23-00", "", inline = "KZ24", group = g_KZ)
kz24 = input.session("2300-0000", "", inline = "KZ24", group = g_KZ)
kz24_color = input.color(color.blue, "", inline = "KZ24", group = g_KZ)
// ==================== KILLZONE 25 ====================
use_kz25 = input.bool(true, "17:00-21:00", inline = "KZ25", group = g_KZ)
kz25_txt = input.string("17-21", "", inline = "KZ25", group = g_KZ)
kz25 = input.session("1700-2100", "", inline = "KZ25", group = g_KZ)
kz25_color = input.color(color.orange, "", inline = "KZ25", group = g_KZ)
// ==================== KILLZONE 26 ====================
use_kz26 = input.bool(true, "21:00-01:00", inline = "KZ26", group = g_KZ)
kz26_txt = input.string("21-01", "", inline = "KZ26", group = g_KZ)
kz26 = input.session("2100-0100", "", inline = "KZ26", group = g_KZ)
kz26_color = input.color(color.aqua, "", inline = "KZ26", group = g_KZ)
// ==================== KILLZONE 27 ====================
use_kz27 = input.bool(true, "01:00-05:00", inline = "KZ27", group = g_KZ)
kz27_txt = input.string("01-05", "", inline = "KZ27", group = g_KZ)
kz27 = input.session("0100-0500", "", inline = "KZ27", group = g_KZ)
kz27_color = input.color(color.green, "", inline = "KZ27", group = g_KZ)
// ==================== KILLZONE 28 ====================
use_kz28 = input.bool(true, "05:00-09:00", inline = "KZ28", group = g_KZ)
kz28_txt = input.string("05-09", "", inline = "KZ28", group = g_KZ)
kz28 = input.session("0500-0900", "", inline = "KZ28", group = g_KZ)
kz28_color = input.color(color.yellow, "", inline = "KZ28", group = g_KZ)
// ==================== KILLZONE 29 ====================
use_kz29 = input.bool(true, "09:00-13:00", inline = "KZ29", group = g_KZ)
kz29_txt = input.string("09-13", "", inline = "KZ29", group = g_KZ)
kz29 = input.session("0900-1300", "", inline = "KZ29", group = g_KZ)
kz29_color = input.color(color.red, "", inline = "KZ29", group = g_KZ)
// ==================== KILLZONE 30 ====================
use_kz30 = input.bool(true, "13:00-17:00", inline = "KZ30", group = g_KZ)
kz30_txt = input.string("13-17", "", inline = "KZ30", group = g_KZ)
kz30 = input.session("1300-1700", "", inline = "KZ30", group = g_KZ)
kz30_color = input.color(color.purple, "", inline = "KZ30", group = g_KZ)
var g_LABELS = "Killzone Pivots"
show_pivots = input.bool(false, "Show Pivots", inline = "PV", group = g_LABELS)
use_alerts = input.bool(false, "Alert Broken Pivots", inline = "PV", tooltip = "The desired killzones must be enabled at the time that an alert is created, along with the show pivots option, in order for alerts to work", group = g_LABELS)
show_midpoints = input.bool(false, "Show Pivot Midpoints", inline = "mp", group = g_LABELS)
stop_midpoints = input.bool(false, "Stop Once Mitigated", inline = "mp", group = g_LABELS)
show_labels = input.bool(false, "Show Pivot Labels", inline = "LB", tooltip = "Show labels denoting each killzone's high and low. Optionally choose to show the price of each level. Right side will show labels on the right-hand side of the chart until they are reached", group = g_LABELS)
label_price = input.bool(false, "Display Price", inline = "LB", group = g_LABELS)
label_right = input.bool(false, "Right Side", inline = "LB", group = g_LABELS)
ext_pivots = input.string("Until Mitigated", "Extend Pivots...", options = , group = g_LABELS)
ext_which = input.string("All", "...From Which Sessions", options = , group = g_LABELS)
ash_str = input.string("AS.H", "Killzone 1 Labels", inline = "L_AS", group = g_LABELS)
asl_str = input.string("AS.L", "", inline = "L_AS", group = g_LABELS)
loh_str = input.string("LO.H", "Killzone 2 Labels", inline = "L_LO", group = g_LABELS)
lol_str = input.string("LO.L", "", inline = "L_LO", group = g_LABELS)
nah_str = input.string("NYAM.H", "Killzone 3 Labels", inline = "L_NA", group = g_LABELS)
nal_str = input.string("NYAM.L", "", inline = "L_NA", group = g_LABELS)
nlh_str = input.string("NYL.H", "Killzone 4 Labels", inline = "L_NL", group = g_LABELS)
nll_str = input.string("NYL.L", "", inline = "L_NL", group = g_LABELS)
nph_str = input.string("NYPM.H", "Killzone 5 Labels", inline = "L_NP", group = g_LABELS)
npl_str = input.string("NYPM.L", "", inline = "L_NP", group = g_LABELS)
kzp_style = get_line_type(input.string(defval = 'Solid', title = "Pivot Style", options = , inline = "KZP", group = g_LABELS))
kzp_width = input.int(1, "", inline = "KZP", group = g_LABELS)
kzm_style = get_line_type(input.string(defval = 'Dotted', title = "Midpoint Style", options = , inline = "KZM", group = g_LABELS))
kzm_width = input.int(1, "", inline = "KZM", group = g_LABELS)
var g_RNG = "Killzone Range"
show_range = input.bool(false, "Show Killzone Range", tooltip = "Show the most recent ranges of each selected killzone, from high to low", group = g_RNG)
show_range_avg = input.bool(false, "Show Average", tooltip = "Show the average range of each selected killzone", group = g_RNG)
range_avg = input.int(5, "Average Length", 0, tooltip = "This many previous sessions will be used to calculate the average. If there isn't enough data on the current chart, it will use as many sessions as possible", group = g_RNG)
range_pos = get_table_pos(input.string('Top Right', "Table Position", options = , group = g_RNG))
range_size = get_size(input.string('Normal', "Table Size", options = , group = g_RNG))
var g_DWM = "Day - Week - Month"
sep_unlimited = input.bool(false, "Unlimited", tooltip = "Unlimited will show as many of the selected lines as possible. Otherwise, the session drawing limit will be used", group = g_DWM)
alert_HL = input.bool(false, "Alert High/Low Break", tooltip = "Alert when any selected highs and lows are traded through. The desired timeframe's high/low option must be enabled at the time that an alert is created", group = g_DWM)
show_d_open = input.bool(false, "D Open", inline = "DO", group = g_DWM)
dhl = input.bool(false, "High/Low", inline = "DO", tooltip = "", group = g_DWM)
ds = input.bool(false, "Separators", inline = "DO", tooltip = "Mark where a new day begins", group = g_DWM)
d_color = input.color(color.blue, "", inline = "DO", group = g_DWM)
show_w_open = input.bool(false, "W Open", inline = "WO", group = g_DWM)
whl = input.bool(false, "High/Low", inline = "WO", tooltip = "", group = g_DWM)
ws = input.bool(false, "Separators", inline = "WO", tooltip = "Mark where a new week begins", group = g_DWM)
w_color = input.color(#089981, "", inline = "WO", group = g_DWM)
show_m_open = input.bool(false, "M Open", inline = "MO", group = g_DWM)
mhl = input.bool(false, "High/Low", inline = "MO", tooltip = "", group = g_DWM)
ms = input.bool(false, "Separators", inline = "MO", tooltip = "Mark where a new month begins", group = g_DWM)
m_color = input.color(color.red, "", inline = "MO", group = g_DWM)
htf_style = get_line_type(input.string(defval = 'Solid', title = "Style", options = , inline = "D0", group = g_DWM))
htf_width = input.int(1, "", inline = "D0", group = g_DWM)
dow_labels = input.bool(false, "Day of Week Labels", inline = "DOW", group = g_DWM)
dow_yloc = input.string('Bottom', "", options = , inline = "DOW", group = g_DWM)
dow_xloc = input.string('Midnight', "", options = , inline = "DOW", group = g_DWM)
dow_hide_wknd = input.bool(false, "Hide Weekend Labels", group = g_DWM)
var g_OPEN = "Opening Prices"
open_unlimited = input.bool(false, "Unlimited", tooltip = "Unlimited will show as many of the selected lines as possible. Otherwise, the session drawing limit will be used", group = g_OPEN)
use_h1 = input.bool(false, "", inline = "H1", group = g_OPEN)
h1_text = input.string("17:00 H12/H8/H6/H4", "", inline = "H1", group = g_OPEN)
h1 = input.session("1700-1701", "", inline = "H1", group = g_OPEN)
h1_color = input.color(color.black, "", inline = "H1", group = g_OPEN)
use_h2 = input.bool(false, "", inline = "H2", group = g_OPEN)
h2_text = input.string("05:00 H12/H6/H4", "", inline = "H2", group = g_OPEN)
h2 = input.session("0500-0501", "", inline = "H2", group = g_OPEN)
h2_color = input.color(color.black, "", inline = "H2", group = g_OPEN)
use_h3 = input.bool(false, "", inline = "H3", group = g_OPEN)
h3_text = input.string("01:00 H8/H4", "", inline = "H3", group = g_OPEN)
h3 = input.session("0100-0101", "", inline = "H3", group = g_OPEN)
h3_color = input.color(color.black, "", inline = "H3", group = g_OPEN)
use_h4 = input.bool(false, "", inline = "H4", group = g_OPEN)
h4_text = input.string("09:00 H8/H4", "", inline = "H4", group = g_OPEN)
h4 = input.session("0900-0901", "", inline = "H4", group = g_OPEN)
h4_color = input.color(color.black, "", inline = "H4", group = g_OPEN)
use_h5 = input.bool(false, "", inline = "H5", group = g_OPEN)
h5_text = input.string("23:00 H6", "", inline = "H5", group = g_OPEN)
h5 = input.session("2300-2301", "", inline = "H5", group = g_OPEN)
h5_color = input.color(color.black, "", inline = "H5", group = g_OPEN)
use_h6 = input.bool(false, "", inline = "H6", group = g_OPEN)
h6_text = input.string("11:00 H6", "", inline = "H6", group = g_OPEN)
h6 = input.session("1100-1101", "", inline = "H6", group = g_OPEN)
h6_color = input.color(color.black, "", inline = "H6", group = g_OPEN)
use_h7 = input.bool(false, "", inline = "H7", group = g_OPEN)
h7_text = input.string("21:00 H4", "", inline = "H7", group = g_OPEN)
h7 = input.session("2100-2101", "", inline = "H7", group = g_OPEN)
h7_color = input.color(color.black, "", inline = "H7", group = g_OPEN)
use_h8 = input.bool(false, "", inline = "H8", group = g_OPEN)
h8_text = input.string("13:00 H4", "", inline = "H8", group = g_OPEN)
h8 = input.session("1300-1301", "", inline = "H8", group = g_OPEN)
h8_color = input.color(color.black, "", inline = "H8", group = g_OPEN)
hz_style = get_line_type(input.string(defval = 'Dotted', title = "Style", options = , inline = "H0", group = g_OPEN))
hz_width = input.int(1, "", inline = "H0", group = g_OPEN)
var g_VERTICAL = "Timestamps"
v_unlimited = input.bool(false, "Unlimited", tooltip = "Unlimited will show as many of the selected lines as possible. Otherwise, the session drawing limit will be used", group = g_VERTICAL)
use_v1 = input.bool(false, "", inline = "V1", group = g_VERTICAL)
v1 = input.session("0000-0001", "", inline = "V1", group = g_VERTICAL)
v1_color = input.color(color.black, "", inline = "V1", group = g_VERTICAL)
use_v2 = input.bool(false, "", inline = "V2", group = g_VERTICAL)
v2 = input.session("0800-0801", "", inline = "V2", group = g_VERTICAL)
v2_color = input.color(color.black, "", inline = "V2", group = g_VERTICAL)
use_v3 = input.bool(false, "", inline = "V3", group = g_VERTICAL)
v3 = input.session("1000-1001", "", inline = "V3", group = g_VERTICAL)
v3_color = input.color(color.black, "", inline = "V3", group = g_VERTICAL)
use_v4 = input.bool(false, "", inline = "V4", group = g_VERTICAL)
v4 = input.session("1200-1201", "", inline = "V4", group = g_VERTICAL)
v4_color = input.color(color.black, "", inline = "V4", group = g_VERTICAL)
vl_style = get_line_type(input.string(defval = 'Dotted', title = "Style", options = , inline = "V0", group = g_VERTICAL))
vl_width = input.int(1, "", inline = "V0", group = g_VERTICAL)
// ---------------------------------------- Inputs --------------------------------------------------
// ---------------------------------------- Variables & Constants --------------------------------------------------
type kz
string _title
array _box
array _hi_line
array _md_line
array _lo_line
array _hi_label
array _lo_label
array _hi_valid
array _md_valid
array _lo_valid
array _range_store
float _range_current
type hz
array LN
array LB
array CO
type dwm_hl
array hi_line
array lo_line
array hi_label
array lo_label
bool hit_high = false
bool hit_low = false
type dwm_info
string tf
float o = na
float h = na
float l = na
float ph = na
float pl = na
type lines_helper
hz _hz
string h
string h_text
color h_color
initLines() =>
array res = array.new()
if use_h1
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h1, h1_text, h1_color))
if use_h2
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h2, h2_text, h2_color))
if use_h3
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h3, h3_text, h3_color))
if use_h4
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h4, h4_text, h4_color))
if use_h5
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h5, h5_text, h5_color))
if use_h6
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h6, h6_text, h6_color))
if use_h7
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h7, h7_text, h7_color))
if use_h8
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h8, h8_text, h8_color))
res
var array lines = initLines()
type kz_helper
kz _kz
string session
color c
string box_txt
string hi_txt
string lo_txt
initKZ() =>
array res = array.new()
if use_kz01
res.push(kz_helper.new(
kz.new(kz01_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz01, kz01_color, kz01_txt, "KZ01.H", "KZ01.L"
))
if use_kz02
res.push(kz_helper.new(
kz.new(kz02_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz02, kz02_color, kz02_txt, "KZ02.H", "KZ02.L"
))
if use_kz03
res.push(kz_helper.new(
kz.new(kz03_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz03, kz03_color, kz03_txt, "KZ03.H", "KZ03.L"
))
if use_kz04
res.push(kz_helper.new(
kz.new(kz04_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz04, kz04_color, kz04_txt, "KZ04.H", "KZ04.L"
))
if use_kz05
res.push(kz_helper.new(
kz.new(kz05_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz05, kz05_color, kz05_txt, "KZ05.H", "KZ05.L"
))
if use_kz06
res.push(kz_helper.new(
kz.new(kz06_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz06, kz06_color, kz06_txt, "KZ06.H", "KZ06.L"
))
if use_kz07
res.push(kz_helper.new(
kz.new(kz07_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz07, kz07_color, kz07_txt, "KZ07.H", "KZ07.L"
))
if use_kz08
res.push(kz_helper.new(
kz.new(kz08_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz08, kz08_color, kz08_txt, "KZ08.H", "KZ08.L"
))
if use_kz09
res.push(kz_helper.new(
kz.new(kz09_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz09, kz09_color, kz09_txt, "KZ09.H", "KZ09.L"
))
if use_kz10
res.push(kz_helper.new(
kz.new(kz10_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz10, kz10_color, kz10_txt, "KZ10.H", "KZ10.L"
))
if use_kz11
res.push(kz_helper.new(
kz.new(kz11_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz11, kz11_color, kz11_txt, "KZ11.H", "KZ11.L"
))
if use_kz12
res.push(kz_helper.new(
kz.new(kz12_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz12, kz12_color, kz12_txt, "KZ12.H", "KZ12.L"
))
if use_kz13
res.push(kz_helper.new(
kz.new(kz13_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz13, kz13_color, kz13_txt, "KZ13.H", "KZ13.L"
))
if use_kz14
res.push(kz_helper.new(
kz.new(kz14_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz14, kz14_color, kz14_txt, "KZ14.H", "KZ14.L"
))
if use_kz15
res.push(kz_helper.new(
kz.new(kz15_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz15, kz15_color, kz15_txt, "KZ15.H", "KZ15.L"
))
if use_kz16
res.push(kz_helper.new(
kz.new(kz16_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz16, kz16_color, kz16_txt, "KZ16.H", "KZ16.L"
))
if use_kz17
res.push(kz_helper.new(
kz.new(kz17_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz17, kz17_color, kz17_txt, "KZ17.H", "KZ17.L"
))
if use_kz18
res.push(kz_helper.new(
kz.new(kz18_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz18, kz18_color, kz18_txt, "KZ18.H", "KZ18.L"
))
if use_kz19
res.push(kz_helper.new(
kz.new(kz19_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz19, kz19_color, kz19_txt, "KZ19.H", "KZ19.L"
))
if use_kz20
res.push(kz_helper.new(
kz.new(kz20_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz20, kz20_color, kz20_txt, "KZ20.H", "KZ20.L"
))
if use_kz21
res.push(kz_helper.new(
kz.new(kz21_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz21, kz21_color, kz21_txt, "KZ21.H", "KZ21.L"
))
if use_kz22
res.push(kz_helper.new(
kz.new(kz22_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz22, kz22_color, kz22_txt, "KZ22.H", "KZ22.L"
))
if use_kz23
res.push(kz_helper.new(
kz.new(kz23_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz23, kz23_color, kz23_txt, "KZ23.H", "KZ23.L"
))
if use_kz24
res.push(kz_helper.new(
kz.new(kz24_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz24, kz24_color, kz24_txt, "KZ24.H", "KZ24.L"
))
if use_kz25
res.push(kz_helper.new(
kz.new(kz25_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz25, kz25_color, kz25_txt, "KZ25.H", "KZ25.L"
))
if use_kz26
res.push(kz_helper.new(
kz.new(kz26_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz26, kz26_color, kz26_txt, "KZ26.H", "KZ26.L"
))
if use_kz27
res.push(kz_helper.new(
kz.new(kz27_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz27, kz27_color, kz27_txt, "KZ27.H", "KZ27.L"
))
if use_kz28
res.push(kz_helper.new(
kz.new(kz28_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz28, kz28_color, kz28_txt, "KZ28.H", "KZ28.L"
))
if use_kz29
res.push(kz_helper.new(
kz.new(kz29_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz29, kz29_color, kz29_txt, "KZ29.H", "KZ29.L"
))
if use_kz30
res.push(kz_helper.new(
kz.new(kz30_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz30, kz30_color, kz30_txt, "KZ30.H", "KZ30.L"
))
res
var array _kz = initKZ()
var d_hl = dwm_hl.new(array.new_line(), array.new_line(), array.new_label(), array.new_label())
var w_hl = dwm_hl.new(array.new_line(), array.new_line(), array.new_label(), array.new_label())
var m_hl = dwm_hl.new(array.new_line(), array.new_line(), array.new_label(), array.new_label())
var d_info = dwm_info.new("D")
var w_info = dwm_info.new("W")
var m_info = dwm_info.new("M")
t_co = not na(time("", cutoff, gmt_tz))
type ts_helper
string session
array lines
color c
initTS() =>
array res = array.new()
if use_v1
res.push(ts_helper.new(v1, array.new_line(), v1_color))
if use_v2
res.push(ts_helper.new(v2, array.new_line(), v2_color))
if use_v3
res.push(ts_helper.new(v3, array.new_line(), v3_color))
if use_v4
res.push(ts_helper.new(v4, array.new_line(), v4_color))
res
var array ts_data = initTS()
var d_sep_line = array.new_line()
var w_sep_line = array.new_line()
var m_sep_line = array.new_line()
var d_line = array.new_line()
var w_line = array.new_line()
var m_line = array.new_line()
var d_label = array.new_label()
var w_label = array.new_label()
var m_label = array.new_label()
var transparent = #ffffff00
var ext_current = ext_which == 'Most Recent'
var ext_past = ext_pivots == 'Past Mitigation'
update_dwm_info(dwm_info n) =>
if timeframe.change(n.tf)
n.ph := n.h
n.pl := n.l
n.o := open
n.h := high
n.l := low
else
n.h := math.max(high, n.h)
n.l := math.min(low, n.l)
if dhl or show_d_open
update_dwm_info(d_info)
if whl or show_w_open
update_dwm_info(w_info)
if mhl or show_m_open
update_dwm_info(m_info)
// ---------------------------------------- Variables & Constants --------------------------------------------------
// ---------------------------------------- Functions --------------------------------------------------
get_box_color(color c) =>
color.new(c, box_transparency)
get_text_color(color c) =>
color.new(c, text_transparency)
// ---------------------------------------- Functions --------------------------------------------------
// ---------------------------------------- Core Logic --------------------------------------------------
dwm_sep(string tf, bool use, array arr, color col) =>
if use
if timeframe.change(tf)
arr.unshift(line.new(bar_index, high * 1.0001, bar_index, low, style = htf_style, width = htf_width, extend = extend.both, color = col))
if not sep_unlimited and arr.size() > max_days
arr.pop().delete()
dwm_open(string tf, bool use, array lns, array lbls, dwm_info n, color col) =>
if use
if lns.size() > 0
lns.get(0).set_x2(time)
lbls.get(0).set_x(time)
if timeframe.change(tf)
lns.unshift(line.new(time, n.o, time, n.o, xloc = xloc.bar_time, style = htf_style, width = htf_width, color = col))
lbls.unshift(label.new(time, n.o, tf + " OPEN", xloc = xloc.bar_time, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size))
if not sep_unlimited and lns.size() > max_days
lns.pop().delete()
lbls.pop().delete()
dwm_hl(string tf, bool use, dwm_hl hl, dwm_info n, color col) =>
if use
if hl.hi_line.size() > 0
hl.hi_line.get(0).set_x2(time)
hl.lo_line.get(0).set_x2(time)
hl.hi_label.get(0).set_x(time)
hl.lo_label.get(0).set_x(time)
if timeframe.change(tf)
hl.hi_line.unshift(line.new(time, n.ph, time, n.ph, xloc = xloc.bar_time, style = htf_style, width = htf_width, color = col))
hl.lo_line.unshift(line.new(time, n.pl, time, n.pl, xloc = xloc.bar_time, style = htf_style, width = htf_width, color = col))
hl.hi_label.unshift(label.new(time, n.ph, "P" + tf + "H", xloc = xloc.bar_time, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size))
hl.lo_label.unshift(label.new(time, n.pl, "P" + tf + "L", xloc = xloc.bar_time, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size))
hl.hit_high := false
hl.hit_low := false
if not sep_unlimited and hl.hi_line.size() > max_days
hl.hi_line.pop().delete()
hl.lo_line.pop().delete()
hl.hi_label.pop().delete()
hl.lo_label.pop().delete()
if hl.hi_line.size() > 0 and alert_HL
if not hl.hit_high and high > hl.hi_line.get(0).get_y1()
hl.hit_high := true
alert(str.format("Hit P{0}H", tf))
if not hl.hit_low and low < hl.lo_line.get(0).get_y1()
hl.hit_low := true
alert(str.format("Hit P{0}L", tf))
dwm() =>
if tf_limit_is_equal_or_more_chart_tf
// DWM - Separators
dwm_sep("D", ds, d_sep_line, d_color)
dwm_sep("W", ws, w_sep_line, w_color)
dwm_sep("M", ms, m_sep_line, m_color)
// DWM - Open Lines
dwm_open("D", show_d_open, d_line, d_label, d_info, d_color)
dwm_open("W", show_w_open, w_line, w_label, w_info, w_color)
dwm_open("M", show_m_open, m_line, m_label, m_info, m_color)
// DWM - Highs and Lows
dwm_hl("D", dhl, d_hl, d_info, d_color)
dwm_hl("W", whl, w_hl, w_info, w_color)
dwm_hl("M", mhl, m_hl, m_info, m_color)
method vline(ts_helper this) =>
bool t = not na(time("", this.session, gmt_tz))
bool t_prev = not na(time("", this.session, gmt_tz, bars_back = 1))
array arr = this.lines
color col = this.c
if t and not t_prev
arr.unshift(line.new(bar_index, high * 1.0001, bar_index, low, style = vl_style, width = vl_width, extend = extend.both, color = col))
if not v_unlimited
if arr.size() > max_days
arr.pop().delete()
vlines() =>
if tf_limit_is_equal_or_more_chart_tf
for in ts_data
vline(value)
method hz_line(lines_helper this) =>
bool t = not na(time("", this.h, gmt_tz))
bool t_prev = not na(time("", this.h, gmt_tz, bars_back = 1))
hz hz = this._hz
string txt = this.h_text
color col = this.h_color
if t and not t_prev
hz.LN.unshift(line.new(bar_index, open, bar_index, open, style = hz_style, width = hz_width, color = col))
hz.LB.unshift(label.new(bar_index, open, txt, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size))
array.unshift(hz.CO, false)
if not open_unlimited and hz.LN.size() > max_days
hz.LN.pop().delete()
hz.LB.pop().delete()
hz.CO.pop()
if not t and hz.CO.size() > 0
if not hz.CO.get(0)
hz.LN.get(0).set_x2(bar_index)
hz.LB.get(0).set_x(bar_index)
if (use_cutoff ? t_co : false)
hz.CO.set(0, true)
hz_lines() =>
if tf_limit_is_equal_or_more_chart_tf
for in lines
hz_line(value)
del_kz(kz k) =>
if k._box.size() > max_days
k._box.pop().delete()
if k._hi_line.size() > max_days
k._hi_line.pop().delete()
k._lo_line.pop().delete()
k._hi_valid.pop()
k._lo_valid.pop()
if show_midpoints
k._md_line.pop().delete()
k._md_valid.pop()
if k._hi_label.size() > max_days
k._hi_label.pop().delete()
k._lo_label.pop().delete()
update_price_string(label L, float P) =>
S = L.get_text()
pre = str.substring(S, 0, str.pos(S, " "))
str.trim(pre)
L.set_text(str.format("{0} ({1})", pre, P))
adjust_in_kz(kz kz, bool t) =>
if t
kzBox0 = kz._box.get(0)
kzBox0.set_right(time)
newTop = math.max(kzBox0.get_top(), high)
kzBox0.set_top(newTop)
newBottom = math.min(kzBox0.get_bottom(), low)
kzBox0.set_bottom(newBottom)
kz._range_current := newTop - newBottom
if show_pivots and kz._hi_line.size() > 0
kzHiLine0 = kz._hi_line.get(0)
kzHiLine0.set_x2(time)
if high > kzHiLine0.get_y1()
kzHiLine0.set_xy1(time, high)
kzHiLine0.set_xy2(time, high)
kzLoLine0 = kz._lo_line.get(0)
kzLoLine0.set_x2(time)
if low < kzLoLine0.get_y1()
kzLoLine0.set_xy1(time, low)
kzLoLine0.set_xy2(time, low)
if show_midpoints
kzMidLine0 = kz._md_line.get(0)
kzMidLine0.set_x2(time)
kzMidLine0.set_xy1(time, math.avg(kzHiLine0.get_y2(), kzLoLine0.get_y2()))
kzMidLine0.set_xy2(time, math.avg(kzHiLine0.get_y2(), kzLoLine0.get_y2()))
if show_labels and kz._hi_label.size() > 0
if label_right
kz._hi_label.get(0).set_x(time)
kz._lo_label.get(0).set_x(time)
if high > kz._hi_label.get(0).get_y()
kz._hi_label.get(0).set_xy(time, high)
if label_price
update_price_string(kz._hi_label.get(0), high)
if low < kz._lo_label.get(0).get_y()
kz._lo_label.get(0).set_xy(time, low)
if label_price
update_price_string(kz._lo_label.get(0), low)
adjust_out_kz(kz kz, bool t, bool t_prev) =>
boxCount = kz._box.size()
if not t and boxCount > 0
if t_prev
array.unshift(kz._range_store, kz._range_current)
if kz._range_store.size() > range_avg
kz._range_store.pop()
if show_pivots and boxCount > 0
for i = 0 to boxCount - 1 by 1
if not ext_current or i == 0
kzHiValid = kz._hi_valid.get(i)
if ext_past or kzHiValid
kz._hi_line.get(i).set_x2(time)
if show_labels and label_right
kz._hi_label.get(i).set_x(time)
if kzHiValid and high > kz._hi_line.get(i).get_y1()
if use_alerts and i == 0
alert('Broke ' + kz._title + ' High', alert.freq_once_per_bar)
kz._hi_valid.set(i, false)
if show_labels and label_right
kz._hi_label.get(i).set_style(label.style_label_down)
else if use_cutoff ? t_co : false
kz._hi_valid.set(i, false)
kzLoValid = kz._lo_valid.get(i)
if ext_past or kzLoValid
kz._lo_line.get(i).set_x2(time)
if show_labels and label_right
kz._lo_label.get(i).set_x(time)
if kzLoValid and low < kz._lo_line.get(i).get_y1()
if use_alerts and i == 0
alert("Broke " + kz._title + " Low", alert.freq_once_per_bar)
kz._lo_valid.set(i, false)
if show_labels and label_right
kz._lo_label.get(i).set_style(label.style_label_up)
else if use_cutoff ? t_co : false
kz._lo_valid.set(i, false)
if show_midpoints and not t
if stop_midpoints ? kz._md_valid.get(i) : true
kz._md_line.get(i).set_x2(time)
if kz._md_valid.get(i) and low <= kz._md_line.get(i).get_y1() and high >= kz._md_line.get(i).get_y1()
kz._md_valid.set(i, false)
else
break
method manage_kz(kz_helper this) =>
kz kz = this._kz
c = this.c
string box_txt = this.box_txt
string hi_txt = this.hi_txt
string lo_txt = this.lo_txt
if tf_limit_is_equal_or_more_chart_tf
t = not na(time("", this.session, gmt_tz))
t_prev = not na(time("", this.session, gmt_tz, bars_back = 1))
if t and not t_prev
_c = get_box_color(c)
_t = get_text_color(c)
kz._box.unshift(box.new(time, high, time, low, xloc = xloc.bar_time, border_color = show_kz ? _c : na, bgcolor = show_kz ? _c : na, text = show_kz and show_kz_text ? box_txt : na, text_color = _t))
if show_pivots
kz._hi_line.unshift(line.new(time, high, time, high, xloc = xloc.bar_time, style = kzp_style, color = c, width = kzp_width))
kz._lo_line.unshift(line.new(time, low, time, low, xloc = xloc.bar_time, style = kzp_style, color = c, width = kzp_width))
if show_midpoints
kz._md_line.unshift(line.new(time, math.avg(high, low), time, math.avg(high, low), xloc = xloc.bar_time, style = kzm_style, color = c, width = kzm_width))
array.unshift(kz._md_valid, true)
array.unshift(kz._hi_valid, true)
array.unshift(kz._lo_valid, true)
if show_labels
_hi_txt = label_price ? str.format('{0} ({1})', hi_txt, high) : hi_txt
_lo_txt = label_price ? str.format('{0} ({1})', lo_txt, low) : lo_txt
if label_right
kz._hi_label.unshift(label.new(time, high, _hi_txt, xloc = xloc.bar_time, color = transparent, textcolor = txt_color, style = label.style_label_left, size = lbl_size))
kz._lo_label.unshift(label.new(time, low, _lo_txt, xloc = xloc.bar_time, color = transparent, textcolor = txt_color, style = label.style_label_left, size = lbl_size))
else
kz._hi_label.unshift(label.new(time, high, _hi_txt, xloc = xloc.bar_time, color = transparent, textcolor = txt_color, style = label.style_label_down, size = lbl_size))
kz._lo_label.unshift(label.new(time, low, _lo_txt, xloc = xloc.bar_time, color = transparent, textcolor = txt_color, style = label.style_label_up, size = lbl_size))
del_kz(kz)
adjust_in_kz(kz, t)
adjust_out_kz(kz, t, t_prev)
for in _kz
manage_kz(value)
dwm()
vlines()
hz_lines()
new_dow_time = dow_xloc == 'Midday' ? time - timeframe.in_seconds("D") / 2 * 1000 : time
new_day = dayofweek(new_dow_time, gmt_tz) != dayofweek(new_dow_time, gmt_tz)
var dow_top = dow_yloc == 'Top'
var saturday = "SATURDAY"
var sunday = "SUNDAY"
var monday = "MONDAY"
var tuesday = "TUESDAY"
var wednesday = "WEDNESDAY"
var thursday = "THURSDAY"
var friday = "FRIDAY"
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 1 and new_day and not dow_hide_wknd, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = sunday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 2 and new_day, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = monday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 3 and new_day, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = tuesday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 4 and new_day, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = wednesday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 5 and new_day, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = thursday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 6 and new_day, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = friday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 7 and new_day and not dow_hide_wknd, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = saturday)
get_min_days_stored() =>
store = array.new_int()
for in _kz
int tmpStoreSize = value._kz._range_store.size()
if tmpStoreSize > 0
store.push(tmpStoreSize)
store.min()
method set_table(table tbl, kz kz, int row, string txt, bool t, color col) =>
table.cell(tbl, 0, row, txt, text_size = range_size, bgcolor = get_box_color(col), text_color = txt_color)
table.cell(tbl, 1, row, str.tostring(kz._range_current), text_size = range_size, bgcolor = t ? get_box_color(col) : na, text_color = txt_color)
if show_range_avg
table.cell(tbl, 2, row, str.tostring(kz._range_store.avg()), text_size = range_size, text_color = txt_color)
if show_range and barstate.islast
var tbl = table.new(range_pos, 10, 10, chart.bg_color, chart.fg_color, 2, chart.fg_color, 1)
table.cell(tbl, 0, 0, "Killzone", text_size = range_size, text_color = txt_color)
table.cell(tbl, 1, 0, "Range", text_size = range_size, text_color = txt_color)
if show_range_avg
table.cell(tbl, 2, 0, "Avg (" + str.tostring(get_min_days_stored()) + ")", text_size = range_size, text_color = txt_color)
for in _kz
set_table(tbl, value._kz, index + 1, value.box_txt, not na(time("", value.session, gmt_tz)), value.c)
// ---------------------------------------- Core Logic --------------------------------------------------
Indicator

Killzones US100/SP500 - Manuel De Jesus Leiva// This source code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// © tradeforopp
//@version=6
indicator("Killzones US100/SP500 - Manuel De Jesus Leiva", "Killzones US100/SP500 - Manuel De Jesus Leiva", true, max_labels_count = 500, max_lines_count = 500, max_boxes_count = 500)
// ---------------------------------------- Constant Functions --------------------------------------------------
get_line_type(_style) =>
switch _style
"Solid" => line.style_solid
"Dotted" => line.style_dotted
"Dashed" => line.style_dashed
get_size(x) =>
switch x
"Auto" => size.auto
"Tiny" => size.tiny
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
"Huge" => size.huge
get_table_pos(pos) =>
switch pos
"Bottom Center" => position.bottom_center
"Bottom Left" => position.bottom_left
"Bottom Right" => position.bottom_right
"Middle Center" => position.middle_center
"Middle Left" => position.middle_left
"Middle Right" => position.middle_right
"Top Center" => position.top_center
"Top Left" => position.top_left
"Top Right" => position.top_right
// ---------------------------------------- Constant Functions --------------------------------------------------
// ---------------------------------------- Inputs --------------------------------------------------
var g_SETTINGS = "Settings"
max_days = input.int(1000, "Session Drawing Limit", 1, tooltip = "Only this many drawings will be kept on the chart, for each selected drawing type (killzone boxes, pivot lines, open lines, etc.). Set to 200 for ~6 months of sessions.", group = g_SETTINGS)
tf_limit = input.timeframe("60", "Timeframe Limit", tooltip = "Drawings will not appear on timeframes greater than or equal to this", group = g_SETTINGS)
gmt_tz = input.string('America/New_York', "Timezone", options = , tooltip = "Note GMT is not adjusted to reflect Daylight Saving Time changes", group = g_SETTINGS)
lbl_size = get_size(input.string('Normal', "Label Size", options = , tooltip = "The size of all labels", group = g_SETTINGS))
txt_color = input.color(color.black, "Text Color", tooltip = "The color of all label and table text", group = g_SETTINGS)
use_cutoff = input.bool(false, "Drawing Cutoff Time", inline = "CO", tooltip = "When enabled, all pivots and open price lines will stop extending at this time", group = g_SETTINGS)
cutoff = input.session("1800-1801", "", inline = "CO", group = g_SETTINGS)
var tf_limit_is_equal_or_more_chart_tf = timeframe.in_seconds('') <= timeframe.in_seconds(tf_limit)
var g_KZ = "Killzones"
// General Killzone Settings
show_kz = input.bool(true, "Show Killzone Boxes", inline = "KZ", group = g_KZ)
show_kz_text = input.bool(false, "Display Text", inline = "KZ", group = g_KZ)
box_transparency = input.int(70, "Box Transparency", 0, 100, group = g_KZ)
text_transparency = input.int(50, "Text Transparency", 0, 100, group = g_KZ)
// ==================== KILLZONE 01 ====================
use_kz01 = input.bool(true, "00:00-01:00", inline = "KZ01", group = g_KZ)
kz01_txt = input.string("00-01", "", inline = "KZ01", group = g_KZ)
kz01 = input.session("0000-0100", "", inline = "KZ01", group = g_KZ)
kz01_color = input.color(color.blue, "", inline = "KZ01", group = g_KZ)
// ==================== KILLZONE 02 ====================
use_kz02 = input.bool(true, "01:00-02:00", inline = "KZ02", group = g_KZ)
kz02_txt = input.string("01-02", "", inline = "KZ02", group = g_KZ)
kz02 = input.session("0100-0200", "", inline = "KZ02", group = g_KZ)
kz02_color = input.color(color.blue, "", inline = "KZ02", group = g_KZ)
// ==================== KILLZONE 03 ====================
use_kz03 = input.bool(true, "02:00-03:00", inline = "KZ03", group = g_KZ)
kz03_txt = input.string("02-03", "", inline = "KZ03", group = g_KZ)
kz03 = input.session("0200-0300", "", inline = "KZ03", group = g_KZ)
kz03_color = input.color(color.blue, "", inline = "KZ03", group = g_KZ)
// ==================== KILLZONE 04 ====================
use_kz04 = input.bool(true, "03:00-04:00", inline = "KZ04", group = g_KZ)
kz04_txt = input.string("03-04", "", inline = "KZ04", group = g_KZ)
kz04 = input.session("0300-0400", "", inline = "KZ04", group = g_KZ)
kz04_color = input.color(color.blue, "", inline = "KZ04", group = g_KZ)
// ==================== KILLZONE 05 ====================
use_kz05 = input.bool(true, "04:00-05:00", inline = "KZ05", group = g_KZ)
kz05_txt = input.string("04-05", "", inline = "KZ05", group = g_KZ)
kz05 = input.session("0400-0500", "", inline = "KZ05", group = g_KZ)
kz05_color = input.color(color.blue, "", inline = "KZ05", group = g_KZ)
// ==================== KILLZONE 06 ====================
use_kz06 = input.bool(true, "05:00-06:00", inline = "KZ06", group = g_KZ)
kz06_txt = input.string("05-06", "", inline = "KZ06", group = g_KZ)
kz06 = input.session("0500-0600", "", inline = "KZ06", group = g_KZ)
kz06_color = input.color(color.blue, "", inline = "KZ06", group = g_KZ)
// ==================== KILLZONE 07 ====================
use_kz07 = input.bool(true, "06:00-07:00", inline = "KZ07", group = g_KZ)
kz07_txt = input.string("06-07", "", inline = "KZ07", group = g_KZ)
kz07 = input.session("0600-0700", "", inline = "KZ07", group = g_KZ)
kz07_color = input.color(color.blue, "", inline = "KZ07", group = g_KZ)
// ==================== KILLZONE 08 ====================
use_kz08 = input.bool(true, "07:00-08:00", inline = "KZ08", group = g_KZ)
kz08_txt = input.string("07-08", "", inline = "KZ08", group = g_KZ)
kz08 = input.session("0700-0800", "", inline = "KZ08", group = g_KZ)
kz08_color = input.color(color.blue, "", inline = "KZ08", group = g_KZ)
// ==================== KILLZONE 09 ====================
use_kz09 = input.bool(true, "08:00-09:00", inline = "KZ09", group = g_KZ)
kz09_txt = input.string("08-09", "", inline = "KZ09", group = g_KZ)
kz09 = input.session("0800-0900", "", inline = "KZ09", group = g_KZ)
kz09_color = input.color(color.blue, "", inline = "KZ09", group = g_KZ)
// ==================== KILLZONE 10 ====================
use_kz10 = input.bool(true, "09:00-10:00", inline = "KZ10", group = g_KZ)
kz10_txt = input.string("09-10", "", inline = "KZ10", group = g_KZ)
kz10 = input.session("0900-1000", "", inline = "KZ10", group = g_KZ)
kz10_color = input.color(color.blue, "", inline = "KZ10", group = g_KZ)
// ==================== KILLZONE 11 ====================
use_kz11 = input.bool(true, "10:00-11:00", inline = "KZ11", group = g_KZ)
kz11_txt = input.string("10-11", "", inline = "KZ11", group = g_KZ)
kz11 = input.session("1000-1100", "", inline = "KZ11", group = g_KZ)
kz11_color = input.color(color.blue, "", inline = "KZ11", group = g_KZ)
// ==================== KILLZONE 12 ====================
use_kz12 = input.bool(true, "11:00-12:00", inline = "KZ12", group = g_KZ)
kz12_txt = input.string("11-12", "", inline = "KZ12", group = g_KZ)
kz12 = input.session("1100-1200", "", inline = "KZ12", group = g_KZ)
kz12_color = input.color(color.blue, "", inline = "KZ12", group = g_KZ)
// ==================== KILLZONE 13 ====================
use_kz13 = input.bool(true, "12:00-13:00", inline = "KZ13", group = g_KZ)
kz13_txt = input.string("12-13", "", inline = "KZ13", group = g_KZ)
kz13 = input.session("1200-1300", "", inline = "KZ13", group = g_KZ)
kz13_color = input.color(color.blue, "", inline = "KZ13", group = g_KZ)
// ==================== KILLZONE 14 ====================
use_kz14 = input.bool(true, "13:00-14:00", inline = "KZ14", group = g_KZ)
kz14_txt = input.string("13-14", "", inline = "KZ14", group = g_KZ)
kz14 = input.session("1300-1400", "", inline = "KZ14", group = g_KZ)
kz14_color = input.color(color.blue, "", inline = "KZ14", group = g_KZ)
// ==================== KILLZONE 15 ====================
use_kz15 = input.bool(true, "14:00-15:00", inline = "KZ15", group = g_KZ)
kz15_txt = input.string("14-15", "", inline = "KZ15", group = g_KZ)
kz15 = input.session("1400-1500", "", inline = "KZ15", group = g_KZ)
kz15_color = input.color(color.blue, "", inline = "KZ15", group = g_KZ)
// ==================== KILLZONE 16 ====================
use_kz16 = input.bool(true, "15:00-16:00", inline = "KZ16", group = g_KZ)
kz16_txt = input.string("15-16", "", inline = "KZ16", group = g_KZ)
kz16 = input.session("1500-1600", "", inline = "KZ16", group = g_KZ)
kz16_color = input.color(color.blue, "", inline = "KZ16", group = g_KZ)
// ==================== KILLZONE 17 ====================
use_kz17 = input.bool(true, "16:00-17:00", inline = "KZ17", group = g_KZ)
kz17_txt = input.string("16-17", "", inline = "KZ17", group = g_KZ)
kz17 = input.session("1600-1700", "", inline = "KZ17", group = g_KZ)
kz17_color = input.color(color.blue, "", inline = "KZ17", group = g_KZ)
// ==================== KILLZONE 18 ====================
use_kz18 = input.bool(true, "17:00-18:00", inline = "KZ18", group = g_KZ)
kz18_txt = input.string("17-18", "", inline = "KZ18", group = g_KZ)
kz18 = input.session("1700-1800", "", inline = "KZ18", group = g_KZ)
kz18_color = input.color(color.blue, "", inline = "KZ18", group = g_KZ)
// ==================== KILLZONE 19 ====================
use_kz19 = input.bool(true, "18:00-19:00", inline = "KZ19", group = g_KZ)
kz19_txt = input.string("18-19", "", inline = "KZ19", group = g_KZ)
kz19 = input.session("1800-1900", "", inline = "KZ19", group = g_KZ)
kz19_color = input.color(color.blue, "", inline = "KZ19", group = g_KZ)
// ==================== KILLZONE 20 ====================
use_kz20 = input.bool(true, "19:00-20:00", inline = "KZ20", group = g_KZ)
kz20_txt = input.string("19-20", "", inline = "KZ20", group = g_KZ)
kz20 = input.session("1900-2000", "", inline = "KZ20", group = g_KZ)
kz20_color = input.color(color.blue, "", inline = "KZ20", group = g_KZ)
// ==================== KILLZONE 21 ====================
use_kz21 = input.bool(true, "20:00-21:00", inline = "KZ21", group = g_KZ)
kz21_txt = input.string("20-21", "", inline = "KZ21", group = g_KZ)
kz21 = input.session("2000-2100", "", inline = "KZ21", group = g_KZ)
kz21_color = input.color(color.blue, "", inline = "KZ21", group = g_KZ)
// ==================== KILLZONE 22 ====================
use_kz22 = input.bool(true, "21:00-22:00", inline = "KZ22", group = g_KZ)
kz22_txt = input.string("21-22", "", inline = "KZ22", group = g_KZ)
kz22 = input.session("2100-2200", "", inline = "KZ22", group = g_KZ)
kz22_color = input.color(color.blue, "", inline = "KZ22", group = g_KZ)
// ==================== KILLZONE 23 ====================
use_kz23 = input.bool(true, "22:00-23:00", inline = "KZ23", group = g_KZ)
kz23_txt = input.string("22-23", "", inline = "KZ23", group = g_KZ)
kz23 = input.session("2200-2300", "", inline = "KZ23", group = g_KZ)
kz23_color = input.color(color.blue, "", inline = "KZ23", group = g_KZ)
// ==================== KILLZONE 24 ====================
use_kz24 = input.bool(true, "23:00-00:00", inline = "KZ24", group = g_KZ)
kz24_txt = input.string("23-00", "", inline = "KZ24", group = g_KZ)
kz24 = input.session("2300-0000", "", inline = "KZ24", group = g_KZ)
kz24_color = input.color(color.blue, "", inline = "KZ24", group = g_KZ)
// ==================== KILLZONE 25 ====================
use_kz25 = input.bool(true, "17:00-21:00", inline = "KZ25", group = g_KZ)
kz25_txt = input.string("17-21", "", inline = "KZ25", group = g_KZ)
kz25 = input.session("1700-2100", "", inline = "KZ25", group = g_KZ)
kz25_color = input.color(color.orange, "", inline = "KZ25", group = g_KZ)
// ==================== KILLZONE 26 ====================
use_kz26 = input.bool(true, "21:00-01:00", inline = "KZ26", group = g_KZ)
kz26_txt = input.string("21-01", "", inline = "KZ26", group = g_KZ)
kz26 = input.session("2100-0100", "", inline = "KZ26", group = g_KZ)
kz26_color = input.color(color.aqua, "", inline = "KZ26", group = g_KZ)
// ==================== KILLZONE 27 ====================
use_kz27 = input.bool(true, "01:00-05:00", inline = "KZ27", group = g_KZ)
kz27_txt = input.string("01-05", "", inline = "KZ27", group = g_KZ)
kz27 = input.session("0100-0500", "", inline = "KZ27", group = g_KZ)
kz27_color = input.color(color.green, "", inline = "KZ27", group = g_KZ)
// ==================== KILLZONE 28 ====================
use_kz28 = input.bool(true, "05:00-09:00", inline = "KZ28", group = g_KZ)
kz28_txt = input.string("05-09", "", inline = "KZ28", group = g_KZ)
kz28 = input.session("0500-0900", "", inline = "KZ28", group = g_KZ)
kz28_color = input.color(color.yellow, "", inline = "KZ28", group = g_KZ)
// ==================== KILLZONE 29 ====================
use_kz29 = input.bool(true, "09:00-13:00", inline = "KZ29", group = g_KZ)
kz29_txt = input.string("09-13", "", inline = "KZ29", group = g_KZ)
kz29 = input.session("0900-1300", "", inline = "KZ29", group = g_KZ)
kz29_color = input.color(color.red, "", inline = "KZ29", group = g_KZ)
// ==================== KILLZONE 30 ====================
use_kz30 = input.bool(true, "13:00-17:00", inline = "KZ30", group = g_KZ)
kz30_txt = input.string("13-17", "", inline = "KZ30", group = g_KZ)
kz30 = input.session("1300-1700", "", inline = "KZ30", group = g_KZ)
kz30_color = input.color(color.purple, "", inline = "KZ30", group = g_KZ)
var g_LABELS = "Killzone Pivots"
show_pivots = input.bool(false, "Show Pivots", inline = "PV", group = g_LABELS)
use_alerts = input.bool(false, "Alert Broken Pivots", inline = "PV", tooltip = "The desired killzones must be enabled at the time that an alert is created, along with the show pivots option, in order for alerts to work", group = g_LABELS)
show_midpoints = input.bool(false, "Show Pivot Midpoints", inline = "mp", group = g_LABELS)
stop_midpoints = input.bool(false, "Stop Once Mitigated", inline = "mp", group = g_LABELS)
show_labels = input.bool(false, "Show Pivot Labels", inline = "LB", tooltip = "Show labels denoting each killzone's high and low. Optionally choose to show the price of each level. Right side will show labels on the right-hand side of the chart until they are reached", group = g_LABELS)
label_price = input.bool(false, "Display Price", inline = "LB", group = g_LABELS)
label_right = input.bool(false, "Right Side", inline = "LB", group = g_LABELS)
ext_pivots = input.string("Until Mitigated", "Extend Pivots...", options = , group = g_LABELS)
ext_which = input.string("All", "...From Which Sessions", options = , group = g_LABELS)
ash_str = input.string("AS.H", "Killzone 1 Labels", inline = "L_AS", group = g_LABELS)
asl_str = input.string("AS.L", "", inline = "L_AS", group = g_LABELS)
loh_str = input.string("LO.H", "Killzone 2 Labels", inline = "L_LO", group = g_LABELS)
lol_str = input.string("LO.L", "", inline = "L_LO", group = g_LABELS)
nah_str = input.string("NYAM.H", "Killzone 3 Labels", inline = "L_NA", group = g_LABELS)
nal_str = input.string("NYAM.L", "", inline = "L_NA", group = g_LABELS)
nlh_str = input.string("NYL.H", "Killzone 4 Labels", inline = "L_NL", group = g_LABELS)
nll_str = input.string("NYL.L", "", inline = "L_NL", group = g_LABELS)
nph_str = input.string("NYPM.H", "Killzone 5 Labels", inline = "L_NP", group = g_LABELS)
npl_str = input.string("NYPM.L", "", inline = "L_NP", group = g_LABELS)
kzp_style = get_line_type(input.string(defval = 'Solid', title = "Pivot Style", options = , inline = "KZP", group = g_LABELS))
kzp_width = input.int(1, "", inline = "KZP", group = g_LABELS)
kzm_style = get_line_type(input.string(defval = 'Dotted', title = "Midpoint Style", options = , inline = "KZM", group = g_LABELS))
kzm_width = input.int(1, "", inline = "KZM", group = g_LABELS)
var g_RNG = "Killzone Range"
show_range = input.bool(false, "Show Killzone Range", tooltip = "Show the most recent ranges of each selected killzone, from high to low", group = g_RNG)
show_range_avg = input.bool(false, "Show Average", tooltip = "Show the average range of each selected killzone", group = g_RNG)
range_avg = input.int(5, "Average Length", 0, tooltip = "This many previous sessions will be used to calculate the average. If there isn't enough data on the current chart, it will use as many sessions as possible", group = g_RNG)
range_pos = get_table_pos(input.string('Top Right', "Table Position", options = , group = g_RNG))
range_size = get_size(input.string('Normal', "Table Size", options = , group = g_RNG))
var g_DWM = "Day - Week - Month"
sep_unlimited = input.bool(false, "Unlimited", tooltip = "Unlimited will show as many of the selected lines as possible. Otherwise, the session drawing limit will be used", group = g_DWM)
alert_HL = input.bool(false, "Alert High/Low Break", tooltip = "Alert when any selected highs and lows are traded through. The desired timeframe's high/low option must be enabled at the time that an alert is created", group = g_DWM)
show_d_open = input.bool(false, "D Open", inline = "DO", group = g_DWM)
dhl = input.bool(false, "High/Low", inline = "DO", tooltip = "", group = g_DWM)
ds = input.bool(false, "Separators", inline = "DO", tooltip = "Mark where a new day begins", group = g_DWM)
d_color = input.color(color.blue, "", inline = "DO", group = g_DWM)
show_w_open = input.bool(false, "W Open", inline = "WO", group = g_DWM)
whl = input.bool(false, "High/Low", inline = "WO", tooltip = "", group = g_DWM)
ws = input.bool(false, "Separators", inline = "WO", tooltip = "Mark where a new week begins", group = g_DWM)
w_color = input.color(#089981, "", inline = "WO", group = g_DWM)
show_m_open = input.bool(false, "M Open", inline = "MO", group = g_DWM)
mhl = input.bool(false, "High/Low", inline = "MO", tooltip = "", group = g_DWM)
ms = input.bool(false, "Separators", inline = "MO", tooltip = "Mark where a new month begins", group = g_DWM)
m_color = input.color(color.red, "", inline = "MO", group = g_DWM)
htf_style = get_line_type(input.string(defval = 'Solid', title = "Style", options = , inline = "D0", group = g_DWM))
htf_width = input.int(1, "", inline = "D0", group = g_DWM)
dow_labels = input.bool(false, "Day of Week Labels", inline = "DOW", group = g_DWM)
dow_yloc = input.string('Bottom', "", options = , inline = "DOW", group = g_DWM)
dow_xloc = input.string('Midnight', "", options = , inline = "DOW", group = g_DWM)
dow_hide_wknd = input.bool(false, "Hide Weekend Labels", group = g_DWM)
var g_OPEN = "Opening Prices"
open_unlimited = input.bool(false, "Unlimited", tooltip = "Unlimited will show as many of the selected lines as possible. Otherwise, the session drawing limit will be used", group = g_OPEN)
use_h1 = input.bool(false, "", inline = "H1", group = g_OPEN)
h1_text = input.string("18:00 H12/H8/H6/H4", "", inline = "H1", group = g_OPEN)
h1 = input.session("1800-1801", "", inline = "H1", group = g_OPEN)
h1_color = input.color(color.black, "", inline = "H1", group = g_OPEN)
use_h2 = input.bool(false, "", inline = "H2", group = g_OPEN)
h2_text = input.string("06:00 H12/H6/H4", "", inline = "H2", group = g_OPEN)
h2 = input.session("0600-0601", "", inline = "H2", group = g_OPEN)
h2_color = input.color(color.black, "", inline = "H2", group = g_OPEN)
use_h3 = input.bool(false, "", inline = "H3", group = g_OPEN)
h3_text = input.string("10:00 H8/H4", "", inline = "H3", group = g_OPEN)
h3 = input.session("1000-1001", "", inline = "H3", group = g_OPEN)
h3_color = input.color(color.black, "", inline = "H3", group = g_OPEN)
use_h4 = input.bool(false, "", inline = "H4", group = g_OPEN)
h4_text = input.string("02:00 H8/H4", "", inline = "H4", group = g_OPEN)
h4 = input.session("0200-0201", "", inline = "H4", group = g_OPEN)
h4_color = input.color(color.black, "", inline = "H4", group = g_OPEN)
use_h5 = input.bool(false, "", inline = "H5", group = g_OPEN)
h5_text = input.string("00:00 H6", "", inline = "H5", group = g_OPEN)
h5 = input.session("0000-0001", "", inline = "H5", group = g_OPEN)
h5_color = input.color(color.black, "", inline = "H5", group = g_OPEN)
use_h6 = input.bool(false, "", inline = "H6", group = g_OPEN)
h6_text = input.string("12:00 H6", "", inline = "H6", group = g_OPEN)
h6 = input.session("1200-1201", "", inline = "H6", group = g_OPEN)
h6_color = input.color(color.black, "", inline = "H6", group = g_OPEN)
use_h7 = input.bool(false, "", inline = "H7", group = g_OPEN)
h7_text = input.string("22:00 H4", "", inline = "H7", group = g_OPEN)
h7 = input.session("2200-2201", "", inline = "H7", group = g_OPEN)
h7_color = input.color(color.black, "", inline = "H7", group = g_OPEN)
use_h8 = input.bool(false, "", inline = "H8", group = g_OPEN)
h8_text = input.string("14:00 H4", "", inline = "H8", group = g_OPEN)
h8 = input.session("1400-1401", "", inline = "H8", group = g_OPEN)
h8_color = input.color(color.black, "", inline = "H8", group = g_OPEN)
hz_style = get_line_type(input.string(defval = 'Dotted', title = "Style", options = , inline = "H0", group = g_OPEN))
hz_width = input.int(1, "", inline = "H0", group = g_OPEN)
var g_VERTICAL = "Timestamps"
v_unlimited = input.bool(false, "Unlimited", tooltip = "Unlimited will show as many of the selected lines as possible. Otherwise, the session drawing limit will be used", group = g_VERTICAL)
use_v1 = input.bool(false, "", inline = "V1", group = g_VERTICAL)
v1 = input.session("0000-0001", "", inline = "V1", group = g_VERTICAL)
v1_color = input.color(color.black, "", inline = "V1", group = g_VERTICAL)
use_v2 = input.bool(false, "", inline = "V2", group = g_VERTICAL)
v2 = input.session("0800-0801", "", inline = "V2", group = g_VERTICAL)
v2_color = input.color(color.black, "", inline = "V2", group = g_VERTICAL)
use_v3 = input.bool(false, "", inline = "V3", group = g_VERTICAL)
v3 = input.session("1000-1001", "", inline = "V3", group = g_VERTICAL)
v3_color = input.color(color.black, "", inline = "V3", group = g_VERTICAL)
use_v4 = input.bool(false, "", inline = "V4", group = g_VERTICAL)
v4 = input.session("1200-1201", "", inline = "V4", group = g_VERTICAL)
v4_color = input.color(color.black, "", inline = "V4", group = g_VERTICAL)
vl_style = get_line_type(input.string(defval = 'Dotted', title = "Style", options = , inline = "V0", group = g_VERTICAL))
vl_width = input.int(1, "", inline = "V0", group = g_VERTICAL)
// ---------------------------------------- Inputs --------------------------------------------------
// ---------------------------------------- Variables & Constants --------------------------------------------------
type kz
string _title
array _box
array _hi_line
array _md_line
array _lo_line
array _hi_label
array _lo_label
array _hi_valid
array _md_valid
array _lo_valid
array _range_store
float _range_current
type hz
array LN
array LB
array CO
type dwm_hl
array hi_line
array lo_line
array hi_label
array lo_label
bool hit_high = false
bool hit_low = false
type dwm_info
string tf
float o = na
float h = na
float l = na
float ph = na
float pl = na
type lines_helper
hz _hz
string h
string h_text
color h_color
initLines() =>
array res = array.new()
if use_h1
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h1, h1_text, h1_color))
if use_h2
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h2, h2_text, h2_color))
if use_h3
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h3, h3_text, h3_color))
if use_h4
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h4, h4_text, h4_color))
if use_h5
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h5, h5_text, h5_color))
if use_h6
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h6, h6_text, h6_color))
if use_h7
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h7, h7_text, h7_color))
if use_h8
res.push(lines_helper.new(hz.new(array.new_line(), array.new_label(), array.new_bool()), h8, h8_text, h8_color))
res
var array lines = initLines()
type kz_helper
kz _kz
string session
color c
string box_txt
string hi_txt
string lo_txt
initKZ() =>
array res = array.new()
if use_kz01
res.push(kz_helper.new(
kz.new(kz01_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz01, kz01_color, kz01_txt, "KZ01.H", "KZ01.L"
))
if use_kz02
res.push(kz_helper.new(
kz.new(kz02_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz02, kz02_color, kz02_txt, "KZ02.H", "KZ02.L"
))
if use_kz03
res.push(kz_helper.new(
kz.new(kz03_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz03, kz03_color, kz03_txt, "KZ03.H", "KZ03.L"
))
if use_kz04
res.push(kz_helper.new(
kz.new(kz04_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz04, kz04_color, kz04_txt, "KZ04.H", "KZ04.L"
))
if use_kz05
res.push(kz_helper.new(
kz.new(kz05_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz05, kz05_color, kz05_txt, "KZ05.H", "KZ05.L"
))
if use_kz06
res.push(kz_helper.new(
kz.new(kz06_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz06, kz06_color, kz06_txt, "KZ06.H", "KZ06.L"
))
if use_kz07
res.push(kz_helper.new(
kz.new(kz07_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz07, kz07_color, kz07_txt, "KZ07.H", "KZ07.L"
))
if use_kz08
res.push(kz_helper.new(
kz.new(kz08_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz08, kz08_color, kz08_txt, "KZ08.H", "KZ08.L"
))
if use_kz09
res.push(kz_helper.new(
kz.new(kz09_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz09, kz09_color, kz09_txt, "KZ09.H", "KZ09.L"
))
if use_kz10
res.push(kz_helper.new(
kz.new(kz10_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz10, kz10_color, kz10_txt, "KZ10.H", "KZ10.L"
))
if use_kz11
res.push(kz_helper.new(
kz.new(kz11_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz11, kz11_color, kz11_txt, "KZ11.H", "KZ11.L"
))
if use_kz12
res.push(kz_helper.new(
kz.new(kz12_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz12, kz12_color, kz12_txt, "KZ12.H", "KZ12.L"
))
if use_kz13
res.push(kz_helper.new(
kz.new(kz13_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz13, kz13_color, kz13_txt, "KZ13.H", "KZ13.L"
))
if use_kz14
res.push(kz_helper.new(
kz.new(kz14_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz14, kz14_color, kz14_txt, "KZ14.H", "KZ14.L"
))
if use_kz15
res.push(kz_helper.new(
kz.new(kz15_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz15, kz15_color, kz15_txt, "KZ15.H", "KZ15.L"
))
if use_kz16
res.push(kz_helper.new(
kz.new(kz16_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz16, kz16_color, kz16_txt, "KZ16.H", "KZ16.L"
))
if use_kz17
res.push(kz_helper.new(
kz.new(kz17_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz17, kz17_color, kz17_txt, "KZ17.H", "KZ17.L"
))
if use_kz18
res.push(kz_helper.new(
kz.new(kz18_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz18, kz18_color, kz18_txt, "KZ18.H", "KZ18.L"
))
if use_kz19
res.push(kz_helper.new(
kz.new(kz19_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz19, kz19_color, kz19_txt, "KZ19.H", "KZ19.L"
))
if use_kz20
res.push(kz_helper.new(
kz.new(kz20_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz20, kz20_color, kz20_txt, "KZ20.H", "KZ20.L"
))
if use_kz21
res.push(kz_helper.new(
kz.new(kz21_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz21, kz21_color, kz21_txt, "KZ21.H", "KZ21.L"
))
if use_kz22
res.push(kz_helper.new(
kz.new(kz22_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz22, kz22_color, kz22_txt, "KZ22.H", "KZ22.L"
))
if use_kz23
res.push(kz_helper.new(
kz.new(kz23_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz23, kz23_color, kz23_txt, "KZ23.H", "KZ23.L"
))
if use_kz24
res.push(kz_helper.new(
kz.new(kz24_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz24, kz24_color, kz24_txt, "KZ24.H", "KZ24.L"
))
if use_kz25
res.push(kz_helper.new(
kz.new(kz25_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz25, kz25_color, kz25_txt, "KZ25.H", "KZ25.L"
))
if use_kz26
res.push(kz_helper.new(
kz.new(kz26_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz26, kz26_color, kz26_txt, "KZ26.H", "KZ26.L"
))
if use_kz27
res.push(kz_helper.new(
kz.new(kz27_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz27, kz27_color, kz27_txt, "KZ27.H", "KZ27.L"
))
if use_kz28
res.push(kz_helper.new(
kz.new(kz28_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz28, kz28_color, kz28_txt, "KZ28.H", "KZ28.L"
))
if use_kz29
res.push(kz_helper.new(
kz.new(kz29_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz29, kz29_color, kz29_txt, "KZ29.H", "KZ29.L"
))
if use_kz30
res.push(kz_helper.new(
kz.new(kz30_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float()),
kz30, kz30_color, kz30_txt, "KZ30.H", "KZ30.L"
))
res
var array _kz = initKZ()
var d_hl = dwm_hl.new(array.new_line(), array.new_line(), array.new_label(), array.new_label())
var w_hl = dwm_hl.new(array.new_line(), array.new_line(), array.new_label(), array.new_label())
var m_hl = dwm_hl.new(array.new_line(), array.new_line(), array.new_label(), array.new_label())
var d_info = dwm_info.new("D")
var w_info = dwm_info.new("W")
var m_info = dwm_info.new("M")
t_co = not na(time("", cutoff, gmt_tz))
type ts_helper
string session
array lines
color c
initTS() =>
array res = array.new()
if use_v1
res.push(ts_helper.new(v1, array.new_line(), v1_color))
if use_v2
res.push(ts_helper.new(v2, array.new_line(), v2_color))
if use_v3
res.push(ts_helper.new(v3, array.new_line(), v3_color))
if use_v4
res.push(ts_helper.new(v4, array.new_line(), v4_color))
res
var array ts_data = initTS()
var d_sep_line = array.new_line()
var w_sep_line = array.new_line()
var m_sep_line = array.new_line()
var d_line = array.new_line()
var w_line = array.new_line()
var m_line = array.new_line()
var d_label = array.new_label()
var w_label = array.new_label()
var m_label = array.new_label()
var transparent = #ffffff00
var ext_current = ext_which == 'Most Recent'
var ext_past = ext_pivots == 'Past Mitigation'
update_dwm_info(dwm_info n) =>
if timeframe.change(n.tf)
n.ph := n.h
n.pl := n.l
n.o := open
n.h := high
n.l := low
else
n.h := math.max(high, n.h)
n.l := math.min(low, n.l)
if dhl or show_d_open
update_dwm_info(d_info)
if whl or show_w_open
update_dwm_info(w_info)
if mhl or show_m_open
update_dwm_info(m_info)
// ---------------------------------------- Variables & Constants --------------------------------------------------
// ---------------------------------------- Functions --------------------------------------------------
get_box_color(color c) =>
color.new(c, box_transparency)
get_text_color(color c) =>
color.new(c, text_transparency)
// ---------------------------------------- Functions --------------------------------------------------
// ---------------------------------------- Core Logic --------------------------------------------------
dwm_sep(string tf, bool use, array arr, color col) =>
if use
if timeframe.change(tf)
arr.unshift(line.new(bar_index, high * 1.0001, bar_index, low, style = htf_style, width = htf_width, extend = extend.both, color = col))
if not sep_unlimited and arr.size() > max_days
arr.pop().delete()
dwm_open(string tf, bool use, array lns, array lbls, dwm_info n, color col) =>
if use
if lns.size() > 0
lns.get(0).set_x2(time)
lbls.get(0).set_x(time)
if timeframe.change(tf)
lns.unshift(line.new(time, n.o, time, n.o, xloc = xloc.bar_time, style = htf_style, width = htf_width, color = col))
lbls.unshift(label.new(time, n.o, tf + " OPEN", xloc = xloc.bar_time, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size))
if not sep_unlimited and lns.size() > max_days
lns.pop().delete()
lbls.pop().delete()
dwm_hl(string tf, bool use, dwm_hl hl, dwm_info n, color col) =>
if use
if hl.hi_line.size() > 0
hl.hi_line.get(0).set_x2(time)
hl.lo_line.get(0).set_x2(time)
hl.hi_label.get(0).set_x(time)
hl.lo_label.get(0).set_x(time)
if timeframe.change(tf)
hl.hi_line.unshift(line.new(time, n.ph, time, n.ph, xloc = xloc.bar_time, style = htf_style, width = htf_width, color = col))
hl.lo_line.unshift(line.new(time, n.pl, time, n.pl, xloc = xloc.bar_time, style = htf_style, width = htf_width, color = col))
hl.hi_label.unshift(label.new(time, n.ph, "P" + tf + "H", xloc = xloc.bar_time, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size))
hl.lo_label.unshift(label.new(time, n.pl, "P" + tf + "L", xloc = xloc.bar_time, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size))
hl.hit_high := false
hl.hit_low := false
if not sep_unlimited and hl.hi_line.size() > max_days
hl.hi_line.pop().delete()
hl.lo_line.pop().delete()
hl.hi_label.pop().delete()
hl.lo_label.pop().delete()
if hl.hi_line.size() > 0 and alert_HL
if not hl.hit_high and high > hl.hi_line.get(0).get_y1()
hl.hit_high := true
alert(str.format("Hit P{0}H", tf))
if not hl.hit_low and low < hl.lo_line.get(0).get_y1()
hl.hit_low := true
alert(str.format("Hit P{0}L", tf))
dwm() =>
if tf_limit_is_equal_or_more_chart_tf
// DWM - Separators
dwm_sep("D", ds, d_sep_line, d_color)
dwm_sep("W", ws, w_sep_line, w_color)
dwm_sep("M", ms, m_sep_line, m_color)
// DWM - Open Lines
dwm_open("D", show_d_open, d_line, d_label, d_info, d_color)
dwm_open("W", show_w_open, w_line, w_label, w_info, w_color)
dwm_open("M", show_m_open, m_line, m_label, m_info, m_color)
// DWM - Highs and Lows
dwm_hl("D", dhl, d_hl, d_info, d_color)
dwm_hl("W", whl, w_hl, w_info, w_color)
dwm_hl("M", mhl, m_hl, m_info, m_color)
method vline(ts_helper this) =>
bool t = not na(time("", this.session, gmt_tz))
bool t_prev = not na(time("", this.session, gmt_tz, bars_back = 1))
array arr = this.lines
color col = this.c
if t and not t_prev
arr.unshift(line.new(bar_index, high * 1.0001, bar_index, low, style = vl_style, width = vl_width, extend = extend.both, color = col))
if not v_unlimited
if arr.size() > max_days
arr.pop().delete()
vlines() =>
if tf_limit_is_equal_or_more_chart_tf
for in ts_data
vline(value)
method hz_line(lines_helper this) =>
bool t = not na(time("", this.h, gmt_tz))
bool t_prev = not na(time("", this.h, gmt_tz, bars_back = 1))
hz hz = this._hz
string txt = this.h_text
color col = this.h_color
if t and not t_prev
hz.LN.unshift(line.new(bar_index, open, bar_index, open, style = hz_style, width = hz_width, color = col))
hz.LB.unshift(label.new(bar_index, open, txt, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size))
array.unshift(hz.CO, false)
if not open_unlimited and hz.LN.size() > max_days
hz.LN.pop().delete()
hz.LB.pop().delete()
hz.CO.pop()
if not t and hz.CO.size() > 0
if not hz.CO.get(0)
hz.LN.get(0).set_x2(bar_index)
hz.LB.get(0).set_x(bar_index)
if (use_cutoff ? t_co : false)
hz.CO.set(0, true)
hz_lines() =>
if tf_limit_is_equal_or_more_chart_tf
for in lines
hz_line(value)
del_kz(kz k) =>
if k._box.size() > max_days
k._box.pop().delete()
if k._hi_line.size() > max_days
k._hi_line.pop().delete()
k._lo_line.pop().delete()
k._hi_valid.pop()
k._lo_valid.pop()
if show_midpoints
k._md_line.pop().delete()
k._md_valid.pop()
if k._hi_label.size() > max_days
k._hi_label.pop().delete()
k._lo_label.pop().delete()
update_price_string(label L, float P) =>
S = L.get_text()
pre = str.substring(S, 0, str.pos(S, " "))
str.trim(pre)
L.set_text(str.format("{0} ({1})", pre, P))
adjust_in_kz(kz kz, bool t) =>
if t
kzBox0 = kz._box.get(0)
kzBox0.set_right(time)
newTop = math.max(kzBox0.get_top(), high)
kzBox0.set_top(newTop)
newBottom = math.min(kzBox0.get_bottom(), low)
kzBox0.set_bottom(newBottom)
kz._range_current := newTop - newBottom
if show_pivots and kz._hi_line.size() > 0
kzHiLine0 = kz._hi_line.get(0)
kzHiLine0.set_x2(time)
if high > kzHiLine0.get_y1()
kzHiLine0.set_xy1(time, high)
kzHiLine0.set_xy2(time, high)
kzLoLine0 = kz._lo_line.get(0)
kzLoLine0.set_x2(time)
if low < kzLoLine0.get_y1()
kzLoLine0.set_xy1(time, low)
kzLoLine0.set_xy2(time, low)
if show_midpoints
kzMidLine0 = kz._md_line.get(0)
kzMidLine0.set_x2(time)
kzMidLine0.set_xy1(time, math.avg(kzHiLine0.get_y2(), kzLoLine0.get_y2()))
kzMidLine0.set_xy2(time, math.avg(kzHiLine0.get_y2(), kzLoLine0.get_y2()))
if show_labels and kz._hi_label.size() > 0
if label_right
kz._hi_label.get(0).set_x(time)
kz._lo_label.get(0).set_x(time)
if high > kz._hi_label.get(0).get_y()
kz._hi_label.get(0).set_xy(time, high)
if label_price
update_price_string(kz._hi_label.get(0), high)
if low < kz._lo_label.get(0).get_y()
kz._lo_label.get(0).set_xy(time, low)
if label_price
update_price_string(kz._lo_label.get(0), low)
adjust_out_kz(kz kz, bool t, bool t_prev) =>
boxCount = kz._box.size()
if not t and boxCount > 0
if t_prev
array.unshift(kz._range_store, kz._range_current)
if kz._range_store.size() > range_avg
kz._range_store.pop()
if show_pivots and boxCount > 0
for i = 0 to boxCount - 1 by 1
if not ext_current or i == 0
kzHiValid = kz._hi_valid.get(i)
if ext_past or kzHiValid
kz._hi_line.get(i).set_x2(time)
if show_labels and label_right
kz._hi_label.get(i).set_x(time)
if kzHiValid and high > kz._hi_line.get(i).get_y1()
if use_alerts and i == 0
alert('Broke ' + kz._title + ' High', alert.freq_once_per_bar)
kz._hi_valid.set(i, false)
if show_labels and label_right
kz._hi_label.get(i).set_style(label.style_label_down)
else if use_cutoff ? t_co : false
kz._hi_valid.set(i, false)
kzLoValid = kz._lo_valid.get(i)
if ext_past or kzLoValid
kz._lo_line.get(i).set_x2(time)
if show_labels and label_right
kz._lo_label.get(i).set_x(time)
if kzLoValid and low < kz._lo_line.get(i).get_y1()
if use_alerts and i == 0
alert("Broke " + kz._title + " Low", alert.freq_once_per_bar)
kz._lo_valid.set(i, false)
if show_labels and label_right
kz._lo_label.get(i).set_style(label.style_label_up)
else if use_cutoff ? t_co : false
kz._lo_valid.set(i, false)
if show_midpoints and not t
if stop_midpoints ? kz._md_valid.get(i) : true
kz._md_line.get(i).set_x2(time)
if kz._md_valid.get(i) and low <= kz._md_line.get(i).get_y1() and high >= kz._md_line.get(i).get_y1()
kz._md_valid.set(i, false)
else
break
method manage_kz(kz_helper this) =>
kz kz = this._kz
c = this.c
string box_txt = this.box_txt
string hi_txt = this.hi_txt
string lo_txt = this.lo_txt
if tf_limit_is_equal_or_more_chart_tf
t = not na(time("", this.session, gmt_tz))
t_prev = not na(time("", this.session, gmt_tz, bars_back = 1))
if t and not t_prev
_c = get_box_color(c)
_t = get_text_color(c)
kz._box.unshift(box.new(time, high, time, low, xloc = xloc.bar_time, border_color = show_kz ? _c : na, bgcolor = show_kz ? _c : na, text = show_kz and show_kz_text ? box_txt : na, text_color = _t))
if show_pivots
kz._hi_line.unshift(line.new(time, high, time, high, xloc = xloc.bar_time, style = kzp_style, color = c, width = kzp_width))
kz._lo_line.unshift(line.new(time, low, time, low, xloc = xloc.bar_time, style = kzp_style, color = c, width = kzp_width))
if show_midpoints
kz._md_line.unshift(line.new(time, math.avg(high, low), time, math.avg(high, low), xloc = xloc.bar_time, style = kzm_style, color = c, width = kzm_width))
array.unshift(kz._md_valid, true)
array.unshift(kz._hi_valid, true)
array.unshift(kz._lo_valid, true)
if show_labels
_hi_txt = label_price ? str.format('{0} ({1})', hi_txt, high) : hi_txt
_lo_txt = label_price ? str.format('{0} ({1})', lo_txt, low) : lo_txt
if label_right
kz._hi_label.unshift(label.new(time, high, _hi_txt, xloc = xloc.bar_time, color = transparent, textcolor = txt_color, style = label.style_label_left, size = lbl_size))
kz._lo_label.unshift(label.new(time, low, _lo_txt, xloc = xloc.bar_time, color = transparent, textcolor = txt_color, style = label.style_label_left, size = lbl_size))
else
kz._hi_label.unshift(label.new(time, high, _hi_txt, xloc = xloc.bar_time, color = transparent, textcolor = txt_color, style = label.style_label_down, size = lbl_size))
kz._lo_label.unshift(label.new(time, low, _lo_txt, xloc = xloc.bar_time, color = transparent, textcolor = txt_color, style = label.style_label_up, size = lbl_size))
del_kz(kz)
adjust_in_kz(kz, t)
adjust_out_kz(kz, t, t_prev)
for in _kz
manage_kz(value)
dwm()
vlines()
hz_lines()
new_dow_time = dow_xloc == 'Midday' ? time - timeframe.in_seconds("D") / 2 * 1000 : time
new_day = dayofweek(new_dow_time, gmt_tz) != dayofweek(new_dow_time, gmt_tz)
var dow_top = dow_yloc == 'Top'
var saturday = "SATURDAY"
var sunday = "SUNDAY"
var monday = "MONDAY"
var tuesday = "TUESDAY"
var wednesday = "WEDNESDAY"
var thursday = "THURSDAY"
var friday = "FRIDAY"
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 1 and new_day and not dow_hide_wknd, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = sunday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 2 and new_day, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = monday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 3 and new_day, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = tuesday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 4 and new_day, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = wednesday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 5 and new_day, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = thursday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 6 and new_day, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = friday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 7 and new_day and not dow_hide_wknd, location = dow_top ? location.top : location.bottom, char = '', textcolor = txt_color, text = saturday)
get_min_days_stored() =>
store = array.new_int()
for in _kz
int tmpStoreSize = value._kz._range_store.size()
if tmpStoreSize > 0
store.push(tmpStoreSize)
store.min()
method set_table(table tbl, kz kz, int row, string txt, bool t, color col) =>
table.cell(tbl, 0, row, txt, text_size = range_size, bgcolor = get_box_color(col), text_color = txt_color)
table.cell(tbl, 1, row, str.tostring(kz._range_current), text_size = range_size, bgcolor = t ? get_box_color(col) : na, text_color = txt_color)
if show_range_avg
table.cell(tbl, 2, row, str.tostring(kz._range_store.avg()), text_size = range_size, text_color = txt_color)
if show_range and barstate.islast
var tbl = table.new(range_pos, 10, 10, chart.bg_color, chart.fg_color, 2, chart.fg_color, 1)
table.cell(tbl, 0, 0, "Killzone", text_size = range_size, text_color = txt_color)
table.cell(tbl, 1, 0, "Range", text_size = range_size, text_color = txt_color)
if show_range_avg
table.cell(tbl, 2, 0, "Avg (" + str.tostring(get_min_days_stored()) + ")", text_size = range_size, text_color = txt_color)
for in _kz
set_table(tbl, value._kz, index + 1, value.box_txt, not na(time("", value.session, gmt_tz)), value.c)
// ---------------------------------------- Core Logic --------------------------------------------------
Indicator

ICT FVG DetectorThis indicator identifies ICT Fair Value Gaps (FVGs) on any timeframe and overlays them as clean, interactive zones directly on your chart. It covers both standard imbalances and higher-timeframe (HTF) imbalances transposed onto lower timeframes — a core concept in ICT-based trading.
What it detects
BISI (Buy-side Imbalance, Sell-side Inefficiency) — bullish FVGs where a gap exists between the high of bar and the low of bar
SIBI (Sell-side Imbalance, Buy-side Inefficiency) — bearish FVGs where a gap exists between the low of bar and the high of bar
Displacement FVGs — tagged when the middle candle of the 3-bar pattern (the actual displacement candle) trades through the most recent confirmed swing high or low, signalling a genuine structure break
HTF Alignment
FVGs from the next-higher relevant timeframe are automatically transposed onto the current chart as gray-shaded zones, making it easy to identify where higher-timeframe imbalances sit without switching charts.
Valid pairs:
Chart timeframe HTF source
1m 15m
5m 1H
15m 4H
1H Daily
4H Weekly
Daily Monthly
HTF zones are visually distinct (gray fill) so they never compete with native FVGs. On unsupported timeframes, HTF zones are simply not drawn.
Features
Four draw styles: Lines + Fill, Lines Only, Fill Only, Boxes
Solid, dashed, or dotted boundary lines
Extend zones to current bar or a fixed number of bars
Mitigation tracking — zones dim or delete once price trades back through them (configurable separately for native and HTF FVGs)
Invisible hover labels positioned at the vertical midpoint of each zone — hover to instantly identify the gap type without cluttering the chart
Alerts for new BISI, SIBI, Displacement BISI, and Displacement SIBI
Settings
All inputs are grouped into five sections: FVG Detection, Swing / Displacement, Display, Mitigation, and HTF Alignment — making it straightforward to tune each layer independently.
Indicator

XauLabs Trend & Range**ENGLISH**
**What it does**
This indicator answers one question, and only one: is the market currently trending up, trending down, or ranging? It reads pure price structure — confirmed swing highs and swing lows — and states a verdict on the chart.
**How it works (full method)**
1. **Swing detection.** A swing high is confirmed only when the highs of the N bars before AND the N bars after are all lower (mirrored for swing lows). N is user-defined, default 7, range 5–21. Confirmation therefore arrives N bars after the actual extreme; the marker is then plotted at its true historical position and never moves again.
2. **Memory.** The script keeps the last two confirmed highs and the last two confirmed lows.
3. **Classification.**
- Uptrend: last high > previous high AND last low > previous low.
- Downtrend: last high < previous high AND last low < previous low.
- Range: anything else, including any state with fewer than two confirmed highs and two confirmed lows.
4. **Close-based invalidation** (optional, on by default). Any bar closing below the last confirmed swing low arms an invalidation flag. While that flag is armed, no uptrend is displayed: the state is forced to Range, even if the swing sequence otherwise qualifies as higher highs and higher lows. The flag is cleared only when a new swing low is confirmed. The logic is mirrored for downtrends, using a close above the last confirmed swing high. Wicks piercing the level do not count — only the close does. This mechanism can only suppress a trend reading, never create one: a trend must always earn its own structure.
**Why the delay is deliberate**
Signals never appear and later vanish. What the history shows is what would have been visible live. The cost is the N-bar confirmation delay, and it is stated openly rather than hidden behind a repainting display.
**On-chart output**
- Background tint: green uptrend, red downtrend, grey range.
- Triangles marking each confirmed swing high and low.
- A two-line state badge in the top-right corner, with selectable size and language (EN/FR).
- One alert condition: state change.
**Suggested use**
Start on H4. When the state reads Range, trend-following setups are structurally out of place — the indicator is meant to be used as a context filter before any entry logic, not as an entry trigger itself. The lower the sensitivity value, the faster and noisier the reading; the higher, the slower and more stable.
**Originality**
Most trend tools average price (moving averages, oscillators) and therefore lag by construction. This one reads structure only, applies a strict non-repainting confirmation rule, and adds a close-based invalidation layer so that a broken structure is downgraded to Range immediately rather than after the next swing forms. Open source: every rule above is verifiable line by line in the code.
This is an educational structure-reading tool. It gives no buy or sell signals and makes no performance claim. Trading involves substantial risk of loss.
---
**FRANÇAIS**
**Ce que fait l'indicateur**
Il répond à une seule question : le marché est-il en tendance haussière, baissière, ou en range ? Il lit la structure pure du prix — sommets et creux confirmés — et affiche son verdict.
**Comment il fonctionne (méthode complète)**
1. **Détection des pivots.** Un sommet n'est confirmé que si les N bougies avant ET les N bougies après ont toutes un plus haut inférieur (symétrique pour les creux). N est réglable, 7 par défaut, plage 5–21. La confirmation arrive donc N bougies après l'extrême réel ; le marqueur est ensuite tracé à sa vraie place historique et ne bouge plus jamais.
2. **Mémoire.** Le script conserve les deux derniers sommets et les deux derniers creux confirmés.
3. **Classification.**
- Hausse : dernier sommet > précédent ET dernier creux > précédent.
- Baisse : dernier sommet < précédent ET dernier creux < précédent.
- Range : tout le reste, y compris tant que moins de deux sommets et deux creux sont confirmés.
4. **Invalidation en clôture** (optionnelle, active par défaut). Toute bougie qui clôture sous le dernier creux confirmé arme une invalidation. Tant qu'elle est armée, aucune tendance haussière n'est affichée : l'état reste Range, même si la séquence de pivots remplit par ailleurs la condition sommets et creux ascendants. L'invalidation ne se désarme qu'à la confirmation d'un nouveau creux. Le mécanisme est symétrique en tendance baissière, avec une clôture au-dessus du dernier sommet confirmé. Une mèche qui perce le niveau ne suffit pas — seule la clôture compte. Ce mécanisme peut uniquement supprimer une lecture de tendance, jamais en créer une : une tendance doit toujours prouver sa propre structure.
**Pourquoi le délai est assumé**
Aucun signal n'apparaît puis ne disparaît. Ce que montre l'historique est ce qui aurait été visible en direct. La contrepartie est le délai de confirmation de N bougies, affiché ouvertement plutôt que masqué derrière un affichage qui se repeint.
**Affichage**
- Fond teinté : vert en hausse, rouge en baisse, gris en range.
- Triangles marquant chaque sommet et creux confirmé.
- Un badge d'état à deux lignes dans le coin supérieur droit, avec taille et langue (EN/FR) réglables.
- Une condition d'alerte : changement d'état.
**Utilisation suggérée**
Commencer en H4. Quand l'état affiche Range, les setups de suivi de tendance sont structurellement hors sujet — l'indicateur est conçu comme un filtre de contexte en amont d'une logique d'entrée, pas comme un déclencheur d'entrée. Plus la sensibilité est basse, plus la lecture est rapide et bruitée ; plus elle est haute, plus elle est lente et stable.
**Originalité**
La plupart des outils de tendance moyennent le prix (moyennes mobiles, oscillateurs) et retardent par construction. Celui-ci lit uniquement la structure, applique une règle de confirmation stricte sans repeinture, et ajoute une couche d'invalidation en clôture pour qu'une structure cassée redevienne Range immédiatement plutôt qu'au pivot suivant. Code ouvert : chaque règle ci-dessus est vérifiable ligne par ligne.
Outil éducatif de lecture de structure. Il ne donne aucun signal d'achat ou de vente et ne formule aucune promesse de performance. Le trading comporte un risque de perte important. Indicator

Smart Money Toolkit Pro [JPT]🔷 OVERVIEW
Smart Money Toolkit Pro is an original Pine Script® v6 indicator that combines multiple Smart Money Concepts (SMC) into one clean and powerful trading tool. It automatically detects market structure, Break of Structure (BOS), Change of Character (CHoCH), liquidity levels, liquidity sweeps, and dynamic support/resistance to help traders analyze price action with confidence.
Designed for Forex, Gold (XAUUSD), Crypto, Stocks, Indices, and Futures, the indicator provides a clear visual representation of institutional market behavior without requiring manual chart drawing.
🔷 HOW IT WORKS
The indicator continuously scans price using confirmed pivot highs and lows.
Market Structure
The script automatically identifies:
• Higher High (HH)
• Higher Low (HL)
• Lower High (LH)
• Lower Low (LL)
These labels help traders understand whether the market is trending, ranging, or reversing.
Break of Structure (BOS)
A BOS is generated when price closes beyond a previous confirmed swing in the direction of the current trend.
Bullish BOS
Price breaks above a previous Swing High.
Bearish BOS
Price breaks below a previous Swing Low.
Change of Character (CHoCH)
A CHoCH signals a potential shift in market direction.
Bullish CHoCH
Price breaks above the previous Lower High.
Bearish CHoCH
Price breaks below the previous Higher Low.
This helps traders recognize possible trend reversals early.
Liquidity Engine
The built-in liquidity engine automatically plots:
• Buy-Side Liquidity (BSL)
• Sell-Side Liquidity (SSL)
• Equal Highs (EQH)
• Equal Lows (EQL)
The indicator monitors these areas for liquidity grabs and sweep events commonly associated with institutional trading activity.
Liquidity Sweeps
The script detects:
• Buy-Side Liquidity Sweeps
• Sell-Side Liquidity Sweeps
When a sweep occurs, the indicator marks the event directly on the chart, allowing traders to identify potential reversal opportunities.
🔷 VISUAL FEATURES
• Automatic Market Structure Labels (HH, HL, LH, LL)
• Break of Structure (BOS)
• Change of Character (CHoCH)
• Buy-Side Liquidity (BSL)
• Sell-Side Liquidity (SSL)
• Equal High Detection
• Equal Low Detection
• Liquidity Sweep Detection
• Dynamic Swing High & Low Levels
• Trend Background Coloring
• Liquidity Dashboard
• Trend Dashboard
• Professional Chart Layout
• Customizable Colors
🔷 DASHBOARD
The built-in dashboard displays:
• Current Trend
• Last Confirmed High
• Last Confirmed Low
• Active Buy-Side Liquidity
• Active Sell-Side Liquidity
• Latest Liquidity Event
This provides a quick overview of current market conditions.
🔷 INPUTS
Available settings include:
• Pivot Strength
• Show Structure Labels
• Show Swing Levels
• Extend Swing Levels
• Show BOS
• Show CHoCH
• Show Liquidity
• Show Liquidity Sweeps
• Show Equal High / Low
• ATR Tolerance
• Maximum Historical Liquidity Levels
• Bullish Color
• Bearish Color
• Liquidity Colors
🔷 ALERTS
Built-in alerts are available for:
• Bullish BOS
• Bearish BOS
• Bullish CHoCH
• Bearish CHoCH
• Buy-Side Liquidity Sweep
• Sell-Side Liquidity Sweep
Alerts can be connected directly to PulseWire's notification system.
🔷 COMMON WORKFLOW
A typical workflow is:
Wait for confirmed market structure (HH, HL, LH, LL).
Observe BOS or CHoCH confirmation.
Monitor Buy-Side and Sell-Side Liquidity levels.
Watch for liquidity sweeps around key swing points.
Combine confirmations with your preferred entry strategy and risk management.
🔷 MARKETS
Smart Money Toolkit Pro can be used on:
• Forex
• Gold (XAUUSD)
• Silver (XAGUSD)
• Cryptocurrency
• Stocks
• Indices
• Futures
• Commodities
Compatible with all PulseWire-supported timeframes.
🔷 BEST PRACTICES
For additional confirmation, many traders combine this indicator with:
• Support & Resistance
• Supply & Demand Zones
• Order Blocks
• Fair Value Gaps (FVG)
• Fibonacci Retracement
• EMA 50 / EMA 200 Trend Filter
• Volume Analysis
• Higher Timeframe Confirmation
These concepts are optional but can enhance decision-making when used alongside market structure.
🔷 UPCOMING FEATURES
Future updates may include:
• Institutional Order Blocks
• Fair Value Gap (FVG) Detection
• Premium & Discount Zones
• Auto Fibonacci Retracement
• Multi-Timeframe Market Structure
• Entry & Exit Signals
• TP1, TP2, TP3 Auto Targets
• Stop Loss Calculation
• Risk/Reward Visualization
• Advanced Smart Money Dashboard
• Session Analysis
• Volume Confirmation
🔷 DISCLAIMER
This indicator is provided for educational and informational purposes only. It highlights market structure and liquidity concepts based on historical price action and does not predict future market movements or guarantee trading performance. Always conduct your own analysis, use proper risk management, and consider additional market factors before making trading decisions. Indicator

Strong MTF Liquidity Matrix | ProjectSyndicateStrong MTF Liquidity Matrix
Strong MTF Liquidity Matrix puts four higher-timeframe charts on one screen and reads the same institutional map on every one of them — order blocks, fair value gaps, and resting liquidity — then ranks each zone by strength so you know which level actually matters. It's a command deck: your main chart stays clean while four live mini-panels track the structure above you, and the liquidity pools that price is really hunting sit directly on your candles.
Most multi-timeframe tools make you flip between charts. This one stops the flipping.
🔲 Four-Panel MTF Engine — the core. Four independent mini-charts render right on your pane — M30 · H1 · H2 · H4 by default, each one fully configurable to any timeframe (drop to seconds or push to Daily). Every panel fetches its own higher-timeframe candles, keyed on the HTF bar's own time, so the zones are invariant to your master chart timeframe — switch your main chart from M30 to H1 to D1 and the panels don't move. The last candle in each panel tracks the live, forming HTF bar tick by tick.
🟩 Order Block Detection — real ICT logic, per timeframe. Each panel runs a swing-pivot + displacement scan: the last opposing candle before an impulsive move that clears your displacement multiple becomes the order block. Bull OBs from swing-low reversals, bear OBs from swing-high reversals — detected natively on every one of the four timeframes at once.
🟥 Fair Value Gap Detection — the imbalance map. True three-candle FVGs on each timeframe, with an optional ATR gap filter so only gaps worth trading survive. Bullish and bearish gaps rendered in the original green/red palette, distinct from the order blocks, on all four panels simultaneously.
🧲 Universal Zone Height — the accuracy differentiator. Raw OB/FVG zones come in wildly different sizes and clutter the read. Every zone is normalized to one clean height — ATR-based or a fixed percentage of price — so the panels stay legible and every zone carries equal visual weight. Fair value framed; noise removed.
🔢 0–10 Strength Ranking — the power-ranking. Every zone earns a live grade, printed inside the shaded box (OB 8.5, FVG 6.0). Order blocks score on displacement force, zone height and age; fair value gaps score on gap size versus ATR. Set a minimum strength floor and the weak zones simply don't draw — only the levels that earned attention survive.
🌊 Liquidity Heatmap — resting pools on your main chart. Buy-side and sell-side liquidity, seeded from fractal swing highs and lows across two pivot passes, drawn as heat-weighted boxes whose opacity scales with liquidity weight (volume × range). Strong pools glow, weak ones stay faint. When price trades through a pool it's consumed — the zone freezes and fades to show exactly what's already been taken. Colours locked 100% to the OB/FVG palette: buy-side green, sell-side red.
🏷️ Clean Liquidity Labels — above the zone, never in the way. Each resting pool is tagged with its side (BSL/SSL), price, weight and distance from current price — anchored above the zone at its left edge so labels never overlap the fills and never protrude past the level. Read the map without the mess.
🧹 Clean-Chart Discipline — dashboard off by default. No stat panel competing with price. The liquidity dashboard exists — nearest SSL/BSL, hottest level, pool counts, consumed tally — but it's switched off out of the box. Turn it on only if you want it.
🎨 Fully Themed & Configurable. Neutral-gray candles that let the coloured zones pop, custom OB/FVG/liquidity colours, panel size and spacing, right-offset from live price, 2× timeframe labels, per-panel OB/FVG toggles, adjustable swing length, displacement, mitigation type (Touch / Full Fill / 50% Fill), gap filter, zone-height method, strength floor, pivot lengths, heat contrast, pool extension and cap.
🔒 Honest, Non-Repainting Core. Panel history is built from confirmed higher-timeframe bars only; the live forming candle refreshes as it builds — inherent to showing a real-time HTF candle, not a defect — while every closed bar is fixed. Liquidity pools consume on confirmed interaction and don't un-consume to flatter the chart. The 0–10 strength score is a descriptive ranking framework for directing attention, not a backtested edge.
🔔 Native Alerts — new sell-side pool and new buy-side pool formation.
🎯 Why this is different. MTF tools make you tab between charts and reconcile the structure in your head. Profile tools show you liquidity and leave the map disconnected from your entries. Strong MTF Liquidity Matrix holds all four higher timeframes in view at once, marks the order blocks and fair value gaps on every one of them, grades each so you know which to trust, and lays the liquidity price is actually hunting directly on your candles — so you read where structure sits, how strong it is, and where price is being pulled, at a glance.
🚀 Apply to Gold (XAUUSD), Silver, Forex, Crypto, Indices and Futures on any timeframe (liquidity heat requires a volume-bearing symbol).
💡 Cleanest setup: give the four panels room — nudge Right Offset and the panels sit clear of live price to the right, while liquidity zones map onto the candles on the left.
🎯 How To Trade It — Two Approaches
Everything hinges on one read the Matrix gives you at a glance: is higher-timeframe structure lining up, and is price being pulled toward unfilled liquidity?
◾ 1) Trade into confluence toward liquidity (the core thesis)
Use when a high-strength zone on a higher panel lines up with a resting liquidity pool in the same direction.
▪️ Scan the four panels for a strong OB or FVG (7+) on H1/H2/H4 sitting where price is heading.
▪️ Confirm a naked liquidity pool (BSL below / SSL above) as the magnet — the untested pools are where price is drawn.
▪️ Entry: as price reaches the higher-timeframe zone, in the direction of the unfilled liquidity beyond it.
▪️ Stop: beyond the zone; if price closes through and accepts, the level failed — stand aside.
▪️ Target: the nearest resting pool in your direction; the opposite-side pool if the move extends.
⚖️ The cleanest version: H1 and H2 panels both print a strong bull OB at the same area, a fat buy-side pool sits just below unconsumed, and the M30 panel shows price rotating down into it. Structure, strength and liquidity all point the same way. That confluence is the exact setup this tool was built to frame.
◾ 2) Stand down — the map says wait
The Matrix also tells you when there's nothing to do.
▪️ Panels disagree — a bull OB on H1 against a bear FVG on H4 is conflict, not confluence. Wait for alignment.
▪️ Liquidity already consumed on your side — the magnet's gone; the pull is spent.
▪️ No strong zone in range — low scores everywhere means no level worth risking on. Let it develop.
Rule of thumb: ⭐ Aligned high-strength zones + an unfilled pool in the same direction → trade into the confluence toward the liquidity. ⭐ Conflicting panels, consumed pools, or weak scores → stand down until the map agrees.
⚠️ IMPORTANT NOTICE: Strong MTF Liquidity Matrix is a structure-and-liquidity mapping tool. Order blocks, fair value gaps and liquidity pools are drawn from swing-pivot and gap logic — a model of institutional behaviour, not exchange order-book data. Liquidity weight is inferred from volume × range and requires a volume-bearing symbol. The 0–10 strength score is a descriptive ranking framework for directing attention — NOT a backtested signal and NOT a standalone trade trigger. Trading into higher-timeframe structure still carries real risk of failed levels and stop-outs. Always combine it with your own strategy, price-action analysis and risk management. Past behaviour does not guarantee future results. Indicator

ICT NDOG & NWOG [D4A]NDWOG - New Day / Week Opening Gap
This script is based on popular open source script made by fadi .
How is this script different from the original:
- has additional option (set as default) to add one day to NDOG and NWOG, so the displayed gap date reflects the day when the gap is first utilized during London and NY sessions, as recommended numerous times by ICT himself (main reason for this fork)
- gap quadrants can be drawn if enabled and ATR based gap size is large enough (user customizable)
- more gap customization options have been added to help distinguish between the current and previous (historical) gaps
- gap date label format can be set according to your preference
- default settings are based on dark Trading View theme
- a few small bugs have been fixed
Overview
The script is designed for ICT traders operating mostly in the CME futures markets (NQ, MNQ, ES, and MES), but NWOG discovery works also in forex markets. The script automatically plots the opening gaps that serve as primary daily and weekly draw-on-liquidity levels.
- NDOG (New Day Opening Gap): Formed daily during the CME's 1-hour session break (5:00 PM to 6:00 PM ET), the NDOG captures the price difference between the 5:00 PM ET closing candle and the 6:00 PM ET opening candle. A new gap is created every weekday evening at 6:00 PM ET.
- NWOG (New Week Opening Gap): Created over the weekend between Friday’s 5:00 PM ET close and Sunday’s 6:00 PM ET market re-open. NWOGs are typically much wider than daily gaps, serving as macro liquidity targets for the entire trading week.
Every identified gap is displayed as a shaded range spanning its high and low extremes, bounded by horizontal levels at the top and bottom. It features middle line, known as C.E. (Consequent Encroachment) marking the 50% midpoint, optional quadrants and gap date label.
Within ICT methodology, opening gaps act as footprint markers for institutional orders. "Smart money" routinely targets these price imbalances; analyzing how price reacts—whether it bounces off the boundary, respects the midpoint, or closes the gap entirely helps traders gauge institutional sentiment.
Weekly & Daily Directional Bias
NWOG (Weekly Framework): Dictates the macro bias. Trading above the NWOG signals a bullish tone, whereas trading below implies a bearish outlook. The C.E. of the NWOG is a critical line as its clean rejection indicates trend continuation, while a strong break through the CE points to a full gap fill and signals potential trend reversal.
NDOG (Intraday Framework): Functions as the daily counterpart. Yesterday's NDOG highlights overnight institutional order flow shifts. Furthermore, multiple unfilled NDOGs from prior sessions act as magnetic liquidity pools during the London and NY Kill Zones.
SETTINGS
- NWOG - New Week Opening Gap - enable the display of NWOGs
- Current NWOG Fill/Border/C.E. - customize the current (the newest) weekly gap
- Previous NWOG Fill/Border/C.E. - customize all the previous weekly gaps (historical)
- Max NWOGs - select how many previous weekly gaps should be displayed on the chart
- Label - enable and customize gap date label
- NDOG - New Day Opening Gap - enable the display of NDOGs
- Hide Above - hide the daily gaps above specific timeframe
- Current NDOG Fill/Border/C.E. - customize the current (the newest) daily gap
- Previous NDOG Fill/Border/C.E. - customize all the previous daily gaps (historical)
- Max NDOGs - select how many previous daily gaps should be displayed on the chart
- Label - enable and customize gap date label
- Draw Quadrants (NDOG & NWOG) - draw quadrants in both daily and weekly gaps
- Threshold - the quadrants are drawn if they are bigger than this ATR threshold
- Only if Price Within the Gap - draw quadrants only if the price is currently inside of the gap. This option serves the purpose of minimizing chart clutter
- Add 1 day offset to date label - most similar scripts use by default the date of gap creation, however this script allows to increase the date by 1 day, thus adhering to ICT recommendations, so the displayed gap date is reflecting the first London and NY sessions after the gap has been created
- Date Format - customize the display of date
- Add left padding - it adds padding to the label, moving it more to the right
- Box Right 'Time Extension' - how far right should the NDOG/NWOG box be extended (time-based)
Note:
NDOG and NWOG created on the same weekend will overlap thus creating one box on the chart. You can still spot them by looking at their date labels: weekly gap labels are bigger and daily labels are smaller (based on script default settings).
The script should work on all timeframes, up to 1D.
-----------------
Disclaimer
The content provided in this script is for educational and informational purposes only. It does not constitute financial advice, investment recommendations, or a solicitation to buy or sell any financial instruments. I will not accept liability for any loss or damage, including without limitation any loss of profit, which may arise directly or indirectly from the use of or reliance on such information.
All investments involve risk, and the past performance of a security, industry, sector, market, financial product, trading strategy, backtest, or individual's trading does not guarantee future results or returns. Investors are fully responsible for any investment decisions they make. Such decisions should be based solely on an evaluation of their financial circumstances, investment objectives, risk tolerance, and liquidity needs. Indicator

ICT Sniper BY DAVIDThe ICT Sniper (Clean Version) is a systematic Pine Script v6 indicator designed for traders using Smart Money Concepts (SMC) and Price Action models. Based on mechanical entry models, this tool identifies institutional market manipulations and precise entry zones by combining Liquidity Sweeps with Fair Value Gaps (FVG).
Instead of cluttering the chart with endless technical indicators, this script operates on market structure and liquidity dynamics. It isolates low-risk, high-probability execution points by waiting for institutional smart money to sweep liquidity before confirming an entry via market imbalance.
Core Strategy and Logical Framework
The indicator executes a mechanical three-phase validation sequence:
1. Liquidity Sweep Detection
Market makers frequently run price beyond key swing points to activate retail stop-loss orders and breakout entries. This script continuously monitors market structure using pivot points:
Bullish Sweep: Price breaks below a recent Pivot Low to grab sell-side liquidity, but the bar closes back above that low, confirming a stop run rather than a legitimate breakout.
Bearish Sweep: Price breaks above a recent Pivot High to grab buy-side liquidity, but the bar closes back below that high, confirming a false breakout.
2. Order Block Marking
When a sweep occurs, the script flags the specific candle or range where the liquidity sweep originated as an active Order Block zone, anticipating that institutional orders remain resting within this area.
3. Fair Value Gap (FVG) Refinement and Signal Trigger
A liquidity sweep alone is insufficient for an entry. The strategy requires displacement—rapid price movement leaving behind an imbalance (FVG).
The indicator tracks the bars following a sweep up to a user-defined lookback window (default: 10 bars).
If a three-candle imbalance forms within this lookback window:
Bullish FVG (Low of candle 1 > High of candle 3): Triggers a BUY Entry signal.
Bearish FVG (High of candle 1 < Low of candle 3): Triggers a SELL Entry signal.
Detailed Input Parameters
Market Structure
Pivot Lookback Length (Default: 5): Determines the sensitivity of swing highs and lows. A smaller number identifies short-term internal liquidity, while a larger number focuses on major swing points.
Strategy Rules
Max Bars After Sweep to Find FVG (Default: 10): Specifies the maximum duration allowed between the liquidity sweep and the displacement/FVG formation. If an FVG forms after this limit, the signal is discarded to ensure only fresh displacement is traded.
Clean Visuals
Show Minor Sweep Shapes (Default: Off): Displays minor directional indicators on every sweep candle. Kept disabled by default to maintain chart clarity.
Show Active Order Blocks (Default: On): Draws shaded boxes around active Order Blocks resulting from liquidity sweeps.
Show FVG Highlights (Default: On): Plots distinct colored boxes directly over the Fair Value Gaps that triggered entry signals.
Max Boxes to Keep on Chart (Default: 2): Automatically deletes older historical boxes to prevent memory lag and visual clutter.
Execution and Risk Management Guidelines
1. Signal Confirmation
Wait for the current bar to close when a BUY or SELL signal appears. Do not execute mid-bar, as FVGs require candle completion to be valid.
2. Stop-Loss Placement
BUY Setup: Position the Stop-Loss a few ticks below the Liquidity Sweep Low or beneath the bottom boundary of the FVG box.
SELL Setup: Position the Stop-Loss a few ticks above the Liquidity Sweep High or above the top boundary of the FVG box.
3. Take-Profit Targets
Fixed Risk-to-Reward: Maintain a standard 1:2 Risk-to-Reward ratio (2R) for consistent expectancy.
Structural Targets: Target the opposing Swing High for long positions or Swing Low for short positions.
Best Practices and Context
While this indicator automates pattern recognition, trade performance improves significantly when aligning signals with higher-timeframe context:
Trade in the direction of the higher-timeframe trend.
Focus executions during major market sessions (London and New York sessions).
Recommended Timeframes: 1-minute to 15-minute charts for intraday execution; 1-hour to 4-hour charts for swing trading.
Recommended Assets: Forex major pairs, equity indices (NAS100, US30), commodities (Gold), and major cryptocurrencies. Indicator

Zero Noise KillzonesThe Killzones, outlined. Nothing else. The ICT killzones drawn cleanly, with each one's high and low carried forward as levels.
What it does
- Outlines the killzones: Asia (20:00–00:00), London (02:00–05:00), New York AM (09:30–11:00), New York Lunch (12:00–13:00, off by default), and New York PM (13:30–16:00) — all pinned to New York time, so daylight-saving changes are handled automatically on any chart, in any timezone.
- A separate forex set — Asia, London Open, New York Open (07:00–10:00), London Close (10:00–12:00) — off by default, so forex traders have the complete set in one place. NY AM and NY Open overlap by design: different windows that share 30 minutes.
- When a killzone closes, its high and low carry forward as levels. A level stays lit and keeps extending until price trades through it — then it greys out and stops. A sweep counts on the wick: any trade through the level retires it, even if the candle closes back inside. A wick through a level is information — that's the definition, on purpose.
- Days Kept bounds how long anything lives on the chart. Nothing accumulates forever.
- Custom windows: up to seven of your own sessions, any HHMM–HHMM window (midnight wraps handled), in any timezone.
What it deliberately doesn't do
- No signals, no alerts, no arrows — a deliberate omission in the free tools, not an oversight. A killzone high is context, not a trade call. The trade is yours.
Settings
- Killzones: five futures windows plus the four-window forex set, each an independent toggle
- Extend Highs & Lows: Until Swept (levels carry forward) or Session End (outlines only)
- Custom: timezone + up to seven custom windows
- Theme: Auto / Dark / Light — change any swatch and your color wins on every theme
- Line width, fill, tags, Days Kept (1–5), watermark — all optional
Futures, stocks, and FX, on any intraday chart up to 1h — above 5m, windows are rebuilt from 1-minute data for exact alignment.
For informational and educational purposes only — not financial advice. Trading involves substantial risk of loss; past performance does not guarantee future results. Indicator

ICT Macros & Killzones & Clock [D4A]ICT Macros
According to ICT (Inner Circle Trader) and his SMC framework, a macro is a small program or set of instructions that runs within an algorithm, which influences price movements in the market. These macros operate at specific times and can be related to price movements from one level to another or certain market behaviours during specific time intervals. They help traders anticipate market movements and potential setups during specific times of the day.
To trade these effectively, it is important to understand the time of day when certain macros run, and understand the concept of market liquidity. The theory behind this - is that the market will either seek buy side or sell side liquidity, or seek to rebalance price at a point of interest in between the open and close of the macro. Traders who follow this theory can use that information to anticipate how price might behave.
This script allows traders to visualize the time when a macro will likely occur in the market. As per ICT, most macros run at every hour from x:50 till x:10. The script draws boxes and lines representing a period of time when a macro runs. Additionally, a label is placed next to the line indicating Macro Open (MO). The script includes alerts that can notify traders when a macro starts.
The following Macros are displayed by the script:
London KZ
02:30 - 03:00 (London Legacy)
04:00 - 04:30 (London Legacy)
01:50 - 02:10
02:50 - 03:10
03:50 - 04:10
04:50 - 05:10
05:50 - 06:10
NY AM KZ
06:50 - 07:10
07:50 - 08:10
08:50 - 09:10
09:50 - 10:10
10:50 - 11:10
11:50 - 12:10
12:50 - 13:10
NY PM KZ
13:50 - 14:10
14:50 - 15:10
15:15 - 15:45
15:50 - 16:10
KZ - Killzones
Apart from displaying the macros, the script visualizes another ICT concept - Killzones. The killzone is a time period when there is an increased market participation from major institutions and big traders who are able to influence price movement. According to ICT this is a good time to participate in the market, as the price will move much quicker than outside of killzone times, allowing for more trading opportunities. The macros that run during killzone may have more weight and importance to macros running outside of a killzone.
How to spot a killzone
The script draws small dots either at the top or the bottom of the screen during the time the killzone is in play. There are three major killzones, pertaining to futures market which have been pre-defined in the script, but each user can modify the times to reflect their own understanding and specific instrument they are trading. The script can display small circle next to the clock which symbolizes that we are in a killzone period.
The following killzones are pre-defined:
London KZ 02:00 - 5:00
NY AM KZ 07:00 - 11:30
NY PM KZ 13:30 - 16:00
The Clock
When the market is open the script displays a digital clock which can also show when a specific macro is running by displaying macro time. The clock is also able to display when we are in a period of active killzone, which is symbolized by small circle next to the clock.
The script is intended to run on 1m timeframe, but it can also run up to 15m and on sub 1m charts. On higher timeframes it's not practical to display macro information.
SETTINGS:
- KZ Killzones - enable display of killzones
- Timezone - set by default to New York timezone
- Lookback - how many past bars are used for computation
- London KZ, NY AM KZ, NY PM KZ - here the user can define exact times for a killzone
- KZ Markers - the script displays small dot (marker) to represent killzone period
- Location - the location of killzone markers on the charts
- Hide Above - hide KZ markers above certain timeframe
- Macros - enable the display of elements representing a macro on the charts
- Hide Above - hide all macro drawings above certain timeframe
- Fill - the background of the box representing a macro
- Highlight - the box representing a macro can be highlighted
- Label - displays macro header containing either MACRO or the time the macro runs
- Hour - displays the time when a macro runs (Label must be enabled for this to work)
- MO - Macro Open line
- Hide Above - hides macro box and MO line above certain timeframe
- Macro pre-defined times - here the user can enable or disable specific macros
- Box/Fill/Border/Highlight - define macro box background, border and highlight transparency
- Label - defines macro header colors
- MO - Macro Open line - defines macro open line style and color
- Show Clock - enables the display of a digital clock
- Background - the background of the clock
- Position - the location of the Clock in the chart
- Time - enable 24h or 12h clock and define the size of the clock when outside of macro and when in macro period
- Macro - define colors of displayed macro time information in the Clock
- Colorize - changes the background of displayed macro information
- KZ Marker in Clock - displays circle next to the clock when we are in active killzone
- Enable Alert at Macro Start - enables elerts when specific macro starts. You still need to add alert for the script in PulseWire to make it work.
NOTE
The script has been preconfigured for dark background in PulseWire. You may need to tune up the colors to satisfy your own PulseWire setup.
-----------------
Disclaimer
The content provided in this script is for educational and informational purposes only. It does not constitute financial advice, investment recommendations, or a solicitation to buy or sell any financial instruments. I will not accept liability for any loss or damage, including without limitation any loss of profit, which may arise directly or indirectly from the use of or reliance on such information.
All investments involve risk, and the past performance of a security, industry, sector, market, financial product, trading strategy, backtest, or individual's trading does not guarantee future results or returns. Investors are fully responsible for any investment decisions they make. Such decisions should be based solely on an evaluation of their financial circumstances, investment objectives, risk tolerance, and liquidity needs. Indicator

Sphinx Unicorn - FVG Breaker Nesting ModelDescription:
Sphinx Unicorn identifies a specific price structure from ICT-influenced methodology: a swing point that forms inside an unfilled fair value gap (FVG), which price then reclaims through displacement. This structure is commonly called a "unicorn" — a breaker nested within an FVG. The script scans for these continuously, tracks each candidate through a defined lifecycle, and confirms only those that complete the full sequence.
What makes this different from a generic FVG or order-block indicator
Most FVG scripts simply draw every gap. Most breaker scripts simply mark broken structure. This one requires the two to coincide and survives a multi-stage confirmation before it marks anything as complete:
The nesting test — a swing must sit inside an FVG that is still unfilled at the moment the swing forms. A gap price has already traded through is rejected, which removes the majority of low-quality candidates on intraday timeframes.
The Balanced Price Range (BPR) gate — activation requires the breaking leg to leave its own fair value gap that overlaps the nesting gap. A slow drift through the level does not qualify; only a genuine displacement that creates a second, opposing inefficiency does.
A self-scaling displacement filter — the gap left by the breaking leg must be at least a configurable fraction (default 0.75) of the size of the gap it inverts. This means a large level demands a proportionally decisive break to confirm, while a small level needs less. The threshold scales with the structure itself rather than using a fixed point or tick value, so it adapts across instruments and volatility regimes without re-tuning.
How it calculates
FVGs are detected using the standard three-bar definition (a gap between the first and third bar's wicks). A pivot is qualified as "nested" when its price falls strictly within an unfilled gap's range inside the search window. Overlapping gaps in the same direction are collapsed into a single zone drawn at the largest gap, so clustered inefficiencies read as one level rather than a stack of boxes. Displacement is confirmed on bar close beyond both the swing and the gap's far edge, subject to the BPR and ratio conditions above.
The four zone states
Level (grey, thin): a nested swing that has been superseded by a newer one. Price may still react here, but it is no longer the watched candidate and cannot activate.
Armed (grey, dashed): the current front-runner — the zone actively being evaluated for displacement.
Active (green or red): a confirmed unicorn. The displacement completed with a valid BPR.
Spent (purple): an Active zone that price has since mitigated. It is retained as a reference level, since a proven structure often sees price return to it.
How to use it
This tool marks where a precise entry structure exists. It is not a standalone system and is best used as one input within a layered approach. In practice it is strongest when the confirmed zone aligns with an independently identified key level — for example a higher-timeframe draw on liquidity, a volume or dealer-positioning level, or a session reference — and when it is paired with SMT (Smart Money Technique) divergence read across correlated instruments on the manipulation leg that forms the breaker. A confirmed unicorn sitting at a defended level, with SMT divergence present on that leg, represents the confluence this structure is designed to isolate. A confirmed unicorn with no surrounding context should be treated with more caution.
Alerts are provided for both the arming and activation of a zone, in each direction.
Inputs
Swing strength, FVG search radius, strict-nesting toggle, displacement-close requirement, BPR requirement and lookback, minimum displacement gap size, and the self-scaling displacement ratio. Display controls cover zone colors per state, the on-chart zone limit, and the mitigation rule (touch versus close-through). A diagnostic panel shows a live count of zones in each state.
Limitations and behavior traders should know
The nesting swing is detected using pivots, which require bars on both sides to confirm. A zone therefore arms only after the pivot's right-hand bars have formed; it does not arm on the exact pivot bar in real time.
On strongly trending sessions the model produces few or no setups, because reversals into unfilled opposing gaps are rare in a one-directional market. Empty output in a trend is expected behavior, not a failure.
SMT divergence, referenced above as a recommended confluence, is read by the trader from correlated instruments and is not drawn by this script.
This indicator marks structure. It does not predict direction, guarantee outcomes, or constitute a trading system on its own.
Open-source. Part of the Sphinx suite by Hermetic Trader. Indicator

ICT Kill Zone Sniper [JOAT]═══ ICT KILL ZONE SNIPER ⚡ ═══
A session-aware sniper tool that paints every candle by its active kill zone, tracks the liquidity pool each session leaves behind, and fires a single clean BUY or SELL only after price sweeps the prior pool and reverses back inside the current kill zone. Built for traders who wait for the liquidity grab, not the breakout.
▎ WHAT IT DOES
It splits the trading day into four classic kill zones — Asia , London , NY-AM and NY-PM — colors the candles inside each one, and records the high and low that every finished session builds. Those prior highs/lows become the liquidity pools hunted in the next window. When the current kill zone reaches into one of those pools and then closes back through it, the tool marks the sweep and projects a full trade: entry, ATR stop, and an R-based target zone.
▎ HOW IT WORKS
• Kill-zone clock — each session window is evaluated in a chosen wall-clock timezone (New York by default). Membership is na-guarded, so it behaves correctly on any intraday timeframe and simply idles on higher timeframes.
• Session state machine — while a kill zone is live, the tool expands that session's running high and low. When the session ends, that high/low is frozen as the prior liquidity pool and drawn as dashed projection lines carried into the next window.
• Sweep + reversal detection — a high sweep needs price to trade above the prior pool high yet close back below it; a low sweep needs a dip below the prior pool low with a close back above. A Min Sweep Depth (× ATR) filter rejects micro-penetrations caused by spread and tick noise.
• Confirmation — sweeps can be evaluated on confirmed bar close only, so signals do not repaint intrabar. At most one long and one short can print per kill-zone occurrence when the one-per-side lock is on.
• Optional HTF bias — a higher-timeframe EMA (requested with lookahead off) can gate direction: longs only above it, shorts only below it.
• Trade projection — on a valid signal the stop is placed beyond the swept extreme plus an ATR buffer, risk is measured from entry to stop, and the target is set at your chosen R multiple. Reward and risk are drawn as tinted zone boxes with entry/SL/TP lines and level labels.
• Optional VWAP — a session-anchored VWAP with a ±σ band is available as extra context.
▎ HOW TO USE IT
• Wait for a BUY or SELL pill to print inside a colored kill zone — it means the prior pool was swept and price reversed back through it.
• The green zone box is the reward leg toward the R-target; the red zone box is the risk leg to the stop. The label pill shows the session and the R multiple.
• Use the dashed prior high/low lines as the liquidity being hunted this session — signals cluster around them.
• Treat the HTF bias as a directional filter and the sweep tags as confirmation that liquidity was actually taken before you commit.
• Combine with your own structure read; the tool marks the setup, you manage the trade.
▎ KEY SETTINGS
• Kill Zones — timezone plus editable session windows for Asia, London, NY-AM and NY-PM.
• Signal Engine — ATR length, confirm-on-close, one-signal-per-side lock, and minimum sweep depth.
• HTF Bias — toggle, higher timeframe, and EMA length.
• Trade Model — stop buffer beyond the sweep, risk/reward target in R, projection length, and how many past signals to keep.
• Visuals — candle tinting and transparency, session boxes, pools, sweep tags, signal labels, SL/TP lines and zone boxes, VWAP bands, and label size.
• Dashboard — show/hide, position, and text size.
▎ DASHBOARD
A cyberpunk chrome-gradient panel reporting the active session , current session high/low , a countdown to the next kill zone , the HTF bias state, the last liquidity grab side, the active signal with bars-since, the last entry , its stop / target , the current ATR , and a running long / short signal tally .
▎ ALERTS
• KZ Sniper Long — prior-pool low sweep plus bullish reversal inside a kill zone.
• KZ Sniper Short — prior-pool high sweep plus bearish reversal inside a kill zone.
▎ NOTES
• Works across assets; the session logic is intended for intraday timeframes and idles on higher ones.
• Confirm-on-close keeps signals non-repainting; the HTF EMA is requested with lookahead off.
• Nearly every visual has a toggle, so you can strip it down to just the candles and signals for a clean chart.
• Any on-chart tallies reflect historical signals only.
For research and education only. This is not financial advice. No indicator can predict the future, and past behavior does not guarantee future results. Always manage your own risk.
Made with passion by JackOfAllTrades ⚡ Indicator

Fair Value Gap Detector | AlphaScript⚡ Fair Value Gap Detector
Most fair value gap indicators mark every three-candle gap on the chart — including the weak, meaningless ones. This tool only marks FVGs created by genuine displacement: a strong-bodied move that signals real institutional participation. Fewer gaps, but the ones that matter.
💡 What a fair value gap is
A fair value gap (FVG) is a three-candle imbalance where price moved so quickly that it left an unfilled gap. In a bullish FVG, the low of the third candle sits above the high of the first — the middle candle's move was so strong it skipped a price range where little trading occurred. Price often returns to "fill" these gaps before continuing, which is why traders watch them as potential entry and reaction zones.
🎯 Why displacement matters
A gap alone is not significant, gaps form constantly, most from weak or random price action. What makes an FVG worth trading is displacement: the middle candle being a large, decisive move that leaves the gap behind. This tool measures the middle candle's body against ATR and only registers the FVG when that body is large enough to qualify as real displacement, and when it moved in the gap's direction. The result is a chart showing institutional-grade gaps instead of noise.
🔍 How detection works
On each confirmed three-candle sequence the tool checks:
A valid gap exists (third candle's low above first candle's high for bullish; third's high below first's low for bearish).
The gap is at least a minimum size, measured as a multiple of ATR, so it is instrument-independent.
The middle candle's body is a genuine displacement — at least a configurable multiple of ATR — and pushed in the gap's direction.
Only sequences passing all three become FVG zones. The displacement requirement can be turned off if you prefer the classic "any gap" behavior.
🟩 Mitigation tracking
Each FVG zone stays active until price fills it. You choose how a fill is counted:
Touch — the gap is mitigated when price reaches its midpoint (the 50% level, where FVGs often react).
Close — the gap is mitigated only when price closes fully through it.
A midline marks the 50% level of every zone.
🎨 Customization
Bullish and bearish fill colors and opacity, midline display, and how far zones extend to the right (a configurable number of bars, so zones don't run infinitely across the chart, or fully infinite if you prefer). Separate toggles for bullish and bearish zones.
📈 How to use it
Treat an active bullish FVG below price as a potential demand zone and an active bearish FVG above price as potential supply. Watch for price returning to a zone — especially the 50% midline — as a possible reaction point, in the direction of the displacement that created it. Because only displacement gaps are shown, each zone represents a move with real momentum behind it rather than a random imbalance. Combine with your own structure and bias — the tool marks the zones, you make the decisions.
🔔 Alerts
Bullish FVG formed, bearish FVG formed, and mitigation alerts when a zone is filled.
⚙️ Settings
ATR length and minimum gap size, displacement requirement and strength, mitigation mode, zone extension length, colors, opacity, midline, and per-direction display toggles.
📌 Notes
FVGs are detected on confirmed bars only and do not repaint intrabar. Detection strictness depends on the gap-size and displacement settings — tune them to your instrument and timeframe. A fair value gap marks an area of potential interest, not a guaranteed reaction — always combine with your own analysis and risk management.
Indicator

MTF FVG + OB Confluence Strategy (4H -> 1H -> 15M) | XAUUSDMTF FVG + OB Confluence Strategy (4H → 1H → 15M) | XAUUSD
This strategy trades price-action confluence across three timeframes (4H, 1H, 15M) using Fair Value Gaps (FVG) and Order Blocks (OB), entering only when a fresh engulfing candle confirms rejection inside an aligned zone.
How it works
Scans the 4H, 1H, and 15M timeframes for Fair Value Gaps and Order Blocks, plotting each as a labeled zone anchored to the candle that formed it.
An Order Block requires a displacement candle at least 1.2x the 15M ATR, confirming real momentum rather than noise.
When a mitigated Order Block is broken, it can optionally flip into a Breaker Block with reversed bias.
A trade is only considered when a 15M zone overlaps a same-direction 1H zone (with an option to require full 4H+1H+15M triple alignment for a stricter filter).
Entry triggers on a bullish/bearish engulfing candle that touches the active confluence zone.
Optional session filter restricts trading to the London and NY AM killzones.
Risk management
Position size is calculated from a fixed risk percentage of equity per trade.
Stop-loss sits just beyond the zone boundary, with an ATR-based buffer.
Take-profit uses three Fibonacci extensions of the initial risk (default 1.618R / 2.618R / 4.236R), scaling out 33/33/34% of the position at each target.
Only one position is open at a time — no pyramiding or averaging into losers.
Notes
Built and tested for XAUUSD; timeframes and risk inputs are adjustable for other symbols.
The on-chart table shows live zone counts, confluence status, and trigger state for transparency.
This is not financial advice — backtested performance does not guarantee future results. Always validate on your own account/broker conditions before trading live. Strategy

ICT Logo 2-1-2 Nested Cycles - ExtendedICT Logo 2–1–2 Fractal AMD Cycles
This indicator is an experimental time-cycle framework inspired by ICT’s logo sequence and the fractal nature of price delivery.
The core idea is that every selected time range can be divided into three proportional phases using the sequence:
2 – 1 – 2
Because the total equals five units, each parent cycle is divided at:
0.40
0.60
1.00
This creates three consecutive time phases (Power of 3):
First phase: 40% of the cycle
Middle phase: 20% of the cycle
Final phase: 40% of the cycle
These phases can be interpreted through the familiar AMD framework:
Accumulation
Manipulation
Distribution
The indicator does not assume that every first phase must accumulate, every middle phase must manipulate, or every final phase must distribute. Instead, it provides a consistent temporal structure in which those behaviors can be studied.
Fractal AMD micro-cycles
The main feature of the indicator is recursive subdivision.
Each of the three primary AMD phases is divided again using the same 2–1–2 ratio. This creates smaller AMD cycles inside the larger one.
At each additional depth, the number of cycles increases:
Depth 1: 3 primary cycles
Depth 2: 9 micro-cycles
Depth 3: 27 smaller cycles
Depth 4: 81 micro-cycles
This makes it possible to observe how short-term price delivery develops inside a larger daily, weekly, monthly, four-hour, hourly, or intraday cycle.
For example, a daily parent cycle contains three major phases. Each major phase can then contain its own accumulation, manipulation, and distribution sequence. Those smaller cycles may themselves contain further micro-cycles.
The result is a nested temporal structure:
Parent AMD cycle
├── First major phase
│ ├── Micro accumulation
│ ├── Micro manipulation
│ └── Micro distribution
├── Middle major phase
│ ├── Micro accumulation
│ ├── Micro manipulation
│ └── Micro distribution
└── Final major phase
├── Micro accumulation
├── Micro manipulation
└── Micro distribution
Range boxes
Every cycle can be surrounded by a box that records the high and low produced during that specific time window.
The larger boxes show the range of the parent or major AMD phase, while the smaller nested boxes show the range created inside each micro-cycle.
The boxes update as new candles print and remain anchored to the chart’s time and price coordinates.
This helps visualize:
Range expansion and contraction
Liquidity forming above or below previous cycle ranges
Manipulation outside an earlier micro-cycle
Distribution away from a completed range
Nested premium and discount relationships
Whether a smaller cycle is expanding with or against the larger cycle
The box colors represent the repeating three-part sequence, not guaranteed bullish or bearish direction.
Supported parent cycles
The indicator can apply the same 2–1–2 structure across multiple time ranges:
Monthly
Weekly
Daily
4 Hour
1 Hour
15 Minute
Custom duration
The default daily range is: 00:00–16:15 New York time
The default weekly range is: Sunday futures open–Friday 16:15 New York time
Weekly, daily, and repeating-cycle anchors are adjustable, allowing the model to be tested on different market sessions and instruments.
Timing guides
Vertical timing lines show the boundaries of each cycle and micro-cycle.
Different colors and line styles distinguish the fractal depth. Major boundaries represent the larger cycle divisions, while thinner or dotted lines represent smaller nested timing intervals.
These lines are intended as areas of interest rather than automatic reversal signals (Or are they? 💡).
A timing boundary becomes more meaningful when it aligns with additional context such as:
External or internal liquidity
Previous highs or lows
Fair value gaps
Order blocks
NDOGs/NWOGs
SMT divergence
CISD
Displacement
Premium or discount positioning
Midnight Open
The indicator also plots the New York Midnight Open using the actual 00:00 candle opening price.
This level can be used as a daily reference for:
Intraday premium and discount
Bullish or bearish delivery relative to midnight
Liquidity runs around the opening price
Alignment between the parent AMD cycle and its micro-cycles
Suggested interpretation
The indicator is best used from the outside inward.
First, identify the current parent cycle and determine which of its three major phases is active. Then examine the smaller cycle currently developing inside that phase.
For example:
The daily cycle may be in its final 2-phase,
while the active hourly micro-cycle is still in manipulation.
This allows the trader to distinguish between the larger delivery structure and the immediate short-term behavior.
A lower-timeframe reversal may only represent a micro-cycle transition, while a reversal at the boundary of both a micro-cycle and a major parent phase may carry greater significance.
Important note
This indicator is a research and visualization tool. It does not claim that time alone predicts price, nor does it generate automatic trade signals.
The 2–1–2 sequence is used as a consistent fractal framework for studying AMD-style delivery across multiple time horizons. The model should be combined with price action, liquidity, market structure, and independent testing.
Past reactions around cycle boundaries do not guarantee future reversals or continuation.
Happy to discuss further in the comments. Let me know your thoughts 👇: Indicator

ICT Sessions & Killzones [JOAT]ICT Sessions and Killzones
Maps the trading day into sessions and killzones, then shows where each session's liquidity rests and when the next session raids it.
What it is
Intraday price is organised by time: different sessions have different behaviour, and each one leaves liquidity that the next session hunts. This indicator frames when the market is active and where that liquidity sits, so the raids become obvious in advance. It is an original session-mapping tool built around the widely-taught concept of session killzones and inter-session liquidity.
How it works
• Session boxes — Asia, London, New York AM and New York PM are each boxed from their own high to their own low across their clock window. The box is that session's realised range, and its edges are the liquidity the following sessions tend to seek.
• Liquidity lines — every completed session leaves its high and low as thin levels extended to the right. Resting buy-side liquidity sits at the highs, sell-side at the lows, each labelled.
• Sweeps — when a later session trades through a prior session's high or low, that raid is tagged, marking where stops were likely taken.
• Classic reference levels — the previous day's high and low and the midnight open are drawn as the anchor points this style of analysis leans on.
• Bias read — a simple, transparent read from the midnight open and the most recent killzone sweep-and-reclaim prints an understated directional tag. This tool is about mapping context and timing; it deliberately shows direction rather than full trade management.
The dashboard
An adjustable session-clock panel shows which session is currently active, the countdown context of the day, the most recent liquidity event, the current bias, and the reference levels in play, so the state of the day is readable at a glance.
How to use it
• Set the session windows and timezone to your market.
• Watch for a session to sweep the prior session's high or low and then reclaim — that is the timing this map is built to highlight.
• Use it as a context and timing layer beneath your own entry method, or alongside a structure or entry tool.
Settings
Session windows and timezone, which sessions and reference levels to display, sweep marking, bias options, plus full visual and dashboard controls.
Originality and usefulness
The contribution is a single, coherent map of session ranges, inter-session liquidity, sweeps and classic reference levels, with a transparent bias read — assembled so a trader can see the day's liquidity structure and timing without cluttering the chart. Everything evaluates on confirmed bars and does not repaint.
Notes and limitations
• Session times depend on the timezone and the instrument's trading hours; set them correctly for your market.
• The bias read is intentionally simple context, not a standalone trade signal.
• This tool maps liquidity and timing; it does not place stops or targets for you.
• Educational and analytical tool, not financial advice.
— made with passion by officialjackofalltrades
Indicator

LTF FVGs (Lower Timeframe Fair Value Gaps) [D4A]LTF FVGs - (Lower Timeframe FVGs)
This script draws Fair Value Gaps on the chart that occured on lower timeframe, eg. 1m FVG is drawn on 5 min chart. The script uses request.security_lower_tf to get the lower timeframe data for this. There are several distinct features that make this script unique:
- the script automatically pulls FVGs from the most relevant lower timeframe (this can be manually changed at any time)
- the size of smallest FVGs can be customized based on ATR threshold
- Volume Imbalance can be included as part of FVG
This script can be useful for traders who want to be informed about any gaps created on lower timeframe without switching to lower timeframe chart.
What is FVG?
FVG or Fair Value Gap is a three-candle formation where the middle candle moves so aggressively creating displacement that it leaves a gap between the wick of the prior candle and the wick of the following candle. Price often returns to fill these gaps before continuing — making them useful as targets, entry zones, or invalidation levels.
A bullish forms when the low of the current candle is above the high of two candles ago, with a bullish middle candle. A bearish FVG is the inverse.
FVGs often occur due to sudden market movements triggered by news events, changes in market sentiment, or large orders that move the price significantly. The market tend to return to these unfilled spaces, providing potential opportunities for traders. These areas may serve as either support (bullish FVG) or resistance (bearish FVG). They may also be completely filled by the price and then act as Inversion FVGs but this is outside of scope of this script.
SETTINGS
- Force Manual TF - the user can manually select lower timeframe from which the script can pull FVGs. When this option is not active, the script is pre-programmed to select lower timeframe automatically for FVG discovery which is at least one level below the current timeframe, eg. 15S when on 1m, 1m when on 5m and so on.
- FVG Fill and border transparency - customize the look of FVG boxes
- FVG threshold - set the threshold to eliminate very small gaps
- Volume Imbalance included - include Volume Imbalance as part of FVG. Enabled by default.
- Show LTF Label & Transparency - enable the label which shows from which timeframe is the FVG from
- Extend to Current Bar or by X-bars - customize how the FVG boxes are presented on the chart
- Max FVGs Displayed - how many FVGs should be kept in memory by default
When FVG is fully filled by price, the script removes it from the memory.
Other relevant scripts that are complementary to this script: Candle Displacement
-----------------
Disclaimer
The content provided in this script is for educational and informational purposes only. It does not constitute financial advice, investment recommendations, or a solicitation to buy or sell any financial instruments. I will not accept liability for any loss or damage, including without limitation any loss of profit, which may arise directly or indirectly from the use of or reliance on such information.
All investments involve risk, and the past performance of a security, industry, sector, market, financial product, trading strategy, backtest, or individual's trading does not guarantee future results or returns. Investors are fully responsible for any investment decisions they make. Such decisions should be based solely on an evaluation of their financial circumstances, investment objectives, risk tolerance, and liquidity needs. Indicator

Indicator

Indicator

ICT Liquidity Sweep & Structure [JOAT]ICT Liquidity Sweep and Structure
A smart-money workflow that maps resting liquidity, detects stop-hunt sweeps, and reads market structure shifts on one clean overlay.
What it is
This tool organises several well-known smart-money / ICT concepts into one coherent, non-repainting engine and — importantly — explains how the pieces reinforce each other rather than just stacking them. The premise: price is drawn to pools of resting orders (old highs and lows), often sweeps them to trigger stops, and then reveals its true intent through a structure break. The indicator makes each of those steps visible and gates its signals on their confluence.
How it works
• Liquidity levels — confirmed swing highs and lows (pivots) are drawn as buy-side liquidity (above old highs) and sell-side liquidity (below old lows) lines, each labelled with its price. These mark where stops are likely resting.
• Liquidity sweeps — a sweep is detected when price trades through one of these levels and then closes back on the original side, i.e. the level was raided but not accepted. This is the classic stop-hunt footprint and is the setup trigger.
• Market structure (BOS / CHoCH) — the engine tracks the live sequence of swings. A Break of Structure confirms trend continuation; a Change of Character is the first counter-break that flips the internal bias. Both are labelled on confirmed closes.
• Fair value gaps — three-bar imbalances left by displacement are drawn as zones and used as entry confluence, since price often rebalances them.
• Confluence gate — a Buy requires a bullish sequence (a sweep of sell-side liquidity followed by a bullish structure shift, optionally aligned with a fair-value gap); a Sell is the mirror. Buy and Sell are made mutually exclusive so both never print on the same bar, and a minimum-spacing control prevents clustering.
Trade levels
Each signal renders a red risk box from entry to stop and a green reward box from entry to the third target, with inner target dividers and right-edge labels for entry, stop and each take-profit at your R multiples. The stop is anchored to the structure that produced the signal, not to a fixed distance.
The dashboard
An adjustable panel summarises the current structural bias, the most recent liquidity event, the nearest untapped level, a conviction estimate, the active signal, and a live first-target-before-stop tally computed only on closed bars.
How to use it
• Suitable for any asset and timeframe; the concepts are scale-independent, though very low timeframes produce more noise.
• Use the liquidity lines to anticipate where price may be drawn next, and wait for a sweep-plus-structure confluence rather than acting on a raw level touch.
• Combine with a higher-timeframe bias for directional filtering.
Settings
Pivot strength, liquidity extension, sweep sensitivity, fair-value-gap minimum size, structure options, risk multiple and target R multiples, plus full colour and dashboard controls.
Originality and usefulness
Rather than plotting isolated ICT drawings, this engine chains them into a single logical sequence — liquidity, sweep, structure shift, imbalance — and only signals when that sequence agrees. The description of why those components belong together, and the confirmed-bar evaluation that keeps them honest, is what distinguishes it from a generic structure plotter.
Notes and limitations
• Structure and sweeps are defined algorithmically; discretionary traders may mark them slightly differently.
• Signals confirm on bar close, which trades a small amount of immediacy for stability and no repainting.
• The on-chart tally reflects only past bars on the current chart and is not a prediction.
• Educational and analytical tool, not financial advice.
— made with passion by officialjackofalltrades
Indicator
