CTZ Swing Exhaustion Levels
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «indicator ctz swing exhaustion levels for tradingview.pine» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
CTZ Swing Exhaustion Levels — индикатор анализа и отображения для TradingView (Pine Script v6), который отслеживает свечные swing-структуры (свинг-хаи и свинг-лоу) и рассчитывает уровни истощения с вероятностными прогнозами. Свинг завершается, когда цена возвращается на расстояние k ATR(14) от экстремума, а вероятности достижения уровней и разворота рассчитываются на основе истории свингов текущего графика. Индикатор отображает линии уровней (50%, 75%, 90%), временное окно, зигзаг, теги структуры и информационную панель с показателями. Встроен ядерный регрессионный тренд на основе метода Надарая—Уотсона (рационально-квадратичное + гауссово ядро), а также сигналы совпадения свинг- и тренд-анализа с поддержкой оповещений.
Настройки программы
| Настройка | Описание |
|---|---|
| mktSel | Выбор рынка: Auto (автоматическое определение крипто), Crypto или Other markets. Влияет на параметры k для свингов. |
| presetSel | Размер свинга: Micro, Standard, Major или Custom. Определяет коэффициент k ATR для завершения свинга (Micro k=1.5/2.0, Standard k=2.5/3.5, Major k=4.0/5.5 — для обычных/крипто рынков). |
| warmIn | Количество сохранённых свингов в каждом направлении, необходимое перед тем, как прогнозы считаются готовыми (ready). Больше — стабильнее прогнозы, дольше прогрев. |
| kCustom | Коэффициент k в кратных ATR для режима «Custom» — расстояние от экстремума свинга, при котором свинг считается завершённым. |
| nCustom | Длина ATR в барах для режима «Custom» (по умолчанию 14). |
| srcSel | Источник для определения экстремумов свинга: Wicks (максимумы/минимумы свечей) или Closes (только закрытия). ATR всегда рассчитывается по true range. |
| showLv | Включение/отключение отображения линий уровней истощения (50%, 75%, 90% за пределами экстремума свинга) с вероятностями. |
| lvLen | Количество баров вправо, на которое отображаются линии уровней истощения. |
| showWin | Включение/отключение отображения временного окна (полосы, в которой половина свингов данного размера завершилась). |
| cardSel | Положение информационной панели с показателями (odds panel) на графике. |
| showTags | Отображение меток структуры (HH/LH/HL/LL) и размера свинга в ATR при каждом подтверждённом пивоте. |
| themeSel | Цветовая тема индикатора: Neon, Classic или Custom. При Neon и Classic цвета задаются встроенными, при Custom — параметрами ниже. |
| upIn | Цвет восходящих (up) свингов и маркеров в режиме «Neon» и «Classic». |
| dnIn | Цвет нисходящих (down) свингов и маркеров в режиме «Neon» и «Classic». |
| accIn | Цвет индикатора часов (временного окна) в режиме «Neon» и «Classic». |
| showZig | Включение/отключение отображения зигзага — линий, соединяющих подтверждённые пивоты. |
| zigT | Прозрачность линий зигзага в процентах (0–90). |
| glowOn | Включение/отключение свечения (glow) линий зигзага — широкая полупрозрачная линия под каждой ногой зигзага. |
| tintSel | Режим окраски свечей: Swing (по текущему свингу — бледные при рождении, насыщенные при достижении 50%), Kernel trend (по ядерному тренду) или Off. |
| showLive | Отображение тега текущего (живого) свинга рядом с последним баром с информацией о размере и возрасте. |
| showKr | Включение/отключение отображения линий ядерной регрессионной оценки и сигнала на графике. |
| krFillOn | Включение/отключение заливки области между ядерной оценкой и ядерным сигналом. |
| krSrc | Источник данных для расчёта ядерной регрессионного тренда. |
| krH | Длина окна обратного отсчёта (lookback) для ядерной регрессии, в барах. Рекомендуется 3–50. Больше — медленнее и плавнее тренд. |
| krR | Относительный весовой коэффициент для рационально-квадратичного ядра. Рекомендуется 0.25–25. Меньше — больше веса долгосрочным движениям. |
| krX | Количество баров, используемых в оценке регрессии (regression level), в барах. Рекомендуется 2–25. |
| krLag | Задержка сигнала для гауссова компонента ядерного тренда, в барах. |
| showSig | Отображение маркеров совпадения свинг- и тренд-сигналов: стрелки при совпадении зоны разворота с изменением ядерного тренда и метки при подтверждении свинга. |
| alKr | Оповещение при совпадении свинг- и тренд-сигналов (совпадение зоны разворота с изменением ядерного тренда). |
| alKrTr | Оповещение при каждом изменении направления ядерного тренда. |
| alLevel | Оповещение при достижении свингом одного из уровней (50%, 75% или 90%). |
| alOdds | Оповещение при пересечении пороговой вероятности разворота или подтверждения (Turn/Conf odds cross). |
| alThr | Процентный порог для оповещений пересечения вероятности (Turn/Conf odds cross), в процентах. |
| alLikely | Оповещение при высокой вероятности разворота (Top/Bottom likely in, когда p_in >= 1 - alpha). |
| alConf | Оповещение при подтверждении свинга (подтверждённый свинг высокого или низкого уровня). |
| alOverdue | Оповещение при просрочке свинга (свинг вышел за пределы временного окна). |
| startTime | Время начала расчётов: все данные (движок, таблицы) начинаются с первого бара на или после указанного времени. |
Поиск по коду файла
indicator("CTZ Swing Exhaustion Levels", "CTZ Swing Exhaustion", overlay = true, max_lines_count = 500, max_boxes_count = 100, max_labels_count = 250)
grpE = "Swing"
mktSel = input.string("Auto", "Market", options = ["Auto", "Crypto", "Other markets"], group = grpE,
tooltip = "Auto uses the crypto presets on crypto charts. Crypto swings run further and wick harder, so a bigger pullback is needed before a swing counts as over.")
presetSel = input.string("Standard", "Swing size", options = ["Micro", "Standard", "Major", "Custom"], group = grpE,
tooltip = "A swing ends when price comes back k ATR(14) from its extreme.\nCrypto: Micro k = 2.0, Standard k = 3.5, Major k = 5.5.\nOther markets: Micro k = 1.5, Standard k = 2.5, Major k = 4.0.")
warmIn = input.int(20, "Swings needed before odds show", minval = 10, maxval = 60, group = grpE,
tooltip = "Per direction. Bigger crypto swings mean fewer swings in the chart's history, so this is lower than the original 30. Higher = steadier odds, longer warm-up.")
kCustom = input.float(2.5, "Custom k (ATR multiples)", minval = 0.5, step = 0.1, group = grpE)
nCustom = input.int(14, "Custom ATR length", minval = 2, group = grpE)
srcSel = input.string("Wicks", "Pivot source", options = ["Wicks", "Closes"], group = grpE,
tooltip = "Closes: extremes and retraces use the close only. The ATR always uses the true range.")
grpD = "Display"
showLv = input.bool(true, "Extension levels", group = grpD, inline = "lv",
tooltip = "Three levels beyond the swing's extreme: of past swings on this chart that got as far as this one and kept going, 50%, 75% and 90% ended before them. Each label shows the chance that price tags the level from here, which also counts the chance that the swing is already over (Top in). The lines move only when the swing makes a new extreme; the odds update every bar. Red over an up swing, green under a down swing.")
lvLen = input.int(30, "bars", minval = 5, maxval = 200, group = grpD, inline = "lv")
showWin = input.bool(true, "Time window", group = grpD,
tooltip = "Faint band over the bars in which half of such swings ended, set at the swing's birth. Dashed once the swing is past it.")
cardSel = input.string("Bottom right", "Odds panel", options = ["Bottom right", "Top right", "Bottom left", "Top left", "Off"], group = grpD,
tooltip = "Swing size and age, the time window, and the odds as bars, all from this chart's own history.")
showTags = input.bool(true, "Structure labels", group = grpD,
tooltip = "At each confirmed pivot: HH / LH / HL / LL and the swing size in ATR. Hover for the length in bars.")
grpS = "Style"
themeSel = input.string("Neon", "Theme", options = ["Neon", "Classic", "Custom"], group = grpS,
tooltip = "Neon and Classic set the colours; Custom uses the three below.")
upIn = input.color(#00e5b4, "Up", group = grpS, inline = "cu")
dnIn = input.color(#ff4d6d, "Down", group = grpS, inline = "cu")
accIn = input.color(#ffb21e, "Clock", group = grpS, inline = "cu")
showZig = input.bool(true, "Zigzag", group = grpS, inline = "zig")
zigT = input.int(10, "transparency", minval = 0, maxval = 90, group = grpS, inline = "zig")
glowOn = input.bool(true, "Glow", group = grpS, inline = "zig")
tintSel = input.string("Swing", "Candle tint", options = ["Swing", "Kernel trend", "Off"], group = grpS,
tooltip = "Swing: bars take the live swing's colour, faint at its birth and full strength as it reaches its 50% level. Kernel trend: bars take the kernel trend colour.")
showLive = input.bool(true, "Live swing tag", group = grpS)
color upCol = themeSel == "Neon" ? #00e5b4 : themeSel == "Classic" ? #26a69a : upIn
color dnCol = themeSel == "Neon" ? #ff4d6d : themeSel == "Classic" ? #ef5350 : dnIn
color accCol = themeSel == "Neon" ? #ffb21e : themeSel == "Classic" ? #f5b041 : accIn
grpK = "Kernel trend"
showKr = input.bool(true, "Show kernel lines", group = grpK, inline = "kr")
krFillOn = input.bool(true, "Fill", group = grpK, inline = "kr")
krSrc = input.source(close, "Source", group = grpK)
krH = input.int(8, "Lookback window", minval = 3, group = grpK, tooltip = "Recommended 3-50. Higher = slower, smoother trend.")
krR = input.float(8.0, "Relative weighting", minval = 0.25, step = 0.25, group = grpK, tooltip = "Recommended 0.25-25. Lower = more weight on longer-term moves.")
krX = input.int(25, "Regression level", minval = 2, maxval = 200, group = grpK, tooltip = "Bars used in the estimate. Recommended 2-25.")
krLag = input.int(2, "Signal lag", minval = 1, maxval = 10, group = grpK)
showSig = input.bool(true, "Confluence signals (swing + trend)", group = grpK,
tooltip = "KR ▲: a down swing is in its turn zone (or bottom likely in) and the kernel trend turns up. ✓ ▲: a swing low is confirmed while the kernel trend is up. Mirrored for tops.")
alKr = input.bool(true, "Alert on confluence signals", group = grpK)
alKrTr = input.bool(false, "Alert on every kernel trend change", group = grpK)
grpA = "Alerts (on bar close; create one alert with 'Any alert() function call')"
alLevel = input.bool(true, "Swing tagged a level", group = grpA)
alOdds = input.bool(false, "Turn / Conf odds cross", group = grpA, inline = "odds")
alThr = input.float(65.0, "%", minval = 1, maxval = 99, group = grpA, inline = "odds")
alLikely = input.bool(true, "Top / bottom likely in", group = grpA)
alConf = input.bool(true, "Swing confirmed", group = grpA)
alOverdue = input.bool(false, "Overdue", group = grpA)
grpP = "Parity check"
startTime = input.time(timestamp("01 Jan 2000 00:00 +0000"), "Start at", group = grpP,
tooltip = "Everything (engine, tables) starts on the first bar at or after this time. For parity exports: set it inside the exported range. Otherwise leave the default, which is the chart's first bar.")
bool IS_CRYPTO = mktSel == "Crypto" or (mktSel == "Auto" and syminfo.type == "crypto")
float K = presetSel == "Custom" ? kCustom : IS_CRYPTO ? (presetSel == "Micro" ? 2.0 : presetSel == "Major" ? 5.5 : 3.5) : (presetSel == "Micro" ? 1.5 : presetSel == "Major" ? 4.0 : 2.5)
int NATR = presetSel == "Custom" ? nCustom : 14
bool CLOSES = srcSel == "Closes"
int DISCARD = 2 // v0.2 2.3: the first two confirmed swings are not kept
float ALPHA = 0.5 // coverage 50%
float M_HAZ = 80.0 // bars; tuned in the study with the twin as the prior, not re-tuned for this build
float M_BAND = 25.0
int N_POOL = 10
int WARM = warmIn // kept swings per direction before forecasts count as ready (original: 30)
int N_MAX = 500
int FULL_STEPS = 30
int WARM_STEPS = 12
float DELTA = 0.5
int TF_SEC = timeframe.in_seconds()
int HZN = TF_SEC <= 60 ? 5 : TF_SEC <= 900 ? 3 : 2 // Turn horizon N (v0.3.1 R2): 1m 5, 5m/15m 3, 30m/1h 2
int N_LOW = 25 // band sample below this: "low sample"
float CMP = 1e20
gtE(float a, float b) => (a - b) * CMP > 0
geE(float a, float b) => (a - b) * CMP >= 0
ltE(float a, float b) => (b - a) * CMP > 0
leE(float a, float b) => (b - a) * CMP >= 0
eqE(float a, float b) => (a - b) * CMP == 0
maxE(float a, float b) => ltE(a, b) ? b : a
minE(float a, float b) => gtE(a, b) ? b : a
absE(float a) => ltE(a, 0.0) ? -a : a
type Engine
float k
int n
bool closes = false
int nTr = 0
float trSum = 0.0
float rma = na // RMA(TR, n) before the floor
float atr = na // after the floor
float cPrev = na
bool started = false
int sid = 0
float dir = 1.0
int b0 = na
float p0 = na
float atr0 = na
float pe = na
int be = na
float atre = na
float deep = na
int birth = na
bool conf = false // a swing was confirmed on this bar
int cB0 = na // the confirmed swing: pivots, direction, A, D
int cB1 = na
float cP0 = na
float cP1 = na
float cDir = na
float cA = na
int cD = na
method step(Engine e, int t, float h, float l, float c, float floorV) =>
float tr = na(e.cPrev) ? h - l : maxE(maxE(h - l, absE(h - e.cPrev)), absE(l - e.cPrev))
e.nTr := e.nTr + 1
if e.nTr < e.n
e.trSum := e.trSum + tr
else if e.nTr == e.n
e.rma := (e.trSum + tr) / e.n
else
e.rma := (e.rma * (e.n - 1) + tr) / e.n
e.atr := e.nTr >= e.n ? maxE(e.rma, floorV) : na
e.cPrev := c
float hh = e.closes ? c : h
float ll = e.closes ? c : l
e.conf := false
if not e.started
if not na(e.atr)
e.started := true
e.dir := 1.0
e.b0 := t
e.p0 := ll
e.atr0 := e.atr
e.pe := hh
e.be := t
e.atre := e.atr
e.deep := c
e.birth := t
else
float d = e.dir
float hi = d > 0 ? hh : -ll
float lo = d > 0 ? ll : -hh
float cl = d > 0 ? c : -c
float peU = e.pe * d
float deepU = e.deep * d
if gtE(hi, peU) // step 1, extension
peU := hi
e.be := t
e.atre := e.atr
deepU := cl
else // step 2
deepU := minE(deepU, lo)
e.pe := peU * d
e.deep := deepU * d
if geE(peU - deepU, e.k * e.atre) // step 3, at most one confirmation per bar
e.conf := true
e.cB0 := e.b0
e.cB1 := e.be
e.cP0 := e.p0
e.cP1 := e.pe
e.cDir := d
e.cA := d * (e.pe - e.p0) / e.atr0
e.cD := e.be - e.b0
e.sid := e.sid + 1
e.dir := -d
e.p0 := e.pe
e.b0 := e.be
e.atr0 := e.atre
e.pe := e.deep
e.be := t
e.atre := e.atr
e.deep := c
e.birth := t
e
method rhoC(Engine e, float c) =>
e.dir * (e.pe - c) / (e.k * e.atre)
method extent(Engine e) =>
e.dir * (e.pe - e.p0) / e.atr0
cellOf(float d, float rhoC, int g, float r) =>
float rc = minE(maxE(rhoC, 0.0), 1.0)
int ri = math.min(int(rc / 0.2), 4)
int gi = g <= 0 ? 0 : g <= 2 ? 1 : g <= 5 ? 2 : 3
int xi = ltE(r, 1.5) ? 0 : ltE(r, 2.5) ? 1 : ltE(r, 4.0) ? 2 : 3
int di = d > 0 ? 0 : 1
[di * 80 + ri * 16 + gi * 4 + xi, rc, ri]
type Book
array<float> hz // 160 cells x 5: n, sum Y_in, sum Y_N, sum Y_C, sum (Y_in - rho_c)
array<float> srt0 // sorted A of kept swings, up / down
array<float> srt1
array<float> ringA0 // ring buffers of A and D, N_MAX per direction
array<float> ringA1
array<int> ringD0
array<int> ringD1
array<int> liveT // the live swing's bars so far: bar, cell, clipped rho_c
array<int> liveC
array<float> liveR
int pos0 = 0
int pos1 = 0
int kept0 = 0
int kept1 = 0
newBook() =>
Book.new(array.new<float>(800, 0.0), array.new<float>(), array.new<float>(), array.new<float>(), array.new<float>(),
array.new<int>(), array.new<int>(), array.new<int>(), array.new<int>(), array.new<float>())
addAt(array<float> a, int i, float v) =>
array.set(a, i, array.get(a, i) + v)
countLE(array<float> s, float x) =>
int lo = 0
int hi = array.size(s)
while lo < hi
int mid = int((lo + hi) / 2)
if leE(array.get(s, mid), x)
lo := mid + 1
else
hi := mid
lo
countLT(array<float> s, float x) =>
int lo = 0
int hi = array.size(s)
while lo < hi
int mid = int((lo + hi) / 2)
if ltE(array.get(s, mid), x)
lo := mid + 1
else
hi := mid
lo
countX(array<float> s, float x, bool left) =>
int n = 0
if left
n := countLT(s, x)
else
n := countLE(s, x)
n
method insertRec(Book bk, int di, float A, int D) =>
array<float> srt = di == 0 ? bk.srt0 : bk.srt1
array<float> ra = di == 0 ? bk.ringA0 : bk.ringA1
array<int> rd = di == 0 ? bk.ringD0 : bk.ringD1
int pos = di == 0 ? bk.pos0 : bk.pos1
if array.size(ra) == N_MAX
float old = array.get(ra, pos)
array.remove(srt, countLT(srt, old))
array.set(ra, pos, A)
array.set(rd, pos, D)
else
array.push(ra, A)
array.push(rd, D)
if di == 0
bk.pos0 := (pos + 1) % N_MAX
else
bk.pos1 := (pos + 1) % N_MAX
array.insert(srt, countLE(srt, A), A)
var array<float> margR = array.new<float>(40, 0.0) // rho_c margin [dir, rho bin]: n, sum Y_N, sum Y_C, sum (Y_in - rho_c)
var array<float> baseR = array.new<float>(6, 0.0) // direction base rate [dir]: n, sum Y_N, sum Y_C
method absorb(Book bk, Engine e, int t, float c) =>
if e.started
if e.conf
int n = array.size(bk.liveT)
if e.sid - 1 >= DISCARD and n > 0
int di = e.cDir > 0 ? 0 : 1
if di == 0
bk.kept0 := bk.kept0 + 1
else
bk.kept1 := bk.kept1 + 1
for i = 0 to n - 1
int tt = array.get(bk.liveT, i)
int cc = array.get(bk.liveC, i)
float rv = array.get(bk.liveR, i)
float yin = e.cB1 <= tt ? 1.0 : 0.0
float yn = e.cB1 <= tt + HZN ? 1.0 : 0.0
float yc = t <= tt + HZN ? 1.0 : 0.0
addAt(bk.hz, cc * 5, 1.0)
addAt(bk.hz, cc * 5 + 1, yin)
addAt(bk.hz, cc * 5 + 2, yn)
addAt(bk.hz, cc * 5 + 3, yc)
addAt(bk.hz, cc * 5 + 4, yin - rv)
int rb = math.min(int(rv / 0.2), 4)
int mi = (di * 5 + rb) * 4
addAt(margR, mi, 1.0)
addAt(margR, mi + 1, yn)
addAt(margR, mi + 2, yc)
addAt(margR, mi + 3, yin - rv)
addAt(baseR, di * 3, 1.0)
addAt(baseR, di * 3 + 1, yn)
addAt(baseR, di * 3 + 2, yc)
bk.insertRec(di, e.cA, e.cD)
array.clear(bk.liveT)
array.clear(bk.liveC)
array.clear(bk.liveR)
[cell, rc, ri] = cellOf(e.dir, e.rhoC(c), t - e.be, e.extent() / e.k)
array.push(bk.liveT, t)
array.push(bk.liveC, cell)
array.push(bk.liveR, rc)
bk
subset(Book bk, int di, float a) =>
array<float> own = di == 0 ? bk.srt0 : bk.srt1
array<float> oth = di == 0 ? bk.srt1 : bk.srt0
int le = countLE(own, a)
int nOwn = array.size(own) - le
bool pooled = nOwn < N_POOL
int base = le
int n = nOwn
if pooled
int le2 = countLE(oth, a)
base := le + le2
n := nOwn + array.size(oth) - le2
[pooled, base, n]
gExcess(float x, float a, float mu, int di, Book bk, bool pr, int br, int nr, bool left) =>
float g0 = 1.0 - math.exp(-x / mu)
float g = g0
if nr > 0
float ax = a + x
int cnt = countX(di == 0 ? bk.srt0 : bk.srt1, ax, left) - br
if pr
cnt := cnt + countX(di == 0 ? bk.srt1 : bk.srt0, ax, left)
float w = nr / (nr + M_BAND)
g := w * (float(cnt) / nr) + (1.0 - w) * g0
g
gMix(float x, float p, float a, float mu, int di, Book bk, bool pr, int br, int nr) =>
p + (1.0 - p) * gExcess(x, a, mu, di, bk, pr, br, nr, false)
tagOdds(float lv, float a, float p, float mu, int di, Book bk, bool pr, int br, int nr) =>
float out = na
if not na(lv)
out := leE(lv, a) ? 1.0 : (1.0 - p) * (1.0 - gExcess(lv - a, a, mu, di, bk, pr, br, nr, true))
out
solveX(float u, float p, float a, float mu, int di, Book bk, bool pr, int br, int nr, bool warm, float xPrev) =>
float x = 0.0
if gtE(u, p)
float lo = 0.0
float hi = 1.0
int steps = FULL_STEPS
if warm
float d = DELTA
bool found = false
while not found
lo := maxE(0.0, xPrev - d)
hi := xPrev + d
if leE(gMix(lo, p, a, mu, di, bk, pr, br, nr), u) and leE(u, gMix(hi, p, a, mu, di, bk, pr, br, nr))
found := true
else
d := d * 2.0
steps := WARM_STEPS
else
while ltE(gMix(hi, p, a, mu, di, bk, pr, br, nr), u)
hi := hi * 2.0
for i = 1 to steps
float mid = 0.5 * (lo + hi)
if geE(gMix(mid, p, a, mu, di, bk, pr, br, nr), u)
hi := mid
else
lo := mid
x := 0.5 * (lo + hi)
x
windowVals(Book bk, int di, float a, int d) =>
array<float> v = array.new<float>()
for side = 0 to 1
int dd = side == 0 ? di : 1 - di
if side == 1 and array.size(v) >= N_POOL
break
array<float> ra = dd == 0 ? bk.ringA0 : bk.ringA1
array<int> rd = dd == 0 ? bk.ringD0 : bk.ringD1
int n = array.size(ra)
if n > 0
for i = 0 to n - 1
if gtE(array.get(ra, i), a) and array.get(rd, i) > d
array.push(v, float(array.get(rd, i)))
array.sort(v, order.ascending)
v
windowQ(float u, float p, float dExt, array<float> s) =>
float out = na
if leE(u, p)
out := dExt
else
int n = array.size(s)
if n > 0
float v = (u - p) / (1.0 - p)
int i = 0
while i < n and na(out)
float xq = array.get(s, i)
if geE(float(countLE(s, xq)) / n, v - 1e-12)
out := xq
i := i + 1
out
var Engine real = Engine.new(k = K, n = NATR, closes = CLOSES)
var Book bkR = newBook()
var int startBar = na
var line liveLeg = na
var line liveGlow = na
var float fCell = na
var float fPin = na
var float fPn = na
var float fPc = na
var float fLo = na
var float fHi = na
var float fDlo = na
var float fDhi = na
var float fMass = na
var float fNband = na
var float fReady = na
var int lastSid = -1
var float lastA = na
var array<float> xp = array.new<float>(3, 0.0) // warm-start chains: lo, hi, 1 - alpha
var float wLo = na
var float wHi = na
var float bDlo = na
var float bDhi = na
var float prevPn = na
var float prevPc = na
var bool stInZone = false
var bool stLikely = false
var bool stOverdue = false
var float zA = na // display band in price
var float zB = na
var float fL50 = na
var float fL75 = na
var float fL90 = na
var float fT50 = na // chance of a tag from here, per level
var float fT75 = na
var float fT90 = na
var array<float> lvPrev = array.new<float>(3, na)
var array<line> legs = array.new<line>()
var array<label> tags = array.new<label>()
var array<line> glows = array.new<line>()
var float lastHiP = na
var float lastLoP = na
var color tintCol = na
if barstate.isconfirmed and na(startBar) and time >= startTime
startBar := bar_index
if barstate.isconfirmed and not na(startBar)
int t = bar_index - startBar
real.step(t, high, low, close, 2.0 * syminfo.mintick)
bkR.absorb(real, t, close)
if real.conf
float A = real.cA
bool zoneHitBirth = not na(bDlo) and leE(bDlo, A) and leE(A, bDhi)
bool winOk = not na(wLo) and not na(wHi)
bool winHit = winOk ? leE(wLo, real.cD) and leE(real.cD, wHi) : false
if alConf and real.sid - 1 >= DISCARD
alert((real.cDir > 0 ? "Swing Exhaustion: up swing confirmed, " : "Swing Exhaustion: down swing confirmed, ") + str.tostring(A, "0.00") + " ATR. Zone at birth " + (zoneHitBirth ? "hit" : "missed") + ", window " + (winOk ? (winHit ? "hit" : "missed") : "n/a") + ".", alert.freq_once_per_bar_close)
bool isHi = real.cDir > 0
string sTag = isHi ? (na(lastHiP) or gtE(real.cP1, lastHiP) ? "HH" : "LH") : (na(lastLoP) or ltE(real.cP1, lastLoP) ? "LL" : "HL")
if isHi
lastHiP := real.cP1
else
lastLoP := real.cP1
if showTags and real.sid - 1 >= DISCARD
color tagC = sTag == "HH" or sTag == "HL" ? upCol : dnCol
array.push(tags, label.new(startBar + real.cB1, real.cP1, sTag + " · " + str.tostring(A, "0.0") + "×",
style = isHi ? label.style_label_down : label.style_label_up, color = color.new(tagC, 10), textcolor = color.black, size = size.tiny,
tooltip = (isHi ? "Up" : "Down") + " swing: " + str.tostring(A, "0.00") + " ATR in " + str.tostring(real.cD) + " bars"))
if array.size(tags) > 120
label.delete(array.shift(tags))
if real.started
float d = real.dir
int di = d > 0 ? 0 : 1
[c, rc, ri] = cellOf(d, real.rhoC(close), t - real.be, real.extent() / K)
float nb = array.get(baseR, di * 3)
float pbN = nb > 0 ? array.get(baseR, di * 3 + 1) / nb : 0.5
float pbC = nb > 0 ? array.get(baseR, di * 3 + 2) / nb : 0.5
int mi = (di * 5 + ri) * 4
float nm = array.get(margR, mi)
float pmN = (array.get(margR, mi + 1) + M_HAZ * pbN) / (nm + M_HAZ)
float pmC = (array.get(margR, mi + 2) + M_HAZ * pbC) / (nm + M_HAZ)
float resM = array.get(margR, mi + 3) / (nm + M_HAZ)
float n0 = array.get(bkR.hz, c * 5)
float pIn = minE(maxE(rc + (array.get(bkR.hz, c * 5 + 4) + M_HAZ * resM) / (n0 + M_HAZ), 0.0), 1.0)
fCell := c
fPin := pIn
fPn := (array.get(bkR.hz, c * 5 + 2) + M_HAZ * pmN) / (n0 + M_HAZ)
fPc := (array.get(bkR.hz, c * 5 + 3) + M_HAZ * pmC) / (n0 + M_HAZ)
bool ready = bkR.kept0 >= WARM and bkR.kept1 >= WARM
fReady := ready ? 1.0 : 0.0
bool birth = real.sid != lastSid
float a = real.extent()
Показано первые 50% кода (символов: 31239)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.