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

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

SATTAM | CRT+TBSOVERVIEW
A rule-based implementation of Candle Range Theory (CRT) combined with Turtle Body Soup (TBS). It reads the setup on a higher timeframe, requires a key level for context, waits for a liquidity sweep, then marks the entry and manages the trade on your current chart.
HOW IT WORKS
Seven stages are evaluated in order. A failure at any stage cancels everything downstream.
1. Higher timeframe selection — automatic pairing (a 5m chart reads 4H, a 1H chart reads Daily), or set manually
2. Key level detection — Old High, Old Low, Order Block, Fair Value Gap
3. CRT detection — accumulation, manipulation, distribution
4. Time filter — configurable blocked hours
5. TBS confirmation — a body sweep of prior liquidity plus a reversal close
6. Entry model — Model #1, CISD, or MSS+FVG
7. Trade management — stop, three targets, breakeven
THE CRT SEQUENCE
Accumulation — one candle defines the range; its high becomes CRH, its low CRL.
Manipulation — a later candle wicks through the boundary but closes back inside. Direction and target are set here.
Distribution — price travels toward the opposite side.
The decisive rule: the break is made by the wick, with the close returning inside. A close beyond the range is a genuine breakout, not a trap — the setup is invalidated and labelled a reverse CRT.
Four CRT types are classified automatically. The fourth, where price is swept twice, is flagged as a caution and draws its T.S level.
The manipulation is drawn as a zone spanning the candles that carried price past the level and back, so the depth of the sweep is visible rather than implied.
KEY LEVELS
A CRT in isolation is treated as insufficient — the methodology names a missing key level as a primary failure cause. Confluence is required by default and can be disabled.
Display toggles for each zone type control drawing only. Hidden zones are still detected, still satisfy confluence, and still count toward the zone cap. Hiding a zone type never changes which signals fire.
TURTLE BODY SOUP
Two conditions together: a candle closes beyond a prior swing (the sweep is made by the body, not the wick), and a subsequent candle closes back beyond the last opposing candle.
ENTRY MODELS
Model #1 — a full candle closes beyond the previous candle; entry at that close.
CISD — the opening level of the last directional leg is broken; entry on the break.
MSS + FVG — structure breaks with displacement leaving a gap; entry from the gap on the retrace.
All three can run together, or one can be selected. Each fires once per setup.
TRADE MANAGEMENT
Stop sits beyond the manipulation and sweep extremes with an ATR buffer.
Targets follow the range rather than fixed risk multiples:
TP1 — the range midpoint, the 50% level the methodology marks in its diagrams
TP2 — the opposite extreme, the target the methodology names; risk-to-reward is measured here
TP3 — an extension beyond the range, by a configurable multiple
A target that does not sit beyond the entry is dropped rather than drawn behind price. Once TP1 trades through, the stop moves to entry. The stop is checked before the targets on each bar, so a bar touching both is reported as the loss.
ADDITIONAL MODULES
Accumulation and Distribution — detects range compression and classifies it by which way price finally leaves.
Sweep — marks wick raids on internal pivots that no close has broken, with a cooldown so the same area is not reported repeatedly.
Daily Bias — previous day and previous week high and low, each anchored to the candle that made it and extended with price, plus unmitigated swing points.
DASHBOARD AND ALERTS
An on-chart table reports the higher timeframe in use, CRT stage and type, direction, CRH and CRL, the three targets, live trade state, key level type, active entry model, daily bias, and time filter status.
Seventeen alert conditions cover every stage from CRT formation through target completion.
REPAINTING
Higher timeframe data is requested with a one-bar offset so only closed higher timeframe candles are used. Signals are evaluated on bar close by default. The script does not repaint under these settings. Disabling the bar-close option allows intrabar signals, which can change before the candle completes — this is stated in the setting's tooltip.
NOTES
The blocked-hours defaults follow the source methodology, which does not state a reference timezone. The timezone input therefore defaults to New York and should be adjusted to your own reference.
Interface labels are bilingual. Text drawn on the chart switches between Arabic and English; setting names show both, because Pine requires input titles to be known at compile time.
This script implements the CRT+TBS methodology as published by its original author. Credit for the underlying concepts belongs to that source; the Pine implementation is my own.
This is an analysis tool. It organises a discretionary method into explicit rules and visible states — it does not predict outcomes and is not a signal service. Position sizing and risk management remain entirely the responsibility of the user. Test on historical data and in simulation before applying to a live account.
نظرة عامة
تطبيق قائم على القواعد لنظرية نطاق الشمعة (CRT) مدمجاً مع حساء جسم السلحفاة (TBS). يقرأ الإعداد على فريم كبير، ويشترط منطقة اهتمام، وينتظر سحب السيولة، ثم يحدد الدخول ويدير الصفقة على شارتك.
آلية العمل
سبع مراحل متسلسلة. فشل أي مرحلة يُلغي ما بعدها.
١. اختيار الفريم الكبير — ترابط تلقائي حسب جدول المنهج، أو يدوي
٢. رصد مناطق الاهتمام — قمة سابقة، قاع سابق، أوردر بلوك، فجوة سعرية
٣. رصد الـCRT — تجميع، تلاعب، توزيع
٤. فلتر الأوقات الممنوعة
٥. تأكيد الـTBS
٦. مودل الدخول
٧. إدارة الصفقة
تسلسل الـCRT
تجميع — شمعة تحدد النطاق، قمتها CRH وقاعها CRL.
تلاعب — شمعة لاحقة يخترق ويكها الحد ثم يعود الإغلاق داخل النطاق. هنا يُحدَّد الاتجاه والهدف.
توزيع — السعر يقصد الطرف المقابل.
القاعدة الحاسمة: الاختراق بالويك والإغلاق راجع داخل النطاق. أما الإغلاق خارجه فاختراق حقيقي لا فخ — ويُلغى الإعداد ويوصف بـ«CRT عكسي».
تُصنَّف الأنواع الأربعة تلقائياً. والرابع، حيث يُسحب السعر مرتين، يُعلَّم كتحذير ويُرسم مستوى T.S الخاص به.
ويُرسم التلاعب منطقةً تغطي الشمعات التي تجاوزت الحد وعادت، فيظهر عمق السحب بدل أن يُستنتج.
مناطق الاهتمام
الـCRT وحده غير كافٍ — فالمنهج يعدّ غياب منطقة الاهتمام سبباً رئيسياً للفشل. الاشتراط مفعّل افتراضياً ويمكن إطفاؤه.
مفاتيح إظهار كل نوع تتحكم بالرسم وحده. المناطق المخفية تُرصد وتُحقق شرط الالتقاء وتُحتسب في الحد. إخفاء نوع لا يغيّر الإشارات إطلاقاً.
حساء جسم السلحفاة
شرطان معاً: إغلاق شمعة يتجاوز قمة أو قاعاً سابقاً — السحب بالجسم لا بالويك — ثم إغلاق شمعة لاحقة خلف آخر شمعة معاكسة.
مودلات الدخول
Model #1 — إغلاق شمعة كاملة خلف السابقة، والدخول عند ذلك الإغلاق.
CISD — كسر مستوى فتح آخر موجة، والدخول فور الكسر.
MSS + FVG — كسر بنيوي بإزاحة تخلّف فجوة، والدخول من الفجوة عند الارتداد.
تعمل الثلاثة معاً أو يُختار واحد. كل مودل يُطلق مرة واحدة لكل إعداد.
إدارة الصفقة
الوقف خلف أقصى امتداد للتلاعب والسحب، مع هامش محسوب بالـATR.
الأهداف تتبع الرنج لا مضاعفات ثابتة للمخاطرة:
TP1 — منتصف الرنج، وهو مستوى ٥٠٪ الذي يعلّمه المنهج في رسوماته
TP2 — الطرف المقابل، هدف المنهج المعلن، وعليه تُقاس نسبة المخاطرة للعائد
TP3 — امتداد بعد الرنج بمضاعف قابل للتعديل
الهدف الذي لا يقع خلف سعر الدخول يُهمَل بدل رسمه خلف السعر. وعند تحقق TP1 ينتقل الوقف لنقطة التعادل. ويُفحص الوقف قبل الأهداف في كل شمعة، فالشمعة التي تلمس الاثنين تُحتسب خسارة.
وحدات إضافية
التجميع والتوزيع — يرصد انضغاط النطاق ويصنّفه باتجاه خروج السعر منه.
سحب السيولة — يعلّم غارات الويك على نقاط داخلية لم يكسرها إغلاق، مع فترة تهدئة تمنع تكرار الإشارة.
الانحياز اليومي — أعلى وأدنى اليوم والأسبوع السابقين، كل مستوى مربوط بالشمعة التي صنعته وممتد مع السعر، مع نقاط التأرجح غير المستهلكة.
الجدول والتنبيهات
جدول على الشارت يعرض الفريم الكبير المستخدم، ومرحلة الـCRT ونوعه، والاتجاه، وCRH وCRL، والأهداف الثلاثة، وحالة الصفقة الحيّة، ونوع منطقة الاهتمام، والمودل النشط، والانحياز اليومي، وحالة فلتر الوقت.
سبعة عشر تنبيهاً تغطي كل مرحلة من تكوّن الـCRT حتى تحقق الأهداف.
إعادة الرسم
تُطلب بيانات الفريم الكبير بإزاحة شمعة واحدة، فلا تُستخدم إلا الشمعات المغلقة. وتُقيَّم الإشارات على إغلاق الشمعة افتراضياً. المؤشر لا يعيد الرسم بهذه الإعدادات. وإطفاء خيار الإغلاق يسمح بإشارات داخل الشمعة قد تتغيّر قبل اكتمالها، وهذا مذكور في تلميح الإعداد.
ملاحظات
الساعات الممنوعة الافتراضية تتبع المنهج المصدر، وهو لا يذكر التوقيت المرجعي. لذلك يأتي إعداد المنطقة الزمنية بتوقيت نيويورك افتراضياً، ويُضبط حسب توقيتك.
واجهة الإعدادات ثنائية اللغة. نصوص الشارت تتبدّل بين العربية والإنجليزية، أما أسماء الإعدادات فتظهر باللغتين معاً لأن Pine يشترط معرفة عناوين المدخلات وقت التصريف.
هذا المؤشر يطبّق منهجية CRT+TBS كما نشرها مؤلفها الأصلي. الفضل في المفاهيم الأساسية يعود لذلك المصدر، والتنفيذ بلغة Pine من عملي.
أداة تحليل تنظّم منهجاً اجتهادياً في قواعد صريحة وحالات مرئية — لا تتنبأ بالنتائج وليست خدمة توصيات. تحديد حجم المركز وإدارة المخاطر مسؤولية المستخدم وحده. اختبره على البيانات التاريخية وفي التداول التجريبي قبل تطبيقه على حساب حقيقي. 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

Grid Ranges+ (M1D)Grid Ranges+ (M1D)
A grid-range framework for the New York trading day. It draws the higher-timeframe levels that frame the current range, divides any range you choose into quadrants, octants or sixteenths, boxes the three trading sessions, and reads the 12AM–2AM algorithmic range for aid in a directional bias.
Every session window is evaluated in America/New York regardless of the time zone the chart is viewed from, and every window is an input.
HOW IT IS BUILT
Levels are anchored to the candle that formed them. A higher-timeframe data request returns the value of a period's high but not the bar that made it. This script tracks each period's extremes on the chart instead, along with the bar time of each, so a previous-day high begins at the candle that set it rather than at the moment the number changed. The trade-off is that a period only reports once its opening bar is inside loaded history; where it is not, the level stays hidden rather than anchoring to a bar that did not set it.
Week and month boundaries derive from the New York day stamp, not from a weekly timeframe change, which is unreliable on futures instruments.
The swing pair is kept alternating. Pivot-high and pivot-low detection are independent of each other, so a chart can print several highs with no qualifying low between them. A pivot on the same side as the stored one replaces it only when it is more extreme, while a pivot on the opposite side begins the next leg. Without that rule, a recent high pairs with a low from a different move and the two do not describe one leg.
WHAT IT DRAWS
Levels.
Previous month, previous week, previous day and three-day highs and lows, the previous day's equilibrium, and the midnight open. Each line runs from its origin candle to a fixed right-hand edge and carries its name at that end, on the same eye-line as the price it names. Names that would otherwise print on top of each other move right into a second column rather than off their own line.
The grid.
A range bounded by any two of those levels, selected from two dropdowns and oriented automatically, divided into quadrants, octants or sixteenths. It begins at the earlier of the two origin candles. The midline is labelled EQ, and quarter fractions are reduced to lowest terms. A fraction is suppressed wherever a level already names that price, so no price carries two names.
Sessions.
Asia, London and New York as boxes that grow with each session's own high and low and freeze when the window closes. The caption sits below the box at the session open. Each session carries its own day mask.
The bias.
The 12AM–2AM algorithmic range as a box, and a console reading BULLISH, BEARISH, INVALIDATED or UNSET. A sweep clearing both the range boundary and the midnight open inside the sweep window, followed by a confirmed close back inside the range, arms a directional read. A confirmed close back through the swept extreme invalidates it, after which the opposite side may arm. Three alert conditions cover those transitions.
SETTINGS
Grouped as-
Time windows, Sessions, Bias engine, Grid range, Levels shown, Level styling and Labels.
Every level carries its own colour, line style, line width and label offset. The grid carries its own colour, style, width, interior transparency and equilibrium colour. Every session window is an input with a New York default and its own day mask, and session boxes carry their own colours and fill transparency.
NOTES
Nothing extends to the right edge of the chart. Every line stops a set number of bars past the live candle, and its label sits at that end.
Current-day and swing anchors move as the session develops, so a grid anchored to them redraws live. A grid anchored to completed periods does not.
Display toggles gate drawing only. Hiding an element never stops it being tracked, so the bias read is unaffected by what is on screen.
Grid boundaries are not drawn by the grid by default. A boundary is the anchor level itself, which already draws its own line from its own origin candle.
Disclaimer-
This script is a charting tool. It is not financial advice, and it makes no claim about where price will go. Indicator

Indicator

Indicator

Indicator

Indicator

Indicator

Smart-FVGSmart-FVG — Fair Value Gaps with Wick-Touch Tracking & Inverse FVG
Smart-FVG detects three-candle Fair Value Gaps and then tracks what price *does* with them. Instead of just drawing boxes, it distinguishes between untouched gaps, gaps that have been wick-tested, and gaps that have been fully mitigated — and it highlights the single most recently mitigated gap as a potential Inverse FVG (a gap that may now act as the opposite side's support/resistance).
How it works
Detection . A bullish FVG forms when the current candle's low gaps above the high from two candles back; a bearish FVG forms when the current candle's high gaps below the low from two candles back. Two quality filters keep the chart clean:
Min FVG Gap — the gap must be at least this size to be drawn.
Min Middle-Candle Body — the displacement candle in the middle of the pattern must have a real body of at least this size, filtering out weak, low-conviction gaps.
Both sizes can be entered in ticks (automatically scaled to the symbol's tick size — 0.25 on NQ/ES, 0.10 on GC, etc.) or in raw price points.
Wick-touch tracking . If a wick pierces into the gap but the candle closes back outside it, the FVG is recolored (gray by default). The level was tested and respected — often a sign of a partially filled gap that may still hold, but with less "fresh" liquidity than an untouched one.
Mitigation . When a candle *closes* through the far side of the gap, the FVG is considered fully mitigated and is removed from the chart. Wicks alone never mitigate — only closes.
Inverse FVG . The most recently mitigated gap is redrawn in a distinct color (purple by default) from its original starting point. A bullish FVG that price closed through often flips into resistance, and vice versa — this is the inversion (iFVG) concept. Only the single latest mitigation is shown to avoid clutter, and the highlight extends for a configurable number of bars after mitigation before freezing in place. Each new mitigation replaces the previous inverse.
Every gap also displays a dashed equilibrium line at its 50% level — a common target for partial fills and a refined entry point inside the gap.
Settings
Size Inputs In Ticks — toggle between tick-based and point-based gap/body sizing
Min FVG Gap / Min Middle-Candle Body — quality filters described above
Max Active FVGs Per Side — caps how many bullish and bearish gaps are kept on the chart (oldest are dropped first)
Colors & Line Width — bullish, bearish, wick-touched, and inverse colors are all configurable
Show Inverse FVG / Inverse Display Bars — toggle the iFVG highlight and control how long it extends after mitigation
Notes
Boxes are drawn as outlines with a dashed midline, keeping candles fully visible.
Works on any symbol and time frame; tick-based sizing makes settings portable across futures contracts.
The gap-completion candle itself can mitigate or wick-test the gap it just created, keeping behavior consistent with strict close-based rules.
This indicator is a charting tool, not a trading system. FVGs and inversions describe how price has interacted with prior inefficiencies — always combine with your own analysis and risk management. Indicator

Sniper Liquidity Zones by DAVIDThis indicator is built for Smart Money Concepts (SMC) and ICT traders who want to capture high-probability entry opportunities based on Liquidity Sweeps and Fair Value Gaps (FVG).
Instead of cluttering the chart with endless arrows, shapes, or text labels, this tool draws clean Rectangle Zones that mark exact trading areas and remain active on your chart until price mitigates them.
System Logic and How It Works
Liquidity Sweeps Detection
The indicator tracks dynamic Swing Highs (Buy-Side Liquidity / BSL) and Swing Lows (Sell-Side Liquidity / SSL) using customizable pivot lookback periods. A sweep is confirmed when price pierces past a key swing point and closes back inside the range.
Fair Value Gap (FVG) Confluence
After a liquidity sweep occurs, the algorithm scans the next few candles for a valid 3-bar Fair Value Gap (Imbalance). When a sweep is backed by an FVG, it confirms institutional footprint and validates the signal.
Dynamic Buy and Sell Rectangle Zones
When both Liquidity Sweep and FVG conditions align:
A Green Rectangle Zone labeled "buy" is created for bullish setups.
A Red Rectangle Zone labeled "sell" is created for bearish setups.
These boxes automatically extend horizontally across future bars until price crosses through them (mitigation), giving you clear retest levels.
Built-in Anti-Spam Filter
To prevent duplicate signals on lower timeframes and maintain chart clarity, a minimum bar distance filter is integrated. This ensures zones only appear on fresh, distinct setups.
How to Use for Trading
Buy Setup:
Wait for price to sweep Sell-Side Liquidity (SSL).
Look for the Green Rectangle Zone labeled "buy" to appear on your chart.
Enter on the open or retest of the green rectangle zone, placing stop loss below the zone low.
Sell Setup:
Wait for price to sweep Buy-Side Liquidity (BSL).
Look for the Red Rectangle Zone labeled "sell" to appear on your chart.
Enter on the open or retest of the red rectangle zone, placing stop loss above the zone high.
Indicator Inputs
Pivot Lookback Length: Determines how far back the script looks to mark major market structure highs and lows.
Max Bars After Sweep to Find FVG: Controls how many candles after a sweep the script checks for an imbalance gap.
Min Bars Between Zones: Filters out closely repeating signals to avoid noise on volatile charts.
Zone Transparency and Colors: Allows complete visual customization of the buy and sell boxes. 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

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

Navyraid ToolNavyraid Tool - ICT All-in-One Suite
The Navyraid Tool is a comprehensive, all-in-one indicator designed for traders utilizing Inner Circle Trader (ICT). To prevent chart clutter from overlapping indicators, this tool intelligently consolidates time-based sessions, liquidity levels, price gaps, and SMT divergences into a single, lightweight suite.
Key Features & How It Works:
Smart Auto-DST Sessions: Visually highlights the Asia, London, and New York sessions. It features a built-in dynamic timezone engine that automatically shifts session start/end times based on the active Daylight Saving Time (DST / Non-DST) period. Users can simply toggle between "Forex & Gold Mode" or "Index Mode" to get the mathematically accurate session times without manual monthly adjustments.
Liquidity Levels (PDH/PDL & PWH/PWL): Automatically maps out the Previous Daily High/Low and Previous Weekly High/Low. These lines serve as visual aids for identifying potential draw-on-liquidity targets or purge levels.
True Price Gaps (NWOG & NDOG): Plots the New Week Opening Gap (NWOG) and New Day Opening Gap (NDOG). The indicator actively tracks price interaction; if a candle mitigates and closes outside the gap boundary, it dynamically changes color to represent an "Inverse Gap."
Multi-Timeframe FVG (Fair Value Gaps): Simultaneously displays Higher Timeframe (HTF) and Lower Timeframe (LTF) FVGs on your current chart. Similar to the price gaps, these zones turn into Inverse FVGs (IFVG) upon full mitigation.
Manual SMT Divergence Engine: A strictly manual, linear SMT tracking system. By inputting a correlated comparison symbol (e.g., SP500FT vs NAS100FT, or EURUSD vs GBPUSD), the script calculates and draws structural divergences across Weekly, Daily, and Sessional timeframes.
Why this script?
Most ICT indicators only focus on one concept. The Navyraid Tool integrates all crucial time-and-price theories into one organized dashboard while maintaining high performance through strict historical lookback limiters.
Disclaimer: This indicator is designed solely for educational and structural analysis. It does not generate buy/sell signals. Always use proper risk management. Indicator

Asian Range Liquidity Sweep - Kill Zone ReversalASIAN RANGE LIQUIDITY SWEEP — the complete ICT Asian Range liquidity model in one indicator
The Asia session builds a small, quiet range. London opens, runs the stops sitting above or below that range, and then walks the price the other way. That single move is one of the most repeatable things in FX, and this indicator is the full rule set for it: the range, the liquidity raid, the higher-timeframe point of interest that makes the raid tradeable, the entry, the stop, the targets — and, just as important, the days on which the raid will NOT happen.
Everything is drawn in New York time, the way the model is defined.
━━━ WHAT IT DOES ━━━
① ASIAN RANGE (20:00 – 00:00 New York)
A time based range, not a structural one. The box, its high, its low and its 50 % are projected forward into the whole trading day. The high is buy side liquidity, the low is sell side liquidity. Direction is mechanical and never inverts: above the range this model only sells, below the range it only buys.
② HIGHER TIMEFRAME POI ENGINE — the filter that decides everything
A raid of the Asian high on its own is, most of the time, a trap. The raid only becomes high probability when it lands inside a higher-timeframe point of interest. The indicator scans three timeframes at once (15m / 1h / 4h by default) for
· Fair Value Gaps
· Order Blocks
· Breaker Blocks (a demand block that price closed through and that now acts as resistance)
· Inverse Fair Value Gaps (a bullish gap that got closed through and flipped bearish)
Every zone is anchored to the exact candles that built it, is extended while it is alive, and is dropped once it is used up or once it sits too far from the daily range to matter. On top of that, the higher-timeframe structure itself has to agree: bearish structure for shorts, bullish for longs.
③ LONDON KILL ZONE (02:00 – 05:00, optional 01:30 start) — Trade 1
Between those hours the indicator waits for price to raid the Asian high (or low) INTO one of those zones. A raid is not even accepted as valid until price has traded back into a fair value gap. Then it waits for a lower-timeframe confirmation and enters at a point of interest — never at market:
· MSS + FVG — market structure shift, entry on the retracement into the gap
· CISD — change in state of delivery, entry back at the CISD level itself
· FVG tap — proximal edge on small gaps, 50 % on big ones
· HIDDEN ORDER BLOCK — the opposite-colour candle trapped between two same-direction fair value gaps. The block almost nobody marks, and the sharpest entry in the whole model
That list is a risk ladder: 1m MSS+FVG is the most aggressive and pays the most, 15m FVG is the safest, wins most often and pays the least. Pick the timeframe you actually want to trade and run the indicator there.
Stop goes on the protective structure that belongs to the entry zone. Target 1 is always the opposite side of the Asian range. Target 2 extends to the next inducement swing — the draw for the day.
④ NEW YORK KILL ZONE (07:00 – 10:00) — Trade 2, the continuation
When the London raid then breaks the OPPOSITE side of the Asian range with displacement, the London extreme is very likely the high or the low of the day. The indicator draws the optimal trade entry fibonacci over that impulse — 0.5 / 0.618 / 0.705 / 0.79 — and takes the continuation from the retracement into it, with the stop beyond 0.79 or 1.0. The setup is strongest when the origin zone was a 4h zone, because the whole day is then a 4h market-maker model running internal to external. If the draw on liquidity was already reached before New York opens, the day is flagged as low probability and skipped.
⑤ THE NO-SWEEP FILTERS — the part almost nobody explains
Two situations mean the raid you are waiting for will never come:
· HTF POI ALREADY TAPPED IN ASIA — price worked into the zone during the Asian session and then broke structure against the range. The Asian high is now protected. The indicator says so on the chart and points you at the fallbacks instead: the 50 % of the range, an internal range high (trend line liquidity), or a fair value gap built inside the Asian session.
· STRONG HIGH / STRONG LOW INSIDE THE RANGE — a sweep immediately followed by a break of structure. That extreme is protected. What looks like equal highs later on is a rejection-block reversal, not a raid. Wait for the sweep and you miss the trade.
⑥ NEWS FILTER
High-impact US news in the New York session turns London into a range or a one-way run with no reversal. Pine cannot read a news feed, so paste the dates and those days are skipped.
━━━ WHY EVERY SIGNAL EXPLAINS ITSELF ━━━
Hover any signal pill and you get the full reasoning, not a label:
the range and its size, the exact price the liquidity was raided at, which point of interest it landed in, what the higher timeframe structure was doing, which confirmation fired, whether the raid was validated by a fair value gap, plus entry, stop, both targets, risk in pips, reward in pips and the R multiple.
Setups that were found but rejected are explained too. A "NO TRADE" tag tells you the raid, the zone and the confirmation were all there but the reward did not pay for the stop — so you learn the filter instead of wondering why nothing fired.
Every zone, every structure event, the range lines, the OTE levels and both education cards carry the same kind of tooltip. There is a HOW TO READ THIS card and an honest BEFORE YOU TRADE THIS card on the chart.
━━━ COCKPIT PANEL ━━━
Live session state, symbol, chart timeframe, higher-timeframe bias, the full Asian range with a PROTECTED / OPEN flag on each side, an eight-step checklist that fills in as the setup builds, the open position with stop and target, a large status line, a rough win / loss / break-even tracker and the timestamp of the last signal.
━━━ ALERTS AND AUTOMATION ━━━
Every event fires a clean JSON payload ready for a webhook — entry, stop, both targets, the range boundaries, the point of interest that produced the signal, symbol, exchange, timeframe, volume and an optional account field. Events: ENTRY, TP1, SL, BE, SWEEP, RANGE. Five plain-language alertconditions are included as well for anybody who just wants a notification.
━━━ SETTINGS WORTH KNOWING ━━━
· Sessions are fully configurable if your broker feed needs a different reference
· Turn individual POI types and POI timeframes on and off
· Choose one confirmation model or let it take the first valid trigger
· Four stop modes, two-target management, break-even at a chosen R
· Full chart theme with navy background, mint / red candles and session shading — or switch it off and keep your own
━━━ HONEST NOTES ━━━
This model is mechanical up to the trigger. Direction is fixed and never inverts, the windows are fixed, the filters are fixed — but the final judgement, is this really the high of the session, stays discretionary. Anybody telling you a setup is 100 % mechanical is selling you something.
Expect zero to four setups a day across two pairs, roughly 20 pips average per trade, and losing days. Judge it weekly and monthly, never daily. The safest entry model fires rarely by design; the aggressive ones fire more and stop out more.
The win / loss counter in the panel is a rough on-chart tracker that assumes a fill at the marked price and resolves target before stop within the same bar. It is not a backtest and it is not a performance claim.
This indicator is a study tool. It is not financial advice.
━━━ CREDIT ━━━
The rule set follows the well-known ICT Asian-sweep model as it is taught publicly in the ICT community. The implementation, the point-of-interest engine, the no-sweep filters, the panel and the design are original work.
Open source — read it, change it, learn from it.
WHY THESE PARTS BELONG TOGETHER
The session range, the higher-timeframe point of interest and the lower-timeframe confirmation form
a single filter chain, and the model does not work with any link missing. The range supplies the
liquidity pool that is going to be raided, the higher-timeframe zone decides whether that raid is a
reversal or a trap, and the lower-timeframe trigger decides when. A raid without a zone is noise,
a zone without a raid has nothing to react to, and both without a trigger have no entry.
Indicator

Indicator

Macro MagicianMacro Magician — Hourly Macros (:50 → :10)
Short description
Marks the :50 → :10 hourly macro windows, shades the opening minute of each, and can carry a chosen macro's opening range across the rest of the session.
Full description
What it does
Macro Magician draws the twenty-minute windows that run from :50 of one hour to :10 of the next — the periods intraday traders commonly call hourly macros. Each window gets a shaded box tracking its high and low, and the opening candle of the window is shaded separately in a darker tone, so you can see where price opened the window from relative to where it finished.
Beyond marking the windows, two features do the work that usually gets done by hand:
Carried-forward opening ranges. Any macro can have its opening-candle high and low projected to the right across the rest of the session, turning that one minute into a horizontal reference band. The macro's time is reprinted along the band at a cadence you set, so it stays identifiable hours later without hovering over it.
A standalone highlight candle. One candle per session — 09:30 by default, matching the equity cash open — can be recolored, given a vertical backdrop and a marker, and boxed with its own carried-forward band. This runs independently of the macro slots, so it works whether or not that minute falls inside a macro window.
Nothing here produces signals or predicts direction. It is a time-and-level marking tool that puts the windows and their opening ranges on the chart automatically.
Settings
General
Timezone — all times are interpreted in this zone, so boxes land correctly regardless of your chart's display timezone. Defaults to New York; "Exchange" follows the symbol.
Timeframe limit — hides the drawings above a chosen timeframe. Default 15 minutes.
Style
Fill, opening-candle fill, and border transparency, plus border width.
Opening-candle level — projects the window's opening candle's open, close, or midpoint as a dotted line across the window.
Label visibility and size.
Chart theme — Auto, Light, or Dark. Auto reads the chart's background brightness and flips the extended-macro label text between the two colors you choose, so the script is legible on either without touching anything else.
Optional alert when a macro opens.
Macro windows Eight independent slots, each with an on/off toggle, a session, a color, and an extend checkbox. Defaults cover 06:50 through 14:10 New York time. The session field accepts day filters, so 0850-0910:23456 restricts a window to Tuesday through Saturday for futures. One "extend through" session sets where all carried-forward bands stop, 16:00 by default.
Extended opening range Controls the band label cadence — either at a fixed minute interval from the macro open, or once an hour at a clock minute you choose so the prints stay clear of the other macro windows — along with the text size, which applies to both the label above the box and the prints along the band.
Highlight candle Hour and minute for the candle, its color, an optional full-height vertical backdrop with its own transparency, an optional triangle marker above or below the bar, and an optional carried-forward box with independent fill, border, and width settings. The box can start on the candle or just after it, so its fill doesn't wash out the candle's own color.
How to read it
The lighter box shows what the window did — its full high and low. The darker box shows the range it opened from. When a window closes well outside its opening range, the two together show the displacement at a glance. A carried-forward band lets later sessions be read against an earlier opening range without redrawing it each day.
Notes and limitations
Intraday charts only. On a 1-minute chart the darker box is exactly the :50 candle; on a 5-minute chart it is the first five minutes of the window, which is wider by design.
The highlight candle is drawn with barcolor plus a candle overlay, so it survives chart settings that override bar colors. On timeframes above one minute it paints whichever bar carries that opening time.
PulseWire caps drawings at 500 boxes, lines, and labels, so the oldest sessions eventually drop off the left of the chart. Running fewer macro slots keeps more history visible.
Windows in progress update until they close, as you would expect. Nothing recalculates on historical bars.
This is a charting aid, not a strategy, and not financial advice. Test how these windows behave on your own instrument and timeframe before relying on them. Indicator

EVA Ai+ FVG v1.3 Fair Value Gap FVG - ICT Imbalanc🧬 EVA Ai+ Fair Value Gap — индикатор FVG, дисбаланса и ликвидности
EVA Ai+ Fair Value Gap — это автоматический FVG-индикатор для PulseWire, который находит бычьи и медвежьи зоны Fair Value Gap, показывает ценовой дисбаланс на графике и отслеживает заполнение каждой зоны в реальном времени.
Индикатор предназначен для анализа Price Action, ICT, Smart Money Concepts, ликвидности и рыночного дисбаланса. Он помогает увидеть участки, где цена прошла слишком быстро и оставила незаполненный диапазон между свечами.
🔍 Что такое FVG
Fair Value Gap — FVG представляет собой трёхсвечный ценовой дисбаланс.
🟢 Бычий FVG формируется, когда цена резко движется вверх и между предыдущими свечами остаётся незаполненный диапазон.
🔴 Медвежий FVG формируется при сильном нисходящем движении, когда между свечами остаётся незаполненная область.
Такие зоны обычно рассматриваются как области интереса для анализа возможного возврата цены, реакции, продолжения движения или заполнения дисбаланса. На PulseWire FVG обычно описывается именно как трёхсвечный imbalance, который цена впоследствии может частично или полностью заполнить.
⚙️ Что делает индикатор
✅ Автоматически обнаруживает Bullish FVG и Bearish FVG
✅ Отображает зоны Fair Value Gap непосредственно на графике
✅ Поддерживает текущий или отдельный таймфрейм поиска
✅ Продлевает активные зоны вправо
✅ Динамически уменьшает FVG по мере его заполнения ценой
✅ Не восстанавливает уже заполненную часть после отката
✅ Полностью удаляет зону после полного перекрытия
✅ Поддерживает автоматическую фильтрацию слабых дисбалансов
✅ Позволяет настраивать цвета и количество активных зон
✅ Формирует отдельные алерты для бычьего и медвежьего FVG
✅ Использует lookahead_off без переноса будущих данных в прошлое
📉 Динамическое заполнение FVG
Главная особенность EVA Ai+ FVG — Dynamic Mitigation.
Когда цена начинает входить в Fair Value Gap:
закрашенная область уменьшается вместе с заполнением;
на графике остаётся только незакрытая часть дисбаланса;
уже перекрытая область не появляется снова после отката;
после полного заполнения FVG автоматически удаляется.
Это позволяет видеть не просто исторические прямоугольники, а актуальный остаток ценового дисбаланса.
📈 Как применять бычий FVG
Бычья зона отмечается зелёным цветом.
Возможный сценарий анализа:
Определите восходящий тренд или бычью структуру рынка.
Найдите свежий Bullish Fair Value Gap.
Дождитесь возврата цены к зоне.
Следите за реакцией цены внутри незаполненной части FVG.
Используйте дополнительное подтверждение: структуру рынка, объём, уровень поддержки, свечную реакцию или импульс.
Рассматривайте противоположную границу зоны как точку отмены сценария только в рамках собственной торговой системы.
📉 Как применять медвежий FVG
Медвежья зона отмечается красным цветом.
Возможный сценарий анализа:
Определите нисходящий тренд или медвежью структуру рынка.
Найдите свежий Bearish Fair Value Gap.
Дождитесь возврата цены к зоне дисбаланса.
Оцените реакцию продавцов внутри оставшейся части FVG.
Подтвердите сценарий структурой рынка, сопротивлением, объёмом или свечной моделью.
Не используйте сам факт касания FVG как обязательную команду для входа.
🕒 Мультитаймфрейм-анализ
В настройках можно выбрать отдельный таймфрейм поиска.
Примеры применения:
FVG с 1H на графике 15m;
FVG с 4H для поиска зон на младшем таймфрейме;
FVG текущего таймфрейма для скальпинга и внутридневного анализа;
старший FVG как контекст, младший таймфрейм — для уточнения реакции.
Если поле таймфрейма оставить пустым, индикатор использует текущий таймфрейм графика.
🎯 Практические варианты использования
EVA Ai+ FVG можно применять для:
поиска зон возврата цены;
определения ценового дисбаланса;
анализа ликвидности;
поиска потенциальных зон поддержки и сопротивления;
анализа продолжения тренда;
поиска реакции после импульсного движения;
ICT и Smart Money Concepts;
Price Action;
внутридневной торговли;
скальпинга;
свинг-трейдинга;
анализа криптовалют, акций, форекса, индексов и фьючерсов.
🔔 Алерты
Доступны два типа уведомлений:
🟢 обнаружен новый Bullish Fair Value Gap;
🔴 обнаружен новый Bearish Fair Value Gap.
Алерты создаются через стандартное меню уведомлений PulseWire.
⚠️ Важно
Fair Value Gap не является самостоятельной гарантией разворота или продолжения движения. FVG следует использовать вместе с направлением тренда, рыночной структурой, ликвидностью, объёмом и управлением риском.
Индикатор является аналитическим инструментом и не представляет собой инвестиционную рекомендацию.
🧬 EVA Ai+ Fair Value Gap — FVG, Imbalance and Liquidity Indicator
EVA Ai+ Fair Value Gap is an automatic FVG indicator for PulseWire that detects bullish and bearish Fair Value Gaps, displays price imbalance zones directly on the chart, and tracks the mitigation of every active gap.
The indicator is designed for Price Action, ICT, Smart Money Concepts, liquidity analysis, market imbalance, and order-flow context. It highlights areas where price moved rapidly and left an inefficient or unfilled range between candles.
🔍 What is a Fair Value Gap?
A Fair Value Gap — FVG is a three-candle price imbalance.
🟢 A Bullish FVG appears after strong upward displacement leaves an unfilled range below the current price.
🔴 A Bearish FVG appears after strong downward displacement leaves an unfilled range above the current price.
These zones can be used as areas of interest for analyzing a potential price return, reaction, continuation, or full mitigation. PulseWire’s FVG search pages and widely followed scripts use the same core vocabulary: Fair Value Gap, imbalance, liquidity, mitigation, and three-candle structure.
⚙️ Main features
✅ Automatic Bullish FVG detection
✅ Automatic Bearish FVG detection
✅ Clear Fair Value Gap zones on the chart
✅ Current-timeframe and multi-timeframe analysis
✅ Active FVG zones extended to the right
✅ Dynamic partial mitigation
✅ Filled portions never reappear after a pullback
✅ Automatic removal after complete mitigation
✅ Optional automatic imbalance threshold
✅ Custom bullish and bearish colors
✅ Adjustable maximum number of active gaps
✅ Bullish and bearish PulseWire alerts
✅ lookahead_off calculation
📉 Dynamic FVG mitigation
The key feature of EVA Ai+ FVG is Dynamic Mitigation.
As price moves into a Fair Value Gap:
the highlighted zone contracts with the fill;
only the remaining unmitigated imbalance stays visible;
previously consumed portions do not expand again;
the complete FVG is removed after a full fill.
This provides a cleaner representation of the imbalance that is still active instead of leaving obsolete rectangles across the chart.
📈 How to use a Bullish FVG
Bullish zones are displayed in green.
A possible analysis workflow:
Identify a bullish trend or bullish market structure.
Locate a fresh Bullish Fair Value Gap.
Wait for price to return toward the imbalance.
Observe the reaction inside the remaining FVG.
Confirm the setup with market structure, volume, support, momentum, or candle reaction.
Define invalidation and risk according to your own trading plan.
📉 How to use a Bearish FVG
Bearish zones are displayed in red.
A possible analysis workflow:
Identify a bearish trend or bearish market structure.
Locate a fresh Bearish Fair Value Gap.
Wait for price to retrace into the imbalance.
Evaluate seller reaction inside the remaining FVG.
Use resistance, market structure, volume, or price-action confirmation.
Do not treat every FVG touch as an automatic entry signal.
🕒 Multi-timeframe FVG analysis
The indicator can detect Fair Value Gaps from a selected timeframe.
Examples:
display 1H FVG zones on a 15m chart;
use 4H imbalance zones as higher-timeframe context;
use chart-timeframe FVGs for intraday trading and scalping;
combine higher-timeframe liquidity zones with lower-timeframe confirmation.
Leave the timeframe field empty to use the current chart timeframe.
🎯 Common use cases
EVA Ai+ FVG can be used for:
Fair Value Gap trading;
liquidity-zone analysis;
market imbalance detection;
ICT trading concepts;
Smart Money Concepts;
Price Action;
support and resistance context;
trend-continuation analysis;
pullback and retracement analysis;
crypto trading;
forex trading;
stock trading;
futures and index analysis;
scalping, day trading, and swing trading.
🔔 PulseWire alerts
Two alert conditions are included:
🟢 New Bullish Fair Value Gap detected;
🔴 New Bearish Fair Value Gap detected.
Alerts can be configured through the standard PulseWire alert menu.
⚠️ Disclaimer
A Fair Value Gap does not guarantee a reversal, continuation, or profitable trade. FVG zones should be evaluated together with trend direction, market structure, liquidity, volume, confirmation, and risk management.
This indicator is an analytical tool and does not provide financial or investment advice. Indicator
