High/Low Support FilterPreliminary version of a long support filter for use in future strategies.
V28: Release
在脚本中搜索"high low"
eMOD.HiLoChannel [enigma_trader]High / Low Channel Indicator for the last 'Period' bars
Version: 1.0.0
Created: 2018.12.17
HIGH LOW by KIVANC fr3762Indicator plots the highest and lowest price levels in a certain period of user defined length EXCEPT LAST BAR!
the default value of bars counting back is 50 which can be optimized.
High_Low_ProjectionHigh Low Projections of daily/weekly/quarterly/yearly price movement. Dark/night mode version. Green when broken through to upside, red when broken through to bottom side.
High Low Bollinger Bands Better than Bollinger Bands for finding extreme points timed by an oscillator where the price is statistically likely to stay inside the boundaries.
Good for setting credit spreads such as call and put vertical spreads.
Futures Day-Trade Levels — RTH / ON / ADR / Pivots / VWAP / SettCME_MINI:NQ1! CME_MINI:ES1! COMEX:GC1! NYMEX:CL1!
Purpose
A compact, session-aware level map for intraday futures (e.g., ES, NQ, GC, CL). It draws the key areas day traders watch—previous session levels, today’s developing highs/lows, opening range, VWAP (+/− stdev), floor pivots, ADR projections, official settlement, plus weekly and monthly reference levels. Lines span the full chart for clean confluence reading, while minimalist right-edge tags keep the price scale readable.
What it plots
Previous Day (ETH)
- PDH / PDL / PDC from the continuous ETH daily bar.
Previous Day (RTH)
- Prior RTH High / Low / Close built from your RTH session window.
Today (RTH)
- Developing RTH High / Low and Mid.
Overnight (ON)
- Developing ON High / Low from your ON session window.
Opening Range (RTH)
- First N minutes of RTH, OR High / Low (user-selectable length).
VWAP (Day-Anchored)
- VWAP with optional ± standard-deviation bands (intraday σ computed from session start).
Floor Pivots (Daily ETH)
- PP, R1, S1, R2, S2 from the prior ETH daily H/L/C.
ADR (Average Daily Range)
- 14-day (default) ADR projections Up/Down, anchored from today’s open or yesterday’s close.
Settlement
- Prev Settle (prior official settlement; by default the daily close).
- Today Projected Settle (current ETH daily close proxy).
- Optional manual override for markets with different settlement feeds.
Weekly / Monthly
- Prior Week/Month High, Low, Close and current Week/Month Open for higher-timeframe context.
Labels & readability
Right-edge text tags (not plotted labels) identify each level without polluting the chart.
Automatic packing puts multiple tags at the same price side-by-side (no overlap).
Priority offsets keep the most important tags closest to the price scale.
Optional inline on-chart labels (off by default).
Session awareness
Fully session-aware using your chosen time zone and session templates:
RTH (e.g., 09:30–16:00 ET)
Overnight (ON) (e.g., 18:00–09:29 ET)
Performance / stability
Uses persistent lines (each level has a single line that updates) to minimize resource use and avoid “too many plots” errors.
VWAP lines are drawn with top-level plot() for Pine v6 compatibility.
Inputs (highlights)
- Sessions & Time Zone: RTH/ON windows and chart TZ.
- VWAP: on/off, σ bands, multiplier.
- Opening Range: length (minutes) and display toggle.
- Pivots / ADR / Settlement: independent toggles; ADR lookback & anchor; manual settle override.
- Weekly / Monthly: show/hide higher-TF levels.
- Style: line transparency; right-edge tag font size, base offset, and step spacing; optional inline labels.
How traders use it
- Context quickly: see where price sits relative to ON, RTH, VWAP, pivots, ADR, and settle.
- Confluence: full-width lines make reaction zones obvious when multiple levels align.
- Risk framing: OR / RTH H-L / ADR give natural stops/targets; settle often acts as a magnet.
Notes & tips
Works across futures symbols and timeframes; intended for intraday use.
“Prev Settle” follows your data provider’s daily close; use the manual override if your market uses a different official value.
If you prefer fewer tags, simply toggle features off or increase the tag step spacing.
Disclaimer
This tool is for educational purposes only and does not constitute financial advice. Trading involves risk—manage it responsibly.
Keywords: futures, ES, NQ, GC, CL, RTH, overnight, ON, opening range, VWAP, pivots, ADR, settlement, weekly high/low, monthly high/low, day trading, intraday levels.
FVG Scanner ProFVG Scanner Pro — Smart Fair Value Gap Detector (with HTF context & proximity alerts)
What it does
FVG Scanner Pro automatically finds Fair Value Gaps (FVGs) on your current chart and (optionally) on a higher timeframe (HTF), draws them as color-coded zones, and notifies you when price comes close to a gap boundary using an ADR-based proximity trigger and (optional) volume confirmation. It’s designed for ICT-style gap trading, confluence building, and clean visual execution.
How it works:
FVG definition
* Bullish FVG (gap up): low > high (the current candle’s low is above the high 2 bars ago).
* Bearish FVG (gap down): high < low (the current candle’s high is below the low 2 bars ago).
* Gaps smaller than your Min FVG Size (%) are ignored. (Gap size = (top-bottom)/bottom * 100.)
Higher-timeframe logic (auto-selected)
The script auto picks a sensible HTF:
1–5m → 15m, 15m → 1H, 1H → 4H, 4H → 1D, 1D → 1W, 1W → 1M, small 1M → 3M, big ≥3M → 12M.
You can display HTF FVGs and even filter so current-TF FVGs only show when they overlap an HTF gap.
Proximity alerts (ADR-based)
The script computes ADR on the current chart timeframe over a user-set lookback (default 20 bars).
An alert fires when price moves toward the closest actionable boundary and comes within ADR × Multiplier:
Bullish: price moving down, within distance of the bottom of a bullish FVG.
Bearish: price moving up, within distance of the top of a bearish FVG.
Yellow ▲/▼ markers show where a proximity alert triggered.
Volume filter (optional)
Require volume to be greater than SMA(20) × multiplier to accept a newly formed FVG.
Lifecycle
Each gap remains active for Extend FVG Box (Bars) bars.
You can delete the box after fill, or keep filled gaps visible as gray zones, or hide them.
Color legend
Current-TF Bullish: Pink/Magenta box
Current-TF Bearish: Cyan/Turquoise box
HTF Bullish: Gold box
HTF Bearish: Orange box
Filled (if shown): Gray box
Alert markers: Yellow ▲ (bullish), Yellow ▼ (bearish)
Inputs (what to tweak)
Show FVGs: Bullish / Bearish / Both
Max Bars Back to Find FVG: collection window & cleanup guard
Extend FVG Box (Bars): how long a zone stays tradable/active
Min FVG Size (%): ignore micro gaps
Delete Box After Fill & Show Filled FVGs: choose how you want completed gaps handled
Show Alert Markers: show/hide the yellow proximity arrows
Show Higher Timeframe FVG: overlay HTF gaps (auto TF)
HTF Filter: only display current-TF gaps that overlap an HTF gap
ADR Lookback & Proximity Multiplier: tune alert sensitivity to your market & timeframe
Volume Filter & Volume > MA Multiple: require above-average volume for new gaps
Built-in alerts (ready to use)
Create alerts in TradingView (⚠️ “Once per bar” or “Once per bar close”, your choice) and select from:
🟢 Bullish FVG Proximity — price approaching a bullish gap bottom
🔴 Bearish FVG Proximity — price approaching a bearish gap top
✅ New Bullish FVG Formed
⚠️ New Bearish FVG Formed
The alert messages include the symbol and price; proximity markers are also plotted on chart.
Tips & best practices
Use FVGs with market structure (break of structure, swing points), order blocks, or liquidity pools for confluence.
On very low timeframes, raise Min FVG Size and/or lower Max Bars Back to reduce noise and keep things fast.
Extend FVG Box controls how long a zone is considered valid; align it with your holding horizon (scalp vs swing).
Information panel (top-right)
Shows your mode, current HTF, number of gaps in memory, active bull/bear counts, and current-TF ADR.
FMFM2
// User inputs
prd = input.int(defval=30, title=' Period for Pivot Points', minval=1, maxval=50)
max_num_of_pivots = input.int(defval=6, title=' Maximum Number of Pivots', minval=5, maxval=10)
max_lines = input.int(defval=1, title=' Maximum number of trend lines', minval=1, maxval=10)
show_lines = input.bool(defval=true, title=' Show trend lines')
show_pivots = input.bool(defval=false, title=' Show Pivot Points')
sup_line_color = input(defval = color.lime, title = "Colors", inline = "tcol")
res_line_color = input(defval = color.red, title = "", inline = "tcol")
float ph = ta.pivothigh(high, prd, prd)
float pl = ta.pivotlow(low, prd, prd)
plotshape(ph and show_pivots, style=shape.triangledown, location=location.abovebar, offset=-prd, size=size.tiny)
plotshape(pl and show_pivots, style=shape.triangleup, location=location.belowbar, offset=-prd, size=size.tiny)
// Creating array of pivots
var pivots_high = array.new_float(0)
var pivots_low = array.new_float(0)
var high_ind = array.new_int(0)
var low_ind = array.new_int(0)
if ph
array.push(pivots_high, ph)
array.push(high_ind, bar_index - prd)
if array.size(pivots_high) > max_num_of_pivots // limit the array size
array.shift(pivots_high)
array.shift(high_ind)
if pl
array.push(pivots_low, pl)
array.push(low_ind, bar_index - prd)
if array.size(pivots_low) > max_num_of_pivots // limit the array size
array.shift(pivots_low)
array.shift(low_ind)
// Create arrays to store slopes and lines
var res_lines = array.new_line()
var res_slopes = array.new_float()
len_lines = array.size(res_lines)
if (len_lines >= 1)
for ind = 0 to len_lines - 1
to_delete = array.pop(res_lines)
array.pop(res_slopes)
line.delete(to_delete)
count_slope(ph1, ph2, pos1, pos2) => (ph2 - ph1) / (pos2 - pos1)
if array.size(pivots_high) == max_num_of_pivots
index_of_biggest_slope = 0
for ind1 = 0 to max_num_of_pivots - 2
for ind2 = ind1 + 1 to max_num_of_pivots - 1
p1 = array.get(pivots_high, ind1)
p2 = array.get(pivots_high, ind2)
pos1 = array.get(high_ind, ind1)
pos2 = array.get(high_ind, ind2)
k = count_slope(p1, p2, pos1, pos2)
b = p1 - k * pos1
ok = true
if ind2 - ind1 >= 1 and ok
for ind3 = ind1 + 1 to ind2 - 1
p3 = array.get(pivots_high, ind3)
pos3 = array.get(high_ind, ind3)
if p3 > k * pos3 + b
ok := false
break
pos3 = 0
p_val = p2 + k
if ok
for ind = pos2 + 1 to bar_index
if close > p_val
ok := false
break
pos3 := ind + 1
p_val += k
if ok
if array.size(res_slopes) < max_lines
line = line.new(pos1, p1, pos3, p_val, color=res_line_color)//, extend=extend.right)
array.push(res_lines, line)
array.push(res_slopes, k)
else
max_slope = array.max(res_slopes)
max_slope_ind = array.indexof(res_slopes, max_slope)
if max_lines == 1
max_slope_ind := 0
if k < max_slope
line_to_delete = array.get(res_lines, max_slope_ind)
line.delete(line_to_delete)
new_line = line.new(pos1, p1, pos3, p_val, color=res_line_color)//, extend=extend.right)
array.insert(res_lines, max_slope_ind, new_line)
array.insert(res_slopes, max_slope_ind, k)
array.remove(res_lines, max_slope_ind + 1)
array.remove(res_slopes, max_slope_ind + 1)
if not show_lines
len_l = array.size(res_lines)
if (len_l >= 1)
for ind = 0 to len_l - 1
to_delete = array.pop(res_lines)
array.pop(res_slopes)
line.delete(to_delete)
var sup_lines = array.new_line()
var sup_slopes = array.new_float()
len_lines1 = array.size(sup_lines)
if (len_lines1 >= 1)
for ind = 0 to len_lines1 - 1
to_delete = array.pop(sup_lines)
array.pop(sup_slopes)
line.delete(to_delete)
if array.size(pivots_low) == max_num_of_pivots
for ind1 = 0 to max_num_of_pivots - 2
for ind2 = ind1 + 1 to max_num_of_pivots - 1
p1 = array.get(pivots_low, ind1)
p2 = array.get(pivots_low, ind2)
pos1 = array.get(low_ind, ind1)
pos2 = array.get(low_ind, ind2)
k = count_slope(p1, p2, pos1, pos2)
b = p1 - k * pos1
ok = true
// check if pivot points in the middle of two points is lower
if ind2 - ind1 >= 1 and ok
for ind3 = ind1 + 1 to ind2 - 1
p3 = array.get(pivots_low, ind3)
pos3 = array.get(low_ind, ind3)
if p3 < k * pos3 + b
ok := false
break
pos3 = 0
p_val = p2 + k
if ok
for ind = pos2 + 1 to bar_index
if close < p_val
ok := false
break
pos3 := ind + 1
p_val += k
if ok
if array.size(sup_slopes) < max_lines
line = line.new(pos1, p1, pos3, p_val, color=sup_line_color)//, extend=extend.right)
array.push(sup_lines, line)
array.push(sup_slopes, k)
else
max_slope = array.min(sup_slopes)
max_slope_ind = array.indexof(sup_slopes, max_slope)
if max_lines == 1
max_slope_ind := 0
if k > max_slope
line_to_delete = array.get(sup_lines, max_slope_ind)
line.delete(line_to_delete)
new_line = line.new(pos1, p1, pos3, p_val, color=sup_line_color)//, extend=extend.right)
array.insert(sup_lines, max_slope_ind, new_line)
array.insert(sup_slopes, max_slope_ind, k)
array.remove(sup_lines, max_slope_ind + 1)
array.remove(sup_slopes, max_slope_ind + 1)
if not show_lines
len_l = array.size(sup_lines)
if (len_l >= 1)
for ind = 0 to len_l - 1
to_delete = array.pop(sup_lines)
array.pop(sup_slopes)
line.delete(to_delete)
plotLiq = input.bool(defval=true, title='Liquidity Highs/Lows', group='Enable/Disable Section---------------------------------------------', inline = '01')
/////////////////////////////////////////////////////////////////////////Liquidity Equal Highs
pvtTopColor = input.color(defval=color.new(color.green,85), title='Top Color', group='Liquidity-------------------------------------------------', inline='1')
pvtBtmColor = input.color(defval=color.new(color.red,85), title='Bottom Color', group='Liquidity-------------------------------------------------',inline = '1')
pvtStyle = line.style_solid
pvtMax = input.int(defval=30, title='Maximum Liquidity Displayed', minval=1, maxval=500, group='Liquidity-------------------------------------------------', tooltip='Minimum = 1, Maximum = 500')
delline = input.bool(defval=true, title='Delete After X Bars Through Line', group='Liquidity-------------------------------------------------')
mitdel = input.int(defval=15, title='Mitigated+Line Delete (X Bars)', minval=1, maxval=100, group='Liquidity-------------------------------------------------', tooltip='Line will remain on chart until this many bars after first broken through. Minimum = 1, Maximum = 500')
linebrk = input.bool(defval=true, title='Color After Close Through Line', group='Liquidity-------------------------------------------------')
mitdelcol = input.color(defval=(color.new(#34eb40,0)), title='Mitigated Color', group='Liquidity-------------------------------------------------', tooltip = 'Once broken, line will change to this colour until deleted. Line deletion is controlled by (Mitigated+Line Delete) input control')
//del_pc = input.bool(defval=false, title='', group='Liquidity-------------------------------------------------', inline="m")
//mitdel_pc = input.int(defval=300, title='Only show lines within x% of current price', minval=1, maxval=500, step=50, group='Liquidity-------------------------------------------------', inline="m")
//
brkstyle = line.style_dashed
var line _lowLiqLines = array.new_line()
var line _highLiqLines = array.new_line()
//Functions
isPvtHigh(_index, __high) =>
__high < __high and __high > __high
// | <-- pivot high
// ||| <-- candles
// 210 <-- candle index
isPvtLow(_index, __low) =>
__low > __low and __low < __low
// ||| <-- candles
// | <-- pivot low
// 210 <-- candle index
//Function to Calculte Line Length
_controlLine(_lines, __high, __low) =>
if array.size(_lines) > 0
for i = array.size(_lines) - 1 to 0 by 1
_line = array.get(_lines, i)
_lineLow = line.get_y1(_line)
_lineHigh = line.get_y2(_line)
_lineRight = line.get_x2(_line)
if na or (bar_index == _lineRight and not((__high > _lineLow and __low < _lineLow) or (__high > _lineHigh and __low < _lineHigh)))
line.set_x2(_line, bar_index + 1)
//deletes line if not within X% of current last price
//pch = (mitdel_pc/100) + 1
//pcl = 1 - (mitdel_pc/100)
//cprice = close
//highpc = (cprice * pch)
//lowpc = (cprice * pcl)
//if del_pc
//if _lineLow < close + mitdel_pc //) and > (close*0.98)) //if Y2 < close*1.05
//line.set_color(_line, color.new(color.white,50))
//line.delete(_line)
///deletes line if more than X bars pass through
if _lineRight > bar_index and _lineRight < bar_index and linebrk
line.set_color(_line,mitdelcol)
line.set_style(_line, brkstyle)
if _lineRight < bar_index and delline
line.delete(_line)
//Pivot Low Line Plotting
if isPvtLow(0, low) and plotLiq
_lowPVT = line.new(x1=bar_index - 1, y1=low , x2=bar_index, y2=low , extend=extend.none, color=pvtBtmColor, style=pvtStyle)
if array.size(_lowLiqLines) >= pvtMax
line.delete(array.shift(_lowLiqLines))
array.push(_lowLiqLines, _lowPVT)
//Pivot High Line Plotting
if isPvtHigh(0, high) and plotLiq
_highPVT = line.new(x1=bar_index - 1, y1=high , x2=bar_index, y2=high , extend=extend.none, color=pvtTopColor, style=pvtStyle)
if array.size(_highLiqLines) >= pvtMax
line.delete(array.shift(_highLiqLines))
array.push(_highLiqLines, _highPVT)
if plotLiq
_controlLine(_lowLiqLines, high, low)
_controlLine(_highLiqLines, high, low)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//@version=5
// indicator("ابو فيصل 12", overlay=true, max_labels_count=500,explicit_plot_zorder = 1000,max_lines_count = 500,max_boxes_count = 500,precision = 10)
// Control Colors
sky = color.new(color.rgb(0, 219, 255), 60)
PunkCyan = #2157f3
PunkPink = #ff1100
PunkBuy = color.new(color.rgb(0, 255, 100), 50)
PunkSell = color.new(color.rgb(255, 17, 0), 50)
// Get user settings
showBuySell = input(true, "Smart Signals", group="Smart Signals", tooltip="Confirm that the price will move strongly in the direction that the trend points")
sensitivity = 1.3
float percentStop = na
offsetSignal = 5
smooth1 = 35
smooth2 = 45
lineColor = sky
labelColor = sky
showEmas = false
srcEma1 = close
lenEma1 = 55
srcEma2 = close
lenEma2 = 200
//showSwing = input(false, "Show SFP Signals", group="SFP SIGNALS")
//prdSwing = input.int(10, "SFP Period", 2, group="SFP SIGNALS")
colorPos = input(color.new(PunkBuy, 50), "Buy Signal Color")
colorNeg = input(color.new(PunkSell, 50), "Sell Signal Color")
showDashboard = input(true, "Show Dashboard", group="TREND DASHBOARD")
locationDashboard = input.string("Top Right", "Table Location", , group="TREND DASHBOARD")
tableTextColor = input(color.white, "Table Text Color", group="TREND DASHBOARD")
tableBgColor = input(#48419f, "Table Background Color", group="TREND DASHBOARD")
sizeDashboard = input.string("Small", "Table Size", , group="TREND DASHBOARD")
// Functions
smoothrng(x, t, m) =>
wper = t * 2 - 1
avrng = ta.ema(math.abs(x - x ), t)
smoothrng = ta.ema(avrng, wper) * m
rngfilt(x, r) =>
rngfilt = x
rngfilt := x > nz(rngfilt ) ? x - r < nz(rngfilt ) ? nz(rngfilt ) : x - r : x + r > nz(rngfilt ) ? nz(rngfilt ) : x + r
percWidth(len, perc) => (ta.highest(len) - ta.lowest(len)) * perc / 100
securityNoRep(sym, res, src) => request.security(sym, res, src, barmerge.gaps_off, barmerge.lookahead_on)
swingPoints(prd) =>
pivHi = ta.pivothigh(prd, prd)
pivLo = ta.pivotlow (prd, prd)
last_pivHi = ta.valuewhen(pivHi, pivHi, 1)
last_pivLo = ta.valuewhen(pivLo, pivLo, 1)
hh = pivHi and pivHi > last_pivHi ? pivHi : na
lh = pivHi and pivHi < last_pivHi ? pivHi : na
hl = pivLo and pivLo > last_pivLo ? pivLo : na
ll = pivLo and pivLo < last_pivLo ? pivLo : na
f_chartTfInMinutes() =>
float _resInMinutes = timeframe.multiplier * (
timeframe.isseconds ? 1 :
timeframe.isminutes ? 1. :
timeframe.isdaily ? 60. * 24 :
timeframe.isweekly ? 60. * 24 * 7 :
timeframe.ismonthly ? 60. * 24 * 30.4375 : na)
f_kc(src, len, sensitivity) =>
basis = ta.sma(src, len)
span = ta.atr(len)
wavetrend(src, chlLen, avgLen) =>
esa = ta.ema(src, chlLen)
d = ta.ema(math.abs(src - esa), chlLen)
ci = (src - esa) / (0.015 * d)
wt1 = ta.ema(ci, avgLen)
wt2 = ta.sma(wt1, 3)
f_top_fractal(src) => src < src and src < src and src > src and src > src
f_bot_fractal(src) => src > src and src > src and src < src and src < src
f_fractalize (src) => f_top_fractal(src) ? 1 : f_bot_fractal(src) ? -1 : 0
f_findDivs(src, topLimit, botLimit) =>
fractalTop = f_fractalize(src) > 0 and src >= topLimit ? src : na
fractalBot = f_fractalize(src) < 0 and src <= botLimit ? src : na
highPrev = ta.valuewhen(fractalTop, src , 0)
highPrice = ta.valuewhen(fractalTop, high , 0)
lowPrev = ta.valuewhen(fractalBot, src , 0)
lowPrice = ta.valuewhen(fractalBot, low , 0)
bearSignal = fractalTop and high > highPrice and src < highPrev
bullSignal = fractalBot and low < lowPrice and src > lowPrev
// Get components
source = close
smrng1 = smoothrng(source, 27, 1.5)
smrng2 = smoothrng(source, 55, sensitivity)
smrng = (smrng1 + smrng2) / 2
filt = rngfilt(source, smrng)
up = 0.0, up := filt > filt ? nz(up ) + 1 : filt < filt ? 0 : nz(up )
dn = 0.0, dn := filt < filt ? nz(dn ) + 1 : filt > filt ? 0 : nz(dn )
bullCond = bool(na), bullCond := source > filt and source > source and up > 0 or source > filt and source < source and up > 0
bearCond = bool(na), bearCond := source < filt and source < source and dn > 0 or source < filt and source > source and dn > 0
lastCond = 0, lastCond := bullCond ? 1 : bearCond ? -1 : lastCond
bull = bullCond and lastCond == -1
bear = bearCond and lastCond == 1
countBull = ta.barssince(bull)
countBear = ta.barssince(bear)
trigger = nz(countBull, bar_index) < nz(countBear, bar_index) ? 1 : 0
rsi = ta.rsi(close, 21)
rsiOb = rsi > 70 and rsi > ta.ema(rsi, 10)
rsiOs = rsi < 30 and rsi < ta.ema(rsi, 10)
dHigh = securityNoRep(syminfo.tickerid, "D", high )
dLow = securityNoRep(syminfo.tickerid, "D", low )
dClose = securityNoRep(syminfo.tickerid, "D", close )
ema1 = ta.ema(srcEma1, lenEma1)
ema2 = ta.ema(srcEma2, lenEma2)
ema = ta.ema(close, 144)
emaBull = close > ema
equal_tf(res) => str.tonumber(res) == f_chartTfInMinutes() and not timeframe.isseconds
higher_tf(res) => str.tonumber(res) > f_chartTfInMinutes() or timeframe.isseconds
too_small_tf(res) => (timeframe.isweekly and res=="1") or (timeframe.ismonthly and str.tonumber(res) < 10)
var dashboard_loc = locationDashboard == "Top Center" ? position.top_right : locationDashboard == "Middle Right" ? position.middle_right : locationDashboard == "Bottom Right" ? position.bottom_right : locationDashboard == "Top Right" ? position.top_center : locationDashboard == "Middle Center" ? position.middle_center : locationDashboard == "Bottom Center" ? position.bottom_center : locationDashboard == "Top Left" ? position.top_left : locationDashboard == "Middle Left" ? position.middle_left : position.bottom_left
var dashboard_size = sizeDashboard == "Large" ? size.tiny : sizeDashboard == "Normal" ? size.normal : sizeDashboard == "Small" ? size.small : size.tiny
var dashboard = showDashboard ? table.new(dashboard_loc, 2, 15, tableBgColor, #000000, 2, tableBgColor, 1) : na
dashboard_cell(column, row, txt, signal=false) => table.cell(dashboard, column, row, txt, 0, 0, signal ? #000000 : tableTextColor, text_size=dashboard_size)
dashboard_cell_bg(column, row, col) => table.cell_set_bgcolor(dashboard, column, row, col)
if barstate.islast and showDashboard
dashboard_cell(0, 1 , "المتوقع")
dashboard_cell(0, 2 ," الحالي")
dashboard_cell(0, 3 , "فوليوم")
dashboard_cell(1, 1 , trigger ? "كول" : "بوت", true), dashboard_cell_bg(1, 1, trigger ? color.rgb(89, 255, 12) : color.rgb(255, 7, 7))
dashboard_cell(1, 2 , emaBull ?"كول":"بوت", true), dashboard_cell_bg(1, 2, emaBull ? color.rgb(107, 255, 8) : color.rgb(248, 11, 3))
dashboard_cell(1, 3 , str.tostring(volume))
//* BAR SETTINGS *//
paint_bars = input(false, title = "Paint bars?", group = 'Bars Settings')
catch_flat = input(false, title = "Try to catch flat?", group = 'Bars Settings')
uptrend_colour = input.color(defval = color.rgb(13, 247, 20), title = "Uptrend colour", group = 'Bars Settings')
downtrend_colour = input.color(defval = color.rgb(250, 10, 10), title = "Downtrend colour", group = 'Bars Settings')
neutraltrend_colour = input.color(defval = color.rgb(245, 252, 252), title = "Downtrend colour", tooltip = 'Note that this value is ignored if the setting to catch flat is switched off.', group = 'Bars Settings')
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* TABLE SETTINGS *//
show_header = input(false, title = "Show header?", group = 'Table Settings')
show_ema_value = input(false, title = "Show EMA value?", group = 'Table Settings')
dashboard_position = input.session("Middle right", "Position", , group = 'Table Settings')
text_size = input.session('Normal', "Size", options = , group = 'Table Settings')
text_color = input.color(defval = color.white, title = "Text colour", group = 'Table Settings')
table_color = input.color(defval = color.rgb(240, 249, 250), title = "Border colour", group = 'Table Settings')
uptrend_indicator = input("🟢", title = "Uptrend indicator", group = 'Table Settings')
downtrend_indicator = input("🔴", title = "Downtrend indicator", group = 'Table Settings')
neutraltrend_indicator = input("🟡", title = "Neutraltrend indicator", tooltip = 'Note that this value is ignored if the setting to catch flat is switched off.', group = 'Table Settings')
header_bg_color = input.color(color.rgb(18, 18, 18, 75), title = "Header background colour", group = 'Table Settings')
uptrend_bg_color = input.color(#03030340, title = "Uptrend background colour", group = 'Table Settings')
downtrend_bg_color = input(color.rgb(28, 27, 27, 75), title = "Downtrend background colour", group = 'Table Settings')
neutraltrend_bg_color = input(color.rgb(52, 52, 52, 41), title = "Neutraltrend background colour", tooltip = 'Note that this value is ignored if the setting to catch flat is switched off.', group = 'Table Settings')
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* EMA SETTINGS *//
trend_identification_approach = input.session("Direction of a single EMA", "Trend identification approach", , group = 'EMA Settings')
ema1_length = input.int(title = "EMA length", defval = 50, minval = 1, maxval = 800, group = 'EMA Settings')
ema2_length = input.int(title = "Additional EMA length", defval = 200, minval = 20, maxval = 800, tooltip = 'Note that the single EMA trend identification approach ignores this value.', group = 'EMA Settings')
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* TIMEFRAME SETTINGS *//
show_3m = input(true, title = 'Show 3m ', group = 'Timeframe Settings')
show_5m = input(true, title = 'Show 5m', group = 'Timeframe Settings')
show_15m = input(true, title = 'Show 15m', group = 'Timeframe Settings')
show_1h = input(true, title = 'Show 1h', group = 'Timeframe Settings')
show_4h = input(true, title = 'Show 4h', group = 'Timeframe Settings')
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* CALCULATION *//
var table_position = dashboard_position == 'Bottom left' ? position.top_right :
dashboard_position == 'Top left' ? position.top_left :
dashboard_position == 'Top center' ? position.top_center :
dashboard_position == 'Top right' ? position.bottom_right :
dashboard_position == 'Bottom left' ? position.bottom_left :
dashboard_position == 'Bottom right' ? position.bottom_center :
dashboard_position == 'Middle right' ? position.middle_right :
dashboard_position == 'Middle left' ? position.middle_left : position.middle_right
var table_text_size = text_size == 'Tiny' ? size.normal :
text_size == 'Large' ? size.large :
text_size == 'Normal' ? size.tiny :
text_size == 'Small' ? size.small : size.normal
var t = table.new(position = table_position,
columns = 3,
rows = 20,
frame_color = table_color,
frame_width = 2,
border_color = table_color,
border_width = 2)
calc_smma(src, len) =>
var float smma = na
smma := na(smma) ? ta.sma(src, len) : (smma * (len - 1) + src) / len
smma
calc_zlema(src, len) =>
ema1 = ta.ema(src, len)
ema2 = ta.ema(ema1, len)
d = ema1 - ema2
ema1 + d
check_impulse() =>
impulse_length = 34
impulse_strength = 9
hi = calc_smma(high, impulse_length)
lo = calc_smma(low, impulse_length)
mi = calc_zlema(hlc3, impulse_length)
md = (mi > hi) ? (mi - hi) : (mi < lo) ? (mi - lo) : 0
md_prev = (mi > hi ) ? (mi - hi ) : (mi < lo ) ? (mi - lo ) : 0
sb = ta.sma(md, impulse_strength)
sb_prev = ta.sma(md_prev, impulse_strength)
sh = md - sb
sh_prev = md_prev - sb_prev
is_impulse = sh != 0 and sh_prev != 0
is_impulse
get_trend_status() =>
impulse = catch_flat ? check_impulse() : true
ema1_current_candle = ta.ema(close, ema1_length)
ema1_previous_candle = ema1_current_candle
round = ema1_current_candle > 1000 ? 0 : ema1_current_candle > 10 ? 1 : ema1_current_candle > 0 ? 2 : ema1_current_candle > 0.1 ? 3 : 10
ema1_str = str.tostring(math.round(ema1_current_candle, round))
if (trend_identification_approach == "Direction of a single EMA")
ema1_previous_previous_candle = ema1_current_candle
trend_bg_color = not impulse ? neutraltrend_bg_color : ema1_current_candle > ema1_previous_candle ? uptrend_bg_color : ema1_current_candle < ema1_previous_candle ? downtrend_bg_color : neutraltrend_bg_color
trend_current_candle = not impulse ? neutraltrend_indicator : ema1_current_candle > ema1_previous_candle ? uptrend_indicator : ema1_current_candle < ema1_previous_candle ? downtrend_indicator : neutraltrend_indicator
trend_previous_candle = not impulse ? neutraltrend_indicator : ema1_previous_candle > ema1_previous_previous_candle ? uptrend_indicator : ema1_previous_candle < ema1_previous_previous_candle ? downtrend_indicator : neutraltrend_indicator
else
ema2_current_candle = ta.ema(close, ema2_length)
ema2_previous_candle = ema2_current_candle
trend_bg_color = not impulse ? neutraltrend_bg_color : ema1_current_candle > ema2_current_candle ? uptrend_bg_color : ema1_current_candle < ema2_current_candle ? downtrend_bg_color : neutraltrend_bg_color
trend_current_candle = not impulse ? neutraltrend_indicator : ema1_current_candle > ema2_current_candle ? uptrend_indicator : ema1_current_candle < ema2_current_candle ? downtrend_indicator : neutraltrend_indicator
trend_previous_candle = not impulse ? neutraltrend_indicator : ema1_previous_candle > ema2_previous_candle ? uptrend_indicator : ema1_previous_candle < ema2_previous_candle ? downtrend_indicator : neutraltrend_indicator
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* TABLE *//
= request.security(syminfo.tickerid, "3", get_trend_status())
= request.security(syminfo.tickerid, "5", get_trend_status())
= request.security(syminfo.tickerid, "15", get_trend_status())
= request.security(syminfo.tickerid, "60", get_trend_status())
= request.security(syminfo.tickerid, "240", get_trend_status())
if (barstate.islast)
if (show_header)
table.cell(t, 0, 0, "Timeframe", text_color = text_color, text_size = table_text_size, bgcolor = header_bg_color)
table.cell(t, 1, 0, "Trend", text_color = text_color, text_size = table_text_size, bgcolor = header_bg_color)
if (show_ema_value)
table.cell(t, 2, 0, str.tostring(ema1_length) + " EMA", text_color = text_color, text_size = table_text_size, bgcolor = header_bg_color)
if (show_3m)
table.cell(t, 0, 3, "3m", text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_3m)
table.cell(t, 1, 3, trend_indicator_3m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_3m)
if (show_ema_value)
table.cell(t, 2, 3, ema_3m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_3m)
if (show_5m)
table.cell(t, 0, 4, "5m", text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_5m)
table.cell(t, 1, 4, trend_indicator_5m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_5m)
if (show_ema_value)
table.cell(t, 2, 4, ema_5m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_5m)
if (show_15m)
table.cell(t, 0, 6, "15m", text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_15m)
table.cell(t, 1, 6, trend_indicator_15m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_15m)
if (show_ema_value)
table.cell(t, 2, 6, ema_15m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_15m)
if (show_1h)
table.cell(t, 0, 9, "1h", text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_1h)
table.cell(t, 1, 9, trend_indicator_1h, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_1h)
if (show_ema_value)
table.cell(t, 2, 9, ema_1h, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_1h)
if (show_4h)
table.cell(t, 0, 12, "4h", text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_4h)
table.cell(t, 1, 12, trend_indicator_4h, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_4h)
if (show_ema_value)
table.cell(t, 2, 12, ema_4h, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_4h)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* BARS *//
= get_trend_status()
barcolor = current_trend_indicator_current_timeframe == uptrend_indicator ? uptrend_colour : current_trend_indicator_current_timeframe == downtrend_indicator ? downtrend_colour : neutraltrend_colour
barcolor(color = barcolor, editable = false, display = paint_bars ? display.all : display.none)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* ALERTS *//
alertcondition(current_trend_indicator_current_timeframe != previous_trend_indicator_current_timeframe, '0. Trend changed', '⏰ Trend changed on {{ticker}}:{{interval}}min')
alertcondition(current_trend_indicator_current_timeframe != previous_trend_indicator_current_timeframe and current_trend_indicator_current_timeframe == uptrend_indicator, '1. Uptrend started', '🟢 Uptrend started on {{ticker}}:{{interval}}min')
alertcondition(current_trend_indicator_current_timeframe != previous_trend_indicator_current_timeframe and current_trend_indicator_current_timeframe == downtrend_indicator, '2. Downtrend started', '🔴 Downtrend started on {{ticker}}:{{interval}}min')
alertcondition(current_trend_indicator_current_timeframe != previous_trend_indicator_current_timeframe and current_trend_indicator_current_timeframe == neutraltrend_indicator, '3. Neutral trend started', '⚫️ Neutral trend started on {{ticker}}:{{interval}}min')
alertcondition(trend_indicator_4h == trend_indicator_1h and trend_indicator_1h == trend_indicator_15m, '6. 4h, 1h, 15m aligned', '4h, 1h, 15m {{ticker}} trend alignment')
alertcondition(trend_indicator_1h == trend_indicator_15m and trend_indicator_15m == trend_indicator_5m, '7. 1h, 15m, 5m aligned', '1h, 15m, 5m {{ticker}} trend alignment')
alertcondition(trend_indicator_15m == trend_indicator_5m and trend_indicator_5m == trend_indicator_3m, '8. 15m, 5m, 3m aligned', '15m, 5m, 3m {{ticker}} trend alignment')
// Constants
color CLEAR = color.rgb(0,0,0,100)
eq_threshold = input.float(0.3, '', minval = 0, maxval = 0.5, step = 0.1, group = 'Market Structure',inline = 'equilibrium_zone')
showSwing = input.bool(false, 'Swing Points', group="Market Structure",inline="3")
swingSize_swing = input.int(10, "Swing Point Period",inline="4", group="Market Structure")
label_sizes_s =input.string("Medium", options= , title="Label Size",inline="4", group="Market Structure")
label_size_buysell_s = label_sizes_s == "Small" ? size.tiny : label_sizes_s == "Medium" ? size.small : label_sizes_s == "Large" ? size.normal : label_sizes_s == "Medium2" ? size.normal : label_sizes_s == "Large2" ? size.large : size.huge
label_size_buysell = label_sizes_s == "Small" ? size.tiny : label_sizes_s == "Medium" ? size.small : label_sizes_s == "Large" ? size.normal : label_sizes_s == "Medium2" ? size.normal : label_sizes_s == "Large2" ? size.large : size.huge
swingColor = input.color(#787b86 , '', group="Market Structure",inline="3")
swingSize = 3
length_eqh = 3
//----------------------------------------}
//Key Levels
//----------------------------------------{
var Show_4H_Levels = input.bool(defval=false, title='4H', group='Key Levels', inline='4H')
Color_4H_Levels = input.color(title='', defval=color.orange, group='Key Levels', inline='4H')
Style_4H_Levels = input.string('Dotted', ' Style', , group="Key Levels",inline="4H")
Text_4H_Levels = input.bool(defval=false, title='Shorten', group='Key Levels', inline='4H')
labelsize = input.string(defval='Medium', title='Text Size', options= ,group = "Key Levels", inline='H')
var pihtext = Text_4H_Levels ? '-4H-' :'مقاومة 4'
displayStyle = 'Standard'
distanceright = 25
radistance = 250
linesize = 'Small'
linestyle = 'Solid'
var untested_monday = false
bosConfType = 'Candle High'//input.string('Candle Close', 'BOS Confirmation', , tooltip='Choose whether candle close/wick above previous swing point counts as a BOS.')
MSS = true//input.bool(false, 'Show MSS', tooltip='Renames the first counter t_MS BOS to MSS' )
// showSwing = false//input.bool(true, 'Show Swing Points', tooltip='Show or hide HH, LH, HL, LL')
// Functions
lineStyle(x) =>
switch x
'Solid' => line.style_solid
'Dashed' => line.style_dashed
'Dotted' => line.style_dotted
pivot_high_found = ta.pivothigh(high, swingSize_swing, swingSize_swing)
pivot_low_found = ta.pivotlow(low, swingSize_swing, swingSize_swing)
var float prevHigh_s = na,var float prevLow_s = na,var int prevHighIndex_s = na,var int prevLowIndex_s = na
bool higher_highs = false, bool lower_highs = false, bool higher_lows = false, bool lower_lows = false
var int prevSwing_s = 0
if not na(pivot_high_found)
if pivot_high_found >= prevHigh_s
higher_highs := true
prevSwing_s := 2
else
lower_highs := true
prevSwing_s := 1
prevHigh_s := pivot_high_found
prevHighIndex_s := bar_index - swingSize_swing
if not na(pivot_low_found)
if pivot_low_found >= prevLow_s
higher_lows := true
prevSwing_s := -1
else
lower_lows := true
prevSwing_s := -2
prevLow_s := pivot_low_found
prevLowIndex_s := bar_index - swingSize_swing
// ———————————————————— Global data {
//Using current bar data for HTF highs and lows instead of security to prevent future leaking
var htfH = open
var htfL = open
if close > htfH
htfH:= close
if close < htfL
htfL := close
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------- Key Levels
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
var monday_time = time
var monday_high = high
var monday_low = low
= request.security(syminfo.tickerid, 'W', , lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, 'W', [time , high ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, 'W', [time , low ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, 'M', , lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, 'M', [time , high ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, 'M', [time , low ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '240', [time , high ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '240', [time , low ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '3M', , lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '3M', [time , high ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '3M', [time , low ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '12M', , lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '12M', , lookahead=barmerge.lookahead_on)
if weekly_time != weekly_time
untested_monday := false
untested_monday
untested_monday := true
monday_low
linewidthint = 1
if linesize == 'Small'
linewidthint := 1
linewidthint
if linesize == 'Medium'
linewidthint := 2
linewidthint
if linesize == 'Large'
linewidthint := 3
linewidthint
var linewidth_def = linewidthint
fontsize = size.small
if labelsize == 'Small'
fontsize := size.small
fontsize
if labelsize == 'Medium'
fontsize := size.normal
fontsize
if labelsize == 'Large'
fontsize := size.large
fontsize
linestyles = line.style_solid
if linestyle == 'Dashed'
linestyles := line.style_dashed
linestyles
if linestyle == 'Dotted'
linestyles := line.style_dotted
linestyles
var DEFAULT_LABEL_SIZE = fontsize
var DEFAULT_LABEL_STYLE = label.style_none
var Rigth_Def = distanceright
var arr_price = array.new_float(0)
var arr_label = array.new_label(0)
Combine_Levels(arr_price, arr_label, currentprice, currentlabel, currentcolor) =>
if array.includes(arr_price, currentprice)
whichindex = array.indexof(arr_price, currentprice)
labelhold = array.get(arr_label, whichindex)
whichtext = label.get_text(labelhold)
label.set_text(labelhold, label.get_text(currentlabel) + ' / ' + whichtext)
label.set_text(currentlabel, '')
label.set_textcolor(labelhold, currentcolor)
else
array.push(arr_price, currentprice)
array.push(arr_label, currentlabel)
extend_to_current(bars) =>
timenow + (time - time ) * bars
if barstate.islast
arr_price := array.new_float(0)
arr_label := array.new_label(0)
if Show_4H_Levels
limit_4H_right = extend_to_current(Rigth_Def)
intrah_limit_right = extend_to_current(Rigth_Def)
intral_limit_right = extend_to_current(Rigth_Def)
var intrah_line = line.new(x1=intrah_time, x2=intrah_limit_right, y1=intrah_open, y2=intrah_open, color=Color_4H_Levels, width=linewidth_def, xloc=xloc.bar_time, style=lineStyle(Style_4H_Levels))
var intrah_label = label.new(x=intrah_limit_right, y=intrah_open, text=pihtext, style=DEFAULT_LABEL_STYLE, textcolor=Color_4H_Levels, size=DEFAULT_LABEL_SIZE, xloc=xloc.bar_time)
var intral_line = line.new(x1=intral_time, x2=intral_limit_right, y1=intral_open, y2=intral_open, color=Color_4H_Levels, width=linewidth_def, xloc=xloc.bar_time, style=lineStyle(Style_4H_Levels))
line.set_xy1(intrah_line,intrah_time,intrah_open)
line.set_xy2(intrah_line,intrah_limit_right,intrah_open)
label.set_xy(intrah_label,intrah_limit_right,intrah_open)
label.set_text(intrah_label, pihtext)
line.set_x1(intral_line, intral_time)
line.set_x2(intral_line, intral_limit_right)
line.set_y1(intral_line, intral_open)
line.set_y2(intral_line, intral_open)
Combine_Levels(arr_price, arr_label, intrah_open, intrah_label, Color_4H_Levels)
daily_limit_right = extend_to_current(Rigth_Def)
dailyh_limit_right = extend_to_current(Rigth_Def)
dailyl_limit_right = extend_to_current(Rigth_Def)
type Candle
float o
float c
float h
float l
int o_idx
int c_idx
int h_idx
int l_idx
box body
line wick_up
line wick_down
type Imbalance
box b
int idx
type CandleSettings
bool show
string htf
int max_display
type Settings
int max_sets
color bull_body
color bull_border
color bull_wick
color bear_body
color bear_border
color bear_wick
int offset
int buffer
int htf_buffer
int width
bool trace_show
color trace_o_color
string trace_o_style
int trace_o_size
color trace_c_color
string trace_c_style
int trace_c_size
color trace_h_color
string trace_h_style
int trace_h_size
color trace_l_color
string trace_l_style
int trace_l_size
string trace_anchor
bool label_show
color label_color
string label_size
bool htf_label_show
color htf_label_color
string htf_label_size
bool htf_timer_show
color htf_timer_color
string htf_timer_size
type CandleSet
Candle candles
Imbalance imbalances
CandleSettings settings
label tfName
label tfTimer
type Helper
string name = "Helper"
Settings settings = Settings.new()
var CandleSettings SettingsHTF1 = CandleSettings.new()
var CandleSettings SettingsHTF2 = CandleSettings.new()
var CandleSettings SettingsHTF3 = CandleSettings.new()
var Candle candles_1 = array.new(0)
var Candle candles_2 = array.new(0)
var Candle candles_3 = array.new(0)
var CandleSet htf1 = CandleSet.new()
htf1.settings := SettingsHTF1
htf1.candles := candles_1
var CandleSet htf2 = CandleSet.new()
htf2.settings := SettingsHTF2
htf2.candles := candles_2
var CandleSet htf3 = CandleSet.new()
htf3.settings := SettingsHTF3
htf3.candles := candles_3
//+------------------------------------------------------------------------------------------------------------+//
//+--- Settings ---+//
//+------------------------------------------------------------------------------------------------------------+//
htf1.settings.show := input.bool(true, "HTF 1 ", inline="htf1")
htf_1 = input.timeframe("15", "", inline="htf1")
htf1.settings.htf := htf_1
htf1.settings.max_display := input.int(4, "", inline="htf1")
htf2.settings.show := input.bool(true, "HTF 2 ", inline="htf2")
htf_2 = input.timeframe("60", "", inline="htf2")
htf2.settings.htf := htf_2
htf2.settings.max_display := input.int(4, "", inline="htf2")
htf3.settings.show := input.bool(true, "HTF 3 ", inline="htf3")
htf_3 = input.timeframe("1D", "", inline="htf3")
htf3.settings.htf := htf_3
htf3.settings.max_display := input.int(4, "", inline="htf3")
settings.max_sets := input.int(6, "Limit to next HTFs only", minval=1, maxval=6)
settings.bull_body := input.color(color.new(#0efd16, 3), "Body ", inline="body")
settings.bear_body := input.color(color.new(#ec0808, 0), "", inline="body")
settings.bull_border := input.color(color.rgb(159, 159, 169), "Borders", inline="borders")
settings.bear_border := input.color(color.new(#e5e9ea, 0), "", inline="borders")
settings.bull_wick := input.color(color.new(#e9eeee, 10), "Wick ", inline="wick")
settings.bear_wick := input.color(#f7f9f9, "", inline="wick")
settings.offset := input.int(25, "padding from current candles", minval = 1)
settings.buffer := input.int(1, "space between candles", minval = 1, maxval = 4)
settings.htf_buffer := input.int(10, "space between Higher Timeframes", minval = 1, maxval = 10)
settings.width := input.int(1, "Candle Width", minval = 1, maxval = 4)*2
settings.htf_label_show := input.bool(true, "HTF Label ", inline="HTFlabel")
settings.htf_label_color := input.color(color.new(color.black, 10), "", inline='HTFlabel')
settings.htf_label_size := input.string(size.large, "", , inline="HTFlabel")
//+------------------------------------------------------------------------------------------------------------+//
//+--- Variables ---+//
//+------------------------------------------------------------------------------------------------------------+//
Helper helper = Helper.new()
color color_transparent = #ffffff00
//+------------------------------------------------------------------------------------------------------------+//
//+--- Internal Functions ---+//
//+------------------------------------------------------------------------------------------------------------+//
method LineStyle(Helper helper, string style) =>
helper.name := style
out = switch style
'----' => line.style_dashed
'····' => line.style_dotted
=> line.style_solid
method ValidTimeframe(Helper helper, string HTF) =>
helper.name := HTF
if timeframe.in_seconds(HTF) >= timeframe.in_seconds("D") and timeframe.in_seconds(HTF) > timeframe.in_seconds()
true
else
n1 = timeframe.in_seconds()
n2 = timeframe.in_seconds(HTF)
n3 = n1 % n2
(n1 < n2 and math.round(n2/n1) == n2/n1)
method HTFName(Helper helper, string HTF) =>
helper.name := "HTFName"
formatted = HTF
seconds = timeframe.in_seconds(HTF)
if seconds < 60
formatted := str.tostring(seconds) + "s"
else if (seconds / 60) < 60
formatted := str.tostring((seconds/60)) + "m"
else if (seconds/60/60) < 24
formatted := str.tostring((seconds/60/60)) + "H"
formatted
method HTFEnabled(Helper helper) =>
helper.name := "HTFEnabled"
int enabled =0
enabled += htf1.settings.show ? 1 : 0
enabled += htf2.settings.show ? 1 : 0
enabled += htf3.settings.show ? 1 : 0
int last = math.min(enabled, settings.max_sets)
last
method CandleSetHigh(Helper helper, Candle candles, float h) =>
helper.name := "CandlesSetHigh"
float _h = h
if array.size(candles) > 0
for i = 0 to array.size(candles)-1
Candle c = array.get(candles, i)
if c.h > _h
_h := c.h
_h
method CandlesHigh(Helper helper, Candle candles) =>
helper.name := "CandlesHigh"
h = 0.0
int cnt = 0
int last = helper.HTFEnabled()
if htf1.settings.show and helper.ValidTimeframe(htf1.settings.htf)
h := helper.CandleSetHigh(htf1.candles, h)
cnt += 1
if htf2.settings.show and helper.ValidTimeframe(htf2.settings.htf) and cnt < last
h := helper.CandleSetHigh(htf2.candles, h)
cnt +=1
if htf3.settings.show and helper.ValidTimeframe(htf3.settings.htf) and cnt < last
h := helper.CandleSetHigh(htf3.candles, h)
cnt += 1
if array.size(candles) > 0
for i = 0 to array.size(candles)-1
Candle c = array.get(candles, i)
if c.h > h
h := c.h
h
method Reorder(CandleSet candleSet, int offset) =>
size = candleSet.candles.size()
if size > 0
for i = size-1 to 0
Candle candle = candleSet.candles.get(i)
t_buffer = offset + ((settings.width+settings.buffer)*(size-i-1))
box.set_left(candle.body, bar_index + t_buffer)
box.set_right(candle.body, bar_index + settings.width + t_buffer)
line.set_x1(candle.wick_up, bar_index+((settings.width)/2) + t_buffer)
line.set_x2(candle.wick_up, bar_index+((settings.width)/2) + t_buffer)
line.set_x1(candle.wick_down, bar_index+((settings.width)/2) + t_buffer)
line.set_x2(candle.wick_down, bar_index+((settings.width)/2) + t_buffer)
candleSet
top = helper.CandlesHigh(candleSet.candles)
left = bar_index + offset + ((settings.width+settings.buffer)*(size-1))/2
if settings.htf_label_show
var label l = candleSet.tfName
string lbl = helper.HTFName(candleSet.settings.htf)
if settings.htf_timer_show
lbl += "\n"
if not na(l)
label.set_xy(l, left, top)
else
l := label.new(left, top, lbl, color=color_transparent, textcolor = settings.htf_label_color, style=label.style_label_down, size = settings.htf_label_size)
if settings.htf_timer_show
var label t = candleSet.tfTimer
if not na(t)
label.set_xy(t, left, top)
candleSet
method FindImbalance(CandleSet candleSet) =>
if barstate.isrealtime or barstate.islast
if candleSet.imbalances.size() > 0
for i = candleSet.imbalances.size()-1 to 0
Imbalance del = candleSet.imbalances.get(i)
box.delete(del.b)
candleSet.imbalances.pop()
if candleSet.candles.size() > 3
for i = 1 to candleSet.candles.size() -3
candle1 = candleSet.candles.get(i)
candle2 = candleSet.candles.get(i+2)
candle3 = candleSet.candles.get(i+1)
method Monitor(CandleSet candleSet) =>
HTFBarTime = time(candleSet.settings.htf)
isNewHTFCandle = ta.change(HTFBarTime)
if isNewHTFCandle
Candle candle = Candle.new()
candle.o := open
candle.c := close
candle.h := high
candle.l := low
candle.o_idx := bar_index
candle.c_idx := bar_index
candle.h_idx := bar_index
candle.l_idx := bar_index
bull = candle.c > candle.o
candle.body := box.new(bar_index, math.max(candle.o, candle.c), bar_index+2, math.min(candle.o, candle.c), bull ? settings.bull_border : settings.bear_border, 1, bgcolor = bull ? settings.bull_body : settings.bear_body)
candle.wick_up := line.new(bar_index+1, candle.h, bar_index, math.max(candle.o, candle.c), color=bull ? settings.bull_wick : settings.bear_wick)
candle.wick_down := line.new(bar_index+1, math.min(candle.o, candle.c), bar_index, candle.l, color=bull ? settings.bull_wick : settings.bear_wick)
candleSet.candles.unshift(candle)
if candleSet.candles.size() > candleSet.settings.max_display
Candle delCandle = array.pop(candleSet.candles)
box.delete(delCandle.body)
line.delete(delCandle.wick_up)
line.delete(delCandle.wick_down)
candleSet
method Update(CandleSet candleSet, int offset, bool showTrace) =>
if candleSet.candles.size() > 0
Candle candle = candleSet.candles.first()
candle.h_idx := high > candle.h ? bar_index : candle.h_idx
candle.h := high > candle.h ? high : candle.h
candle.l_idx := low < candle.l ? bar_index : candle.l_idx
candle.l := low < candle.l ? low : candle.l
candle.c := close
candle.c_idx := bar_index
bull = candle.c > candle.o
box.set_top(candle.body, candle.o)
box.set_bottom(candle.body, candle.c)
box.set_bgcolor(candle.body, bull ? settings.bull_body : settings.bear_body)
box.set_border_color(candle.body, bull ? settings.bull_border : settings.bear_border)
line.set_color(candle.wick_up, bull ? settings.bull_wick : settings.bear_wick)
line.set_color(candle.wick_down, bull ? settings.bull_wick : settings.bear_wick)
line.set_y1(candle.wick_up, candle.h)
line.set_y2(candle.wick_up, math.max(candle.o, candle.c))
line.set_y1(candle.wick_down, candle.l)
line.set_y2(candle.wick_down, math.min(candle.o, candle.c))
if barstate.isrealtime or barstate.islast
candleSet.Reorder(offset)
candleSet
int cnt = 0
int last = helper.HTFEnabled()
int offset = settings.offset
if htf1.settings.show and helper.ValidTimeframe(htf1.settings.htf)
bool showTrace = false
if settings.trace_anchor == "First Timeframe"
showTrace := true
if settings.trace_anchor == "Last Timeframe" and settings.max_sets == 1
showTrace := true
htf1.Monitor().Update(offset, showTrace)
cnt +=1
offset += cnt > 0 ? (htf1.candles.size() * settings.width) + (htf1.candles.size() > 0 ? htf1.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
if htf2.settings.show and helper.ValidTimeframe(htf2.settings.htf) and cnt < last
bool showTrace = false
if settings.trace_anchor == "First Timeframe" and cnt == 0
showTrace := true
if settings.trace_anchor == "Last Timeframe" and cnt == last-1
showTrace := true
htf2.Monitor().Update(offset, showTrace)
cnt+=1
offset += cnt > 0 ? (htf2.candles.size() * settings.width) + (htf2.candles.size() > 0 ? htf2.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
if htf3.settings.show and helper.ValidTimeframe(htf3.settings.htf) and cnt < last
bool showTrace = false
if settings.trace_anchor == "First Timeframe" and cnt == 0
showTrace := true
if settings.trace_anchor == "Last Timeframe" and cnt == last-1
showTrace := true
htf3.Monitor().Update(offset, showTrace)
cnt+=1
offset += cnt > 0 ? (htf3.candles.size() * settings.width) + (htf3.candles.size() > 0 ? htf3.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
zigzagBool = input.bool(false, 'Show Market Structure', group = 'Price Action Toolkit Settings')
zigzagLen = input.int(9, 'ZigZag Length', group = 'Price Action Toolkit Settings')
liquidityBool = input.bool(true, 'Show Liquidity Sweeps', group = 'Liquidity Settings')
liquidity_len = input.int(30, 'Liquidity Length', minval = 5, group = 'Liquidity Settings')
orderblockBool = input.bool(true, 'Show Order Blocks', group = 'Order Block Settings')
numberObShow = input.int(2, 'Number of Order Blocks to Show', group = 'Order Block Settings', minval = 1, maxval = 10)
showTrendLines = input.bool(true, 'Show Trend Lines', group = 'Misc')
trendLineLength = input.int(20, 'Trend Line Detection Sensitivity', group = 'Misc', minval = 10)
upTlColor = input.color(color.new(color.teal, 15), title = 'Trend Line Colors', group = 'Misc', inline = 'tl')
downTlColor = input.color(color.new(color.red, 15), title = ' ', group = 'Misc', inline = 'tl')
upColor = input.color(color.new(#000000, 100), title = 'Market/Liquidity Colors', group = 'Visual Settings', inline = '1')
downColor = input.color(color.new(#000000, 100), title = ' ', group = 'Visual Settings', inline = '1')
bearishOrderblockColor = input.color(color.new(#e80000, 1), title = 'Order Block Colors ', group = 'Visual Settings', inline = '2')
bullishOrderblockColor = input.color(color.new(#33cb00, 0), title = ' ', group = 'Visual Settings', inline = '2')
hideWatermark = input.bool(false, title = 'Hide Watermark', group = 'Visual Settings')
type orderblock
float value
int barStart
int barEnd
box block
bool broken
type liquidity
float value
int barStart
int barEnd
line liquidityLine
bool broken
label sweep
type zone
float value
int barStart
int barEnd
box block
string zoneType
var array bullishOrderblock = array.new()
var array bearishOrderblock = array.new()
var array bullishLiquidity = array.new()
var array bearishLiquidity = array.new()
var array highValIndex = array.new()
var array lowValIndex = array.new()
var array highVal = array.new_float()
var array lowVal = array.new_float()
var bool drawUp = false
var bool drawDown = false
var string lastState = na
var bool to_up = false
var bool to_down = false
var int trend = 1
var float fibTopVal = na
var int fibTopIndex = na
var float fibBotVal = na
var int fibBotIndex = na
var float premiumVal = na
var float discountVal = na
var int premiumValIndex = na
var int discountValIndex = na
var box premiumBox = na
var box discountBox = na
var label premiumLabel = na
var label discountLabel = na
var string textOfPremium = na
var string textOfDiscount = na
var line newBearishTrendline = na
var line newBullishTrendline = na
atr = ta.atr(14)
to_up := high >= ta.highest(high, zigzagLen)
to_down := low <= ta.lowest(low, zigzagLen)
trend := trend == 1 and to_down ? -1 : trend == -1 and to_up ? 1 : trend
drawZigzag(x1, y1, x2, y2) =>
line.new(x1 = x1, y1 = y1, x2 = x2, y2 = y2, xloc = xloc.bar_time, width = 1)
if ta.change(trend) != 0 and trend == 1
array.push(highValIndex, time )
array.push(highVal, high )
if array.size(lowVal) > 1
lastLowVal = array.get(lowVal, array.size(lowVal) - 1)
lastLowIndex = array.get(lowValIndex, array.size(lowValIndex) - 1)
lastHighIndex = array.get(highValIndex, array.size(highValIndex) - 1)
lastHighVal = array.get(highVal, array.size(highVal) - 1)
if zigzagBool
drawZigzag(x1 = lastLowIndex, y1 = lastLowVal, x2 = lastHighIndex, y2 = lastHighVal)
drawUp := false
drawUp
fibTopIndex := time
fibTopVal := high
fibTopVal
if ta.change(trend) != 0 and trend == -1
array.push(lowValIndex, time )
array.push(lowVal, low )
if array.size(highVal) > 1
lastHighVal = array.get(highVal, array.size(highVal) - 1)
lastHighIndex = array.get(highValIndex, array.size(highValIndex) - 1)
lastLowIndex = array.get(lowValIndex, array.size(lowValIndex) - 1)
lastLowVal = array.get(lowVal, array.size(lowVal) - 1)
if zigzagBool
drawZigzag(x1 = lastHighIndex, y1 = lastHighVal, x2 = lastLowIndex, y2 = lastLowVal)
drawDown := false
drawDown
fibBotIndex := time
fibBotVal := low
fibBotVal
if array.size(lowVal) > 1 and drawDown == false
if close < array.get(lowVal, array.size(lowVal) - 1)
line.new(x1 = array.get(lowValIndex, array.size(lowValIndex) - 1), y1 = array.get(lowVal, array.size(lowVal) - 1), x2 = time, y2 = array.get(lowVal, array.size(lowVal) - 1), width = 1, xloc = xloc.bar_time)
label.new(x = (array.get(lowValIndex, array.size(lowValIndex) - 1) + time) / 2, y = array.get(lowVal, array.size(lowVal) - 1), text = na(lastState) or lastState == 'up' ? 'CHoCH' : 'BoS', xloc = xloc.bar_time, style = label.style_label_up, textcolor = downColor, color = color.new(color.white, 100))
drawDown := true
lastState := 'down'
if orderblockBool
orderblock newOrderblock = orderblock.new()
float max = 0
int bar = na
for i = (time - array.get(lowValIndex, array.size(lowValIndex) - 1) - (time - time )) / (time - time ) to 0 by 1
if high > max
max := high
bar := time
bar
newOrderblock.barStart := bar
newOrderblock.barEnd := time
newOrderblock.broken := false
newOrderblock.value := max
newOrderblock.block := box.new(left = newOrderblock.barStart, top = newOrderblock.value - atr, right = newOrderblock.barEnd, bottom = newOrderblock.value, xloc = xloc.bar_time, bgcolor = bearishOrderblockColor, border_width = 1, border_color = bearishOrderblockColor)
array.push(bearishOrderblock, newOrderblock)
if array.size(bearishOrderblock) > 20
array.shift(bearishOrderblock)
if array.size(highVal) > 1 and drawUp == false
if close > array.get(highVal, array.size(highVal) - 1)
line.new(x1 = array.get(highValIndex, array.size(highValIndex) - 1), y1 = array.get(highVal, array.size(highVal) - 1), x2 = time, y2 = array.get(highVal, array.size(highVal) - 1), width = 1, xloc = xloc.bar_time)
label.new(x = (array.get(highValIndex, array.size(highValIndex) - 1) + time) / 2, y = array.get(highVal, array.size(highVal) - 1), text = na(lastState) or lastState == 'down' ? 'CHoCH' : 'BoS', xloc = xloc.bar_time, style = label.style_label_down, textcolor = upColor, color = color.new(color.white, 100))
drawUp := true
lastState := 'up'
if orderblockBool
orderblock newOrderblock = orderblock.new()
float min = 999999999
int bar = na
for i = (time - array.get(highValIndex, array.size(highValIndex) - 1) - (time - time )) / (time - time ) to 0 by 1
if low < min
min := low
bar := time
bar
newOrderblock.barStart := bar
newOrderblock.barEnd := time
newOrderblock.broken := false
newOrderblock.value := min
newOrderblock.block := box.new(left = newOrderblock.barStart, top = newOrderblock.value + atr, right = newOrderblock.barEnd, bottom = newOrderblock.value, xloc = xloc.bar_time, bgcolor = bullishOrderblockColor, border_width = 1, border_color = bullishOrderblockColor)
array.push(bullishOrderblock, newOrderblock)
if array.size(bullishOrderblock) > 20
array.shift(bullishOrderblock)
// Order block
//update orderblock
if array.size(bullishOrderblock) > 0
orderblock testOrderblock = na
int counter = 0
for i = array.size(bullishOrderblock) - 1 to 0 by 1
testOrderblock := array.get(bullishOrderblock, i)
if counter < numberObShow
testOrderblock.block.set_right(time)
if close < testOrderblock.value
testOrderblock.block.delete()
array.remove(bullishOrderblock, i)
counter := counter + 1
counter
else
testOrderblock.block.set_right(testOrderblock.barStart)
if array.size(bearishOrderblock) > 0
orderblock testOrderblock = na
int counter = 0
for i = array.size(bearishOrderblock) - 1 to 0 by 1
testOrderblock := array.get(bearishOrderblock, i)
if counter < numberObShow
testOrderblock.block.set_right(time)
if close > testOrderblock.value
testOrderblock.block.delete()
array.remove(bearishOrderblock, i)
counter := counter + 1
counter
else
testOrderblock.block.set_right(testOrderblock.barStart)
// Liquidity
phLiquidity = ta.pivothigh(high, liquidity_len, liquidity_len)
plLiquidity = ta.pivotlow(low, liquidity_len, liquidity_len)
if not na(phLiquidity) and liquidityBool
liquidity newLiquidity = liquidity.new()
newLiquidity.value := high
newLiquidity.barStart := time
newLiquidity.barEnd := time
newLiquidity.broken := false
newLiquidity.liquidityLine := line.new(x1 = newLiquidity.barStart, y1 = newLiquidity.value, x2 = newLiquidity.barEnd, y2 = newLiquidity.value, xloc = xloc.bar_time, color = downColor, width = 1)
array.push(bearishLiquidity, newLiquidity)
if array.size(bearishLiquidity) > 7
deletedLiquidity = array.shift(bearishLiquidity)
deletedLiquidity.liquidityLine.delete()
if not na(plLiquidity) and liquidityBool
liquidity newLiquidity = liquidity.new()
newLiquidity.value := low
newLiquidity.barStart := time
newLiquidity.barEnd := time
newLiquidity.broken := false
newLiquidity.liquidityLine := line.new(x1 = newLiquidity.barStart, y1 = newLiquidity.value, x2 = newLiquidity.barEnd, y2 = newLiquidity.value, xloc = xloc.bar_time, color = upColor, width = 1)
array.push(bullishLiquidity, newLiquidity)
if array.size(bullishLiquidity) > 7
deletedLiquidity = array.shift(bullishLiquidity)
deletedLiquidity.liquidityLine.delete()
// Update liquidity
if array.size(bearishLiquidity) > 0
liquidity testLiquidity = na
for i = array.size(bearishLiquidity) - 1 to 0 by 1
testLiquidity := array.get(bearishLiquidity, i)
if high > testLiquidity.value
testLiquidity.liquidityLine.set_x2(time)
testLiquidity.liquidityLine.set_style(line.style_dashed)
array.remove(bearishLiquidity, i)
if close < testLiquidity.value
testLiquidity.sweep := label.new(x = time, y = high, text = 'x', xloc = xloc.bar_time, style = label.style_label_down, size = size.normal, textcolor = color.new(#e8e8e8, 0), color = color.new(color.white, 100))
testLiquidity.sweep
else
testLiquidity.liquidityLine.set_x2(time)
if array.size(bullishLiquidity) > 0
liquidity testLiquidity = na
for i = array.size(bullishLiquidity) - 1 to 0 by 1
testLiquidity := array.get(bullishLiquidity, i)
if low < testLiquidity.value
testLiquidity.liquidityLine.set_x2(time)
testLiquidity.liquidityLine.set_style(line.style_dashed)
array.remove(bullishLiquidity, i)
if close > testLiquidity.value
testLiquidity.sweep := label.new(x = time, y = low, text = 'x', xloc = xloc.bar_time, style = label.style_label_up, size = size.normal, textcolor = color.new(#e2e2e2, 0), color = color.new(color.white, 100))
testLiquidity.sweep
else
testLiquidity.liquidityLine.set_x2(time)
Fmfm30
// User inputs
prd = input.int(defval=30, title=' Period for Pivot Points', minval=1, maxval=50)
max_num_of_pivots = input.int(defval=6, title=' Maximum Number of Pivots', minval=5, maxval=10)
max_lines = input.int(defval=1, title=' Maximum number of trend lines', minval=1, maxval=10)
show_lines = input.bool(defval=true, title=' Show trend lines')
show_pivots = input.bool(defval=false, title=' Show Pivot Points')
sup_line_color = input(defval = color.lime, title = "Colors", inline = "tcol")
res_line_color = input(defval = color.red, title = "", inline = "tcol")
float ph = ta.pivothigh(high, prd, prd)
float pl = ta.pivotlow(low, prd, prd)
plotshape(ph and show_pivots, style=shape.triangledown, location=location.abovebar, offset=-prd, size=size.tiny)
plotshape(pl and show_pivots, style=shape.triangleup, location=location.belowbar, offset=-prd, size=size.tiny)
// Creating array of pivots
var pivots_high = array.new_float(0)
var pivots_low = array.new_float(0)
var high_ind = array.new_int(0)
var low_ind = array.new_int(0)
if ph
array.push(pivots_high, ph)
array.push(high_ind, bar_index - prd)
if array.size(pivots_high) > max_num_of_pivots // limit the array size
array.shift(pivots_high)
array.shift(high_ind)
if pl
array.push(pivots_low, pl)
array.push(low_ind, bar_index - prd)
if array.size(pivots_low) > max_num_of_pivots // limit the array size
array.shift(pivots_low)
array.shift(low_ind)
// Create arrays to store slopes and lines
var res_lines = array.new_line()
var res_slopes = array.new_float()
len_lines = array.size(res_lines)
if (len_lines >= 1)
for ind = 0 to len_lines - 1
to_delete = array.pop(res_lines)
array.pop(res_slopes)
line.delete(to_delete)
count_slope(ph1, ph2, pos1, pos2) => (ph2 - ph1) / (pos2 - pos1)
if array.size(pivots_high) == max_num_of_pivots
index_of_biggest_slope = 0
for ind1 = 0 to max_num_of_pivots - 2
for ind2 = ind1 + 1 to max_num_of_pivots - 1
p1 = array.get(pivots_high, ind1)
p2 = array.get(pivots_high, ind2)
pos1 = array.get(high_ind, ind1)
pos2 = array.get(high_ind, ind2)
k = count_slope(p1, p2, pos1, pos2)
b = p1 - k * pos1
ok = true
if ind2 - ind1 >= 1 and ok
for ind3 = ind1 + 1 to ind2 - 1
p3 = array.get(pivots_high, ind3)
pos3 = array.get(high_ind, ind3)
if p3 > k * pos3 + b
ok := false
break
pos3 = 0
p_val = p2 + k
if ok
for ind = pos2 + 1 to bar_index
if close > p_val
ok := false
break
pos3 := ind + 1
p_val += k
if ok
if array.size(res_slopes) < max_lines
line = line.new(pos1, p1, pos3, p_val, color=res_line_color)//, extend=extend.right)
array.push(res_lines, line)
array.push(res_slopes, k)
else
max_slope = array.max(res_slopes)
max_slope_ind = array.indexof(res_slopes, max_slope)
if max_lines == 1
max_slope_ind := 0
if k < max_slope
line_to_delete = array.get(res_lines, max_slope_ind)
line.delete(line_to_delete)
new_line = line.new(pos1, p1, pos3, p_val, color=res_line_color)//, extend=extend.right)
array.insert(res_lines, max_slope_ind, new_line)
array.insert(res_slopes, max_slope_ind, k)
array.remove(res_lines, max_slope_ind + 1)
array.remove(res_slopes, max_slope_ind + 1)
if not show_lines
len_l = array.size(res_lines)
if (len_l >= 1)
for ind = 0 to len_l - 1
to_delete = array.pop(res_lines)
array.pop(res_slopes)
line.delete(to_delete)
var sup_lines = array.new_line()
var sup_slopes = array.new_float()
len_lines1 = array.size(sup_lines)
if (len_lines1 >= 1)
for ind = 0 to len_lines1 - 1
to_delete = array.pop(sup_lines)
array.pop(sup_slopes)
line.delete(to_delete)
if array.size(pivots_low) == max_num_of_pivots
for ind1 = 0 to max_num_of_pivots - 2
for ind2 = ind1 + 1 to max_num_of_pivots - 1
p1 = array.get(pivots_low, ind1)
p2 = array.get(pivots_low, ind2)
pos1 = array.get(low_ind, ind1)
pos2 = array.get(low_ind, ind2)
k = count_slope(p1, p2, pos1, pos2)
b = p1 - k * pos1
ok = true
// check if pivot points in the middle of two points is lower
if ind2 - ind1 >= 1 and ok
for ind3 = ind1 + 1 to ind2 - 1
p3 = array.get(pivots_low, ind3)
pos3 = array.get(low_ind, ind3)
if p3 < k * pos3 + b
ok := false
break
pos3 = 0
p_val = p2 + k
if ok
for ind = pos2 + 1 to bar_index
if close < p_val
ok := false
break
pos3 := ind + 1
p_val += k
if ok
if array.size(sup_slopes) < max_lines
line = line.new(pos1, p1, pos3, p_val, color=sup_line_color)//, extend=extend.right)
array.push(sup_lines, line)
array.push(sup_slopes, k)
else
max_slope = array.min(sup_slopes)
max_slope_ind = array.indexof(sup_slopes, max_slope)
if max_lines == 1
max_slope_ind := 0
if k > max_slope
line_to_delete = array.get(sup_lines, max_slope_ind)
line.delete(line_to_delete)
new_line = line.new(pos1, p1, pos3, p_val, color=sup_line_color)//, extend=extend.right)
array.insert(sup_lines, max_slope_ind, new_line)
array.insert(sup_slopes, max_slope_ind, k)
array.remove(sup_lines, max_slope_ind + 1)
array.remove(sup_slopes, max_slope_ind + 1)
if not show_lines
len_l = array.size(sup_lines)
if (len_l >= 1)
for ind = 0 to len_l - 1
to_delete = array.pop(sup_lines)
array.pop(sup_slopes)
line.delete(to_delete)
plotLiq = input.bool(defval=true, title='Liquidity Highs/Lows', group='Enable/Disable Section---------------------------------------------', inline = '01')
/////////////////////////////////////////////////////////////////////////Liquidity Equal Highs
pvtTopColor = input.color(defval=color.new(color.green,85), title='Top Color', group='Liquidity-------------------------------------------------', inline='1')
pvtBtmColor = input.color(defval=color.new(color.red,85), title='Bottom Color', group='Liquidity-------------------------------------------------',inline = '1')
pvtStyle = line.style_solid
pvtMax = input.int(defval=30, title='Maximum Liquidity Displayed', minval=1, maxval=500, group='Liquidity-------------------------------------------------', tooltip='Minimum = 1, Maximum = 500')
delline = input.bool(defval=true, title='Delete After X Bars Through Line', group='Liquidity-------------------------------------------------')
mitdel = input.int(defval=15, title='Mitigated+Line Delete (X Bars)', minval=1, maxval=100, group='Liquidity-------------------------------------------------', tooltip='Line will remain on chart until this many bars after first broken through. Minimum = 1, Maximum = 500')
linebrk = input.bool(defval=true, title='Color After Close Through Line', group='Liquidity-------------------------------------------------')
mitdelcol = input.color(defval=(color.new(#34eb40,0)), title='Mitigated Color', group='Liquidity-------------------------------------------------', tooltip = 'Once broken, line will change to this colour until deleted. Line deletion is controlled by (Mitigated+Line Delete) input control')
//del_pc = input.bool(defval=false, title='', group='Liquidity-------------------------------------------------', inline="m")
//mitdel_pc = input.int(defval=300, title='Only show lines within x% of current price', minval=1, maxval=500, step=50, group='Liquidity-------------------------------------------------', inline="m")
//
brkstyle = line.style_dashed
var line _lowLiqLines = array.new_line()
var line _highLiqLines = array.new_line()
//Functions
isPvtHigh(_index, __high) =>
__high < __high and __high > __high
// | <-- pivot high
// ||| <-- candles
// 210 <-- candle index
isPvtLow(_index, __low) =>
__low > __low and __low < __low
// ||| <-- candles
// | <-- pivot low
// 210 <-- candle index
//Function to Calculte Line Length
_controlLine(_lines, __high, __low) =>
if array.size(_lines) > 0
for i = array.size(_lines) - 1 to 0 by 1
_line = array.get(_lines, i)
_lineLow = line.get_y1(_line)
_lineHigh = line.get_y2(_line)
_lineRight = line.get_x2(_line)
if na or (bar_index == _lineRight and not((__high > _lineLow and __low < _lineLow) or (__high > _lineHigh and __low < _lineHigh)))
line.set_x2(_line, bar_index + 1)
//deletes line if not within X% of current last price
//pch = (mitdel_pc/100) + 1
//pcl = 1 - (mitdel_pc/100)
//cprice = close
//highpc = (cprice * pch)
//lowpc = (cprice * pcl)
//if del_pc
//if _lineLow < close + mitdel_pc //) and > (close*0.98)) //if Y2 < close*1.05
//line.set_color(_line, color.new(color.white,50))
//line.delete(_line)
///deletes line if more than X bars pass through
if _lineRight > bar_index and _lineRight < bar_index and linebrk
line.set_color(_line,mitdelcol)
line.set_style(_line, brkstyle)
if _lineRight < bar_index and delline
line.delete(_line)
//Pivot Low Line Plotting
if isPvtLow(0, low) and plotLiq
_lowPVT = line.new(x1=bar_index - 1, y1=low , x2=bar_index, y2=low , extend=extend.none, color=pvtBtmColor, style=pvtStyle)
if array.size(_lowLiqLines) >= pvtMax
line.delete(array.shift(_lowLiqLines))
array.push(_lowLiqLines, _lowPVT)
//Pivot High Line Plotting
if isPvtHigh(0, high) and plotLiq
_highPVT = line.new(x1=bar_index - 1, y1=high , x2=bar_index, y2=high , extend=extend.none, color=pvtTopColor, style=pvtStyle)
if array.size(_highLiqLines) >= pvtMax
line.delete(array.shift(_highLiqLines))
array.push(_highLiqLines, _highPVT)
if plotLiq
_controlLine(_lowLiqLines, high, low)
_controlLine(_highLiqLines, high, low)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//@version=5
// indicator("ابو فيصل 12", overlay=true, max_labels_count=500,explicit_plot_zorder = 1000,max_lines_count = 500,max_boxes_count = 500,precision = 10)
// Control Colors
sky = color.new(color.rgb(0, 219, 255), 60)
PunkCyan = #2157f3
PunkPink = #ff1100
PunkBuy = color.new(color.rgb(0, 255, 100), 50)
PunkSell = color.new(color.rgb(255, 17, 0), 50)
// Get user settings
showBuySell = input(true, "Smart Signals", group="Smart Signals", tooltip="Confirm that the price will move strongly in the direction that the trend points")
sensitivity = 1.3
float percentStop = na
offsetSignal = 5
smooth1 = 35
smooth2 = 45
lineColor = sky
labelColor = sky
showEmas = false
srcEma1 = close
lenEma1 = 55
srcEma2 = close
lenEma2 = 200
//showSwing = input(false, "Show SFP Signals", group="SFP SIGNALS")
//prdSwing = input.int(10, "SFP Period", 2, group="SFP SIGNALS")
colorPos = input(color.new(PunkBuy, 50), "Buy Signal Color")
colorNeg = input(color.new(PunkSell, 50), "Sell Signal Color")
showDashboard = input(true, "Show Dashboard", group="TREND DASHBOARD")
locationDashboard = input.string("Top Right", "Table Location", , group="TREND DASHBOARD")
tableTextColor = input(color.white, "Table Text Color", group="TREND DASHBOARD")
tableBgColor = input(#48419f, "Table Background Color", group="TREND DASHBOARD")
sizeDashboard = input.string("Small", "Table Size", , group="TREND DASHBOARD")
// Functions
smoothrng(x, t, m) =>
wper = t * 2 - 1
avrng = ta.ema(math.abs(x - x ), t)
smoothrng = ta.ema(avrng, wper) * m
rngfilt(x, r) =>
rngfilt = x
rngfilt := x > nz(rngfilt ) ? x - r < nz(rngfilt ) ? nz(rngfilt ) : x - r : x + r > nz(rngfilt ) ? nz(rngfilt ) : x + r
percWidth(len, perc) => (ta.highest(len) - ta.lowest(len)) * perc / 100
securityNoRep(sym, res, src) => request.security(sym, res, src, barmerge.gaps_off, barmerge.lookahead_on)
swingPoints(prd) =>
pivHi = ta.pivothigh(prd, prd)
pivLo = ta.pivotlow (prd, prd)
last_pivHi = ta.valuewhen(pivHi, pivHi, 1)
last_pivLo = ta.valuewhen(pivLo, pivLo, 1)
hh = pivHi and pivHi > last_pivHi ? pivHi : na
lh = pivHi and pivHi < last_pivHi ? pivHi : na
hl = pivLo and pivLo > last_pivLo ? pivLo : na
ll = pivLo and pivLo < last_pivLo ? pivLo : na
f_chartTfInMinutes() =>
float _resInMinutes = timeframe.multiplier * (
timeframe.isseconds ? 1 :
timeframe.isminutes ? 1. :
timeframe.isdaily ? 60. * 24 :
timeframe.isweekly ? 60. * 24 * 7 :
timeframe.ismonthly ? 60. * 24 * 30.4375 : na)
f_kc(src, len, sensitivity) =>
basis = ta.sma(src, len)
span = ta.atr(len)
wavetrend(src, chlLen, avgLen) =>
esa = ta.ema(src, chlLen)
d = ta.ema(math.abs(src - esa), chlLen)
ci = (src - esa) / (0.015 * d)
wt1 = ta.ema(ci, avgLen)
wt2 = ta.sma(wt1, 3)
f_top_fractal(src) => src < src and src < src and src > src and src > src
f_bot_fractal(src) => src > src and src > src and src < src and src < src
f_fractalize (src) => f_top_fractal(src) ? 1 : f_bot_fractal(src) ? -1 : 0
f_findDivs(src, topLimit, botLimit) =>
fractalTop = f_fractalize(src) > 0 and src >= topLimit ? src : na
fractalBot = f_fractalize(src) < 0 and src <= botLimit ? src : na
highPrev = ta.valuewhen(fractalTop, src , 0)
highPrice = ta.valuewhen(fractalTop, high , 0)
lowPrev = ta.valuewhen(fractalBot, src , 0)
lowPrice = ta.valuewhen(fractalBot, low , 0)
bearSignal = fractalTop and high > highPrice and src < highPrev
bullSignal = fractalBot and low < lowPrice and src > lowPrev
// Get components
source = close
smrng1 = smoothrng(source, 27, 1.5)
smrng2 = smoothrng(source, 55, sensitivity)
smrng = (smrng1 + smrng2) / 2
filt = rngfilt(source, smrng)
up = 0.0, up := filt > filt ? nz(up ) + 1 : filt < filt ? 0 : nz(up )
dn = 0.0, dn := filt < filt ? nz(dn ) + 1 : filt > filt ? 0 : nz(dn )
bullCond = bool(na), bullCond := source > filt and source > source and up > 0 or source > filt and source < source and up > 0
bearCond = bool(na), bearCond := source < filt and source < source and dn > 0 or source < filt and source > source and dn > 0
lastCond = 0, lastCond := bullCond ? 1 : bearCond ? -1 : lastCond
bull = bullCond and lastCond == -1
bear = bearCond and lastCond == 1
countBull = ta.barssince(bull)
countBear = ta.barssince(bear)
trigger = nz(countBull, bar_index) < nz(countBear, bar_index) ? 1 : 0
rsi = ta.rsi(close, 21)
rsiOb = rsi > 70 and rsi > ta.ema(rsi, 10)
rsiOs = rsi < 30 and rsi < ta.ema(rsi, 10)
dHigh = securityNoRep(syminfo.tickerid, "D", high )
dLow = securityNoRep(syminfo.tickerid, "D", low )
dClose = securityNoRep(syminfo.tickerid, "D", close )
ema1 = ta.ema(srcEma1, lenEma1)
ema2 = ta.ema(srcEma2, lenEma2)
ema = ta.ema(close, 144)
emaBull = close > ema
equal_tf(res) => str.tonumber(res) == f_chartTfInMinutes() and not timeframe.isseconds
higher_tf(res) => str.tonumber(res) > f_chartTfInMinutes() or timeframe.isseconds
too_small_tf(res) => (timeframe.isweekly and res=="1") or (timeframe.ismonthly and str.tonumber(res) < 10)
var dashboard_loc = locationDashboard == "Top Center" ? position.top_right : locationDashboard == "Middle Right" ? position.middle_right : locationDashboard == "Bottom Right" ? position.bottom_right : locationDashboard == "Top Right" ? position.top_center : locationDashboard == "Middle Center" ? position.middle_center : locationDashboard == "Bottom Center" ? position.bottom_center : locationDashboard == "Top Left" ? position.top_left : locationDashboard == "Middle Left" ? position.middle_left : position.bottom_left
var dashboard_size = sizeDashboard == "Large" ? size.tiny : sizeDashboard == "Normal" ? size.normal : sizeDashboard == "Small" ? size.small : size.tiny
var dashboard = showDashboard ? table.new(dashboard_loc, 2, 15, tableBgColor, #000000, 2, tableBgColor, 1) : na
dashboard_cell(column, row, txt, signal=false) => table.cell(dashboard, column, row, txt, 0, 0, signal ? #000000 : tableTextColor, text_size=dashboard_size)
dashboard_cell_bg(column, row, col) => table.cell_set_bgcolor(dashboard, column, row, col)
if barstate.islast and showDashboard
dashboard_cell(0, 1 , "المتوقع")
dashboard_cell(0, 2 ," الحالي")
dashboard_cell(0, 3 , "فوليوم")
dashboard_cell(1, 1 , trigger ? "كول" : "بوت", true), dashboard_cell_bg(1, 1, trigger ? color.rgb(89, 255, 12) : color.rgb(255, 7, 7))
dashboard_cell(1, 2 , emaBull ?"كول":"بوت", true), dashboard_cell_bg(1, 2, emaBull ? color.rgb(107, 255, 8) : color.rgb(248, 11, 3))
dashboard_cell(1, 3 , str.tostring(volume))
//* BAR SETTINGS *//
paint_bars = input(false, title = "Paint bars?", group = 'Bars Settings')
catch_flat = input(false, title = "Try to catch flat?", group = 'Bars Settings')
uptrend_colour = input.color(defval = color.rgb(13, 247, 20), title = "Uptrend colour", group = 'Bars Settings')
downtrend_colour = input.color(defval = color.rgb(250, 10, 10), title = "Downtrend colour", group = 'Bars Settings')
neutraltrend_colour = input.color(defval = color.rgb(245, 252, 252), title = "Downtrend colour", tooltip = 'Note that this value is ignored if the setting to catch flat is switched off.', group = 'Bars Settings')
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* TABLE SETTINGS *//
show_header = input(false, title = "Show header?", group = 'Table Settings')
show_ema_value = input(false, title = "Show EMA value?", group = 'Table Settings')
dashboard_position = input.session("Middle right", "Position", , group = 'Table Settings')
text_size = input.session('Normal', "Size", options = , group = 'Table Settings')
text_color = input.color(defval = color.white, title = "Text colour", group = 'Table Settings')
table_color = input.color(defval = color.rgb(240, 249, 250), title = "Border colour", group = 'Table Settings')
uptrend_indicator = input("🟢", title = "Uptrend indicator", group = 'Table Settings')
downtrend_indicator = input("🔴", title = "Downtrend indicator", group = 'Table Settings')
neutraltrend_indicator = input("🟡", title = "Neutraltrend indicator", tooltip = 'Note that this value is ignored if the setting to catch flat is switched off.', group = 'Table Settings')
header_bg_color = input.color(color.rgb(18, 18, 18, 75), title = "Header background colour", group = 'Table Settings')
uptrend_bg_color = input.color(#03030340, title = "Uptrend background colour", group = 'Table Settings')
downtrend_bg_color = input(color.rgb(28, 27, 27, 75), title = "Downtrend background colour", group = 'Table Settings')
neutraltrend_bg_color = input(color.rgb(52, 52, 52, 41), title = "Neutraltrend background colour", tooltip = 'Note that this value is ignored if the setting to catch flat is switched off.', group = 'Table Settings')
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* EMA SETTINGS *//
trend_identification_approach = input.session("Direction of a single EMA", "Trend identification approach", , group = 'EMA Settings')
ema1_length = input.int(title = "EMA length", defval = 50, minval = 1, maxval = 800, group = 'EMA Settings')
ema2_length = input.int(title = "Additional EMA length", defval = 200, minval = 20, maxval = 800, tooltip = 'Note that the single EMA trend identification approach ignores this value.', group = 'EMA Settings')
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* TIMEFRAME SETTINGS *//
show_3m = input(true, title = 'Show 3m ', group = 'Timeframe Settings')
show_5m = input(true, title = 'Show 5m', group = 'Timeframe Settings')
show_15m = input(true, title = 'Show 15m', group = 'Timeframe Settings')
show_1h = input(true, title = 'Show 1h', group = 'Timeframe Settings')
show_4h = input(true, title = 'Show 4h', group = 'Timeframe Settings')
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* CALCULATION *//
var table_position = dashboard_position == 'Bottom left' ? position.top_right :
dashboard_position == 'Top left' ? position.top_left :
dashboard_position == 'Top center' ? position.top_center :
dashboard_position == 'Top right' ? position.bottom_right :
dashboard_position == 'Bottom left' ? position.bottom_left :
dashboard_position == 'Bottom right' ? position.bottom_center :
dashboard_position == 'Middle right' ? position.middle_right :
dashboard_position == 'Middle left' ? position.middle_left : position.middle_right
var table_text_size = text_size == 'Tiny' ? size.normal :
text_size == 'Large' ? size.large :
text_size == 'Normal' ? size.tiny :
text_size == 'Small' ? size.small : size.normal
var t = table.new(position = table_position,
columns = 3,
rows = 20,
frame_color = table_color,
frame_width = 2,
border_color = table_color,
border_width = 2)
calc_smma(src, len) =>
var float smma = na
smma := na(smma) ? ta.sma(src, len) : (smma * (len - 1) + src) / len
smma
calc_zlema(src, len) =>
ema1 = ta.ema(src, len)
ema2 = ta.ema(ema1, len)
d = ema1 - ema2
ema1 + d
check_impulse() =>
impulse_length = 34
impulse_strength = 9
hi = calc_smma(high, impulse_length)
lo = calc_smma(low, impulse_length)
mi = calc_zlema(hlc3, impulse_length)
md = (mi > hi) ? (mi - hi) : (mi < lo) ? (mi - lo) : 0
md_prev = (mi > hi ) ? (mi - hi ) : (mi < lo ) ? (mi - lo ) : 0
sb = ta.sma(md, impulse_strength)
sb_prev = ta.sma(md_prev, impulse_strength)
sh = md - sb
sh_prev = md_prev - sb_prev
is_impulse = sh != 0 and sh_prev != 0
is_impulse
get_trend_status() =>
impulse = catch_flat ? check_impulse() : true
ema1_current_candle = ta.ema(close, ema1_length)
ema1_previous_candle = ema1_current_candle
round = ema1_current_candle > 1000 ? 0 : ema1_current_candle > 10 ? 1 : ema1_current_candle > 0 ? 2 : ema1_current_candle > 0.1 ? 3 : 10
ema1_str = str.tostring(math.round(ema1_current_candle, round))
if (trend_identification_approach == "Direction of a single EMA")
ema1_previous_previous_candle = ema1_current_candle
trend_bg_color = not impulse ? neutraltrend_bg_color : ema1_current_candle > ema1_previous_candle ? uptrend_bg_color : ema1_current_candle < ema1_previous_candle ? downtrend_bg_color : neutraltrend_bg_color
trend_current_candle = not impulse ? neutraltrend_indicator : ema1_current_candle > ema1_previous_candle ? uptrend_indicator : ema1_current_candle < ema1_previous_candle ? downtrend_indicator : neutraltrend_indicator
trend_previous_candle = not impulse ? neutraltrend_indicator : ema1_previous_candle > ema1_previous_previous_candle ? uptrend_indicator : ema1_previous_candle < ema1_previous_previous_candle ? downtrend_indicator : neutraltrend_indicator
else
ema2_current_candle = ta.ema(close, ema2_length)
ema2_previous_candle = ema2_current_candle
trend_bg_color = not impulse ? neutraltrend_bg_color : ema1_current_candle > ema2_current_candle ? uptrend_bg_color : ema1_current_candle < ema2_current_candle ? downtrend_bg_color : neutraltrend_bg_color
trend_current_candle = not impulse ? neutraltrend_indicator : ema1_current_candle > ema2_current_candle ? uptrend_indicator : ema1_current_candle < ema2_current_candle ? downtrend_indicator : neutraltrend_indicator
trend_previous_candle = not impulse ? neutraltrend_indicator : ema1_previous_candle > ema2_previous_candle ? uptrend_indicator : ema1_previous_candle < ema2_previous_candle ? downtrend_indicator : neutraltrend_indicator
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* TABLE *//
= request.security(syminfo.tickerid, "3", get_trend_status())
= request.security(syminfo.tickerid, "5", get_trend_status())
= request.security(syminfo.tickerid, "15", get_trend_status())
= request.security(syminfo.tickerid, "60", get_trend_status())
= request.security(syminfo.tickerid, "240", get_trend_status())
if (barstate.islast)
if (show_header)
table.cell(t, 0, 0, "Timeframe", text_color = text_color, text_size = table_text_size, bgcolor = header_bg_color)
table.cell(t, 1, 0, "Trend", text_color = text_color, text_size = table_text_size, bgcolor = header_bg_color)
if (show_ema_value)
table.cell(t, 2, 0, str.tostring(ema1_length) + " EMA", text_color = text_color, text_size = table_text_size, bgcolor = header_bg_color)
if (show_3m)
table.cell(t, 0, 3, "3m", text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_3m)
table.cell(t, 1, 3, trend_indicator_3m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_3m)
if (show_ema_value)
table.cell(t, 2, 3, ema_3m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_3m)
if (show_5m)
table.cell(t, 0, 4, "5m", text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_5m)
table.cell(t, 1, 4, trend_indicator_5m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_5m)
if (show_ema_value)
table.cell(t, 2, 4, ema_5m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_5m)
if (show_15m)
table.cell(t, 0, 6, "15m", text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_15m)
table.cell(t, 1, 6, trend_indicator_15m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_15m)
if (show_ema_value)
table.cell(t, 2, 6, ema_15m, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_15m)
if (show_1h)
table.cell(t, 0, 9, "1h", text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_1h)
table.cell(t, 1, 9, trend_indicator_1h, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_1h)
if (show_ema_value)
table.cell(t, 2, 9, ema_1h, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_1h)
if (show_4h)
table.cell(t, 0, 12, "4h", text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_4h)
table.cell(t, 1, 12, trend_indicator_4h, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_4h)
if (show_ema_value)
table.cell(t, 2, 12, ema_4h, text_color = text_color, text_size = table_text_size, bgcolor = trend_bg_color_4h)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* BARS *//
= get_trend_status()
barcolor = current_trend_indicator_current_timeframe == uptrend_indicator ? uptrend_colour : current_trend_indicator_current_timeframe == downtrend_indicator ? downtrend_colour : neutraltrend_colour
barcolor(color = barcolor, editable = false, display = paint_bars ? display.all : display.none)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//* ALERTS *//
alertcondition(current_trend_indicator_current_timeframe != previous_trend_indicator_current_timeframe, '0. Trend changed', '⏰ Trend changed on {{ticker}}:{{interval}}min')
alertcondition(current_trend_indicator_current_timeframe != previous_trend_indicator_current_timeframe and current_trend_indicator_current_timeframe == uptrend_indicator, '1. Uptrend started', '🟢 Uptrend started on {{ticker}}:{{interval}}min')
alertcondition(current_trend_indicator_current_timeframe != previous_trend_indicator_current_timeframe and current_trend_indicator_current_timeframe == downtrend_indicator, '2. Downtrend started', '🔴 Downtrend started on {{ticker}}:{{interval}}min')
alertcondition(current_trend_indicator_current_timeframe != previous_trend_indicator_current_timeframe and current_trend_indicator_current_timeframe == neutraltrend_indicator, '3. Neutral trend started', '⚫️ Neutral trend started on {{ticker}}:{{interval}}min')
alertcondition(trend_indicator_4h == trend_indicator_1h and trend_indicator_1h == trend_indicator_15m, '6. 4h, 1h, 15m aligned', '4h, 1h, 15m {{ticker}} trend alignment')
alertcondition(trend_indicator_1h == trend_indicator_15m and trend_indicator_15m == trend_indicator_5m, '7. 1h, 15m, 5m aligned', '1h, 15m, 5m {{ticker}} trend alignment')
alertcondition(trend_indicator_15m == trend_indicator_5m and trend_indicator_5m == trend_indicator_3m, '8. 15m, 5m, 3m aligned', '15m, 5m, 3m {{ticker}} trend alignment')
// Constants
color CLEAR = color.rgb(0,0,0,100)
eq_threshold = input.float(0.3, '', minval = 0, maxval = 0.5, step = 0.1, group = 'Market Structure',inline = 'equilibrium_zone')
showSwing = input.bool(false, 'Swing Points', group="Market Structure",inline="3")
swingSize_swing = input.int(10, "Swing Point Period",inline="4", group="Market Structure")
label_sizes_s =input.string("Medium", options= , title="Label Size",inline="4", group="Market Structure")
label_size_buysell_s = label_sizes_s == "Small" ? size.tiny : label_sizes_s == "Medium" ? size.small : label_sizes_s == "Large" ? size.normal : label_sizes_s == "Medium2" ? size.normal : label_sizes_s == "Large2" ? size.large : size.huge
label_size_buysell = label_sizes_s == "Small" ? size.tiny : label_sizes_s == "Medium" ? size.small : label_sizes_s == "Large" ? size.normal : label_sizes_s == "Medium2" ? size.normal : label_sizes_s == "Large2" ? size.large : size.huge
swingColor = input.color(#787b86 , '', group="Market Structure",inline="3")
swingSize = 3
length_eqh = 3
//----------------------------------------}
//Key Levels
//----------------------------------------{
var Show_4H_Levels = input.bool(defval=false, title='4H', group='Key Levels', inline='4H')
Color_4H_Levels = input.color(title='', defval=color.orange, group='Key Levels', inline='4H')
Style_4H_Levels = input.string('Dotted', ' Style', , group="Key Levels",inline="4H")
Text_4H_Levels = input.bool(defval=false, title='Shorten', group='Key Levels', inline='4H')
labelsize = input.string(defval='Medium', title='Text Size', options= ,group = "Key Levels", inline='H')
var pihtext = Text_4H_Levels ? '-4H-' :'مقاومة 4'
displayStyle = 'Standard'
distanceright = 25
radistance = 250
linesize = 'Small'
linestyle = 'Solid'
var untested_monday = false
bosConfType = 'Candle High'//input.string('Candle Close', 'BOS Confirmation', , tooltip='Choose whether candle close/wick above previous swing point counts as a BOS.')
MSS = true//input.bool(false, 'Show MSS', tooltip='Renames the first counter t_MS BOS to MSS' )
// showSwing = false//input.bool(true, 'Show Swing Points', tooltip='Show or hide HH, LH, HL, LL')
// Functions
lineStyle(x) =>
switch x
'Solid' => line.style_solid
'Dashed' => line.style_dashed
'Dotted' => line.style_dotted
pivot_high_found = ta.pivothigh(high, swingSize_swing, swingSize_swing)
pivot_low_found = ta.pivotlow(low, swingSize_swing, swingSize_swing)
var float prevHigh_s = na,var float prevLow_s = na,var int prevHighIndex_s = na,var int prevLowIndex_s = na
bool higher_highs = false, bool lower_highs = false, bool higher_lows = false, bool lower_lows = false
var int prevSwing_s = 0
if not na(pivot_high_found)
if pivot_high_found >= prevHigh_s
higher_highs := true
prevSwing_s := 2
else
lower_highs := true
prevSwing_s := 1
prevHigh_s := pivot_high_found
prevHighIndex_s := bar_index - swingSize_swing
if not na(pivot_low_found)
if pivot_low_found >= prevLow_s
higher_lows := true
prevSwing_s := -1
else
lower_lows := true
prevSwing_s := -2
prevLow_s := pivot_low_found
prevLowIndex_s := bar_index - swingSize_swing
// ———————————————————— Global data {
//Using current bar data for HTF highs and lows instead of security to prevent future leaking
var htfH = open
var htfL = open
if close > htfH
htfH:= close
if close < htfL
htfL := close
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------- Key Levels
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
var monday_time = time
var monday_high = high
var monday_low = low
= request.security(syminfo.tickerid, 'W', , lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, 'W', [time , high ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, 'W', [time , low ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, 'M', , lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, 'M', [time , high ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, 'M', [time , low ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '240', [time , high ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '240', [time , low ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '3M', , lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '3M', [time , high ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '3M', [time , low ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '12M', , lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, '12M', , lookahead=barmerge.lookahead_on)
if weekly_time != weekly_time
untested_monday := false
untested_monday
untested_monday := true
monday_low
linewidthint = 1
if linesize == 'Small'
linewidthint := 1
linewidthint
if linesize == 'Medium'
linewidthint := 2
linewidthint
if linesize == 'Large'
linewidthint := 3
linewidthint
var linewidth_def = linewidthint
fontsize = size.small
if labelsize == 'Small'
fontsize := size.small
fontsize
if labelsize == 'Medium'
fontsize := size.normal
fontsize
if labelsize == 'Large'
fontsize := size.large
fontsize
linestyles = line.style_solid
if linestyle == 'Dashed'
linestyles := line.style_dashed
linestyles
if linestyle == 'Dotted'
linestyles := line.style_dotted
linestyles
var DEFAULT_LABEL_SIZE = fontsize
var DEFAULT_LABEL_STYLE = label.style_none
var Rigth_Def = distanceright
var arr_price = array.new_float(0)
var arr_label = array.new_label(0)
Combine_Levels(arr_price, arr_label, currentprice, currentlabel, currentcolor) =>
if array.includes(arr_price, currentprice)
whichindex = array.indexof(arr_price, currentprice)
labelhold = array.get(arr_label, whichindex)
whichtext = label.get_text(labelhold)
label.set_text(labelhold, label.get_text(currentlabel) + ' / ' + whichtext)
label.set_text(currentlabel, '')
label.set_textcolor(labelhold, currentcolor)
else
array.push(arr_price, currentprice)
array.push(arr_label, currentlabel)
extend_to_current(bars) =>
timenow + (time - time ) * bars
if barstate.islast
arr_price := array.new_float(0)
arr_label := array.new_label(0)
if Show_4H_Levels
limit_4H_right = extend_to_current(Rigth_Def)
intrah_limit_right = extend_to_current(Rigth_Def)
intral_limit_right = extend_to_current(Rigth_Def)
var intrah_line = line.new(x1=intrah_time, x2=intrah_limit_right, y1=intrah_open, y2=intrah_open, color=Color_4H_Levels, width=linewidth_def, xloc=xloc.bar_time, style=lineStyle(Style_4H_Levels))
var intrah_label = label.new(x=intrah_limit_right, y=intrah_open, text=pihtext, style=DEFAULT_LABEL_STYLE, textcolor=Color_4H_Levels, size=DEFAULT_LABEL_SIZE, xloc=xloc.bar_time)
var intral_line = line.new(x1=intral_time, x2=intral_limit_right, y1=intral_open, y2=intral_open, color=Color_4H_Levels, width=linewidth_def, xloc=xloc.bar_time, style=lineStyle(Style_4H_Levels))
line.set_xy1(intrah_line,intrah_time,intrah_open)
line.set_xy2(intrah_line,intrah_limit_right,intrah_open)
label.set_xy(intrah_label,intrah_limit_right,intrah_open)
label.set_text(intrah_label, pihtext)
line.set_x1(intral_line, intral_time)
line.set_x2(intral_line, intral_limit_right)
line.set_y1(intral_line, intral_open)
line.set_y2(intral_line, intral_open)
Combine_Levels(arr_price, arr_label, intrah_open, intrah_label, Color_4H_Levels)
daily_limit_right = extend_to_current(Rigth_Def)
dailyh_limit_right = extend_to_current(Rigth_Def)
dailyl_limit_right = extend_to_current(Rigth_Def)
type Candle
float o
float c
float h
float l
int o_idx
int c_idx
int h_idx
int l_idx
box body
line wick_up
line wick_down
type Imbalance
box b
int idx
type CandleSettings
bool show
string htf
int max_display
type Settings
int max_sets
color bull_body
color bull_border
color bull_wick
color bear_body
color bear_border
color bear_wick
int offset
int buffer
int htf_buffer
int width
bool trace_show
color trace_o_color
string trace_o_style
int trace_o_size
color trace_c_color
string trace_c_style
int trace_c_size
color trace_h_color
string trace_h_style
int trace_h_size
color trace_l_color
string trace_l_style
int trace_l_size
string trace_anchor
bool label_show
color label_color
string label_size
bool htf_label_show
color htf_label_color
string htf_label_size
bool htf_timer_show
color htf_timer_color
string htf_timer_size
type CandleSet
Candle candles
Imbalance imbalances
CandleSettings settings
label tfName
label tfTimer
type Helper
string name = "Helper"
Settings settings = Settings.new()
var CandleSettings SettingsHTF1 = CandleSettings.new()
var CandleSettings SettingsHTF2 = CandleSettings.new()
var CandleSettings SettingsHTF3 = CandleSettings.new()
var Candle candles_1 = array.new(0)
var Candle candles_2 = array.new(0)
var Candle candles_3 = array.new(0)
var CandleSet htf1 = CandleSet.new()
htf1.settings := SettingsHTF1
htf1.candles := candles_1
var CandleSet htf2 = CandleSet.new()
htf2.settings := SettingsHTF2
htf2.candles := candles_2
var CandleSet htf3 = CandleSet.new()
htf3.settings := SettingsHTF3
htf3.candles := candles_3
//+------------------------------------------------------------------------------------------------------------+//
//+--- Settings ---+//
//+------------------------------------------------------------------------------------------------------------+//
htf1.settings.show := input.bool(true, "HTF 1 ", inline="htf1")
htf_1 = input.timeframe("15", "", inline="htf1")
htf1.settings.htf := htf_1
htf1.settings.max_display := input.int(4, "", inline="htf1")
htf2.settings.show := input.bool(true, "HTF 2 ", inline="htf2")
htf_2 = input.timeframe("60", "", inline="htf2")
htf2.settings.htf := htf_2
htf2.settings.max_display := input.int(4, "", inline="htf2")
htf3.settings.show := input.bool(true, "HTF 3 ", inline="htf3")
htf_3 = input.timeframe("1D", "", inline="htf3")
htf3.settings.htf := htf_3
htf3.settings.max_display := input.int(4, "", inline="htf3")
settings.max_sets := input.int(6, "Limit to next HTFs only", minval=1, maxval=6)
settings.bull_body := input.color(color.new(#0efd16, 3), "Body ", inline="body")
settings.bear_body := input.color(color.new(#ec0808, 0), "", inline="body")
settings.bull_border := input.color(color.rgb(159, 159, 169), "Borders", inline="borders")
settings.bear_border := input.color(color.new(#e5e9ea, 0), "", inline="borders")
settings.bull_wick := input.color(color.new(#e9eeee, 10), "Wick ", inline="wick")
settings.bear_wick := input.color(#f7f9f9, "", inline="wick")
settings.offset := input.int(25, "padding from current candles", minval = 1)
settings.buffer := input.int(1, "space between candles", minval = 1, maxval = 4)
settings.htf_buffer := input.int(10, "space between Higher Timeframes", minval = 1, maxval = 10)
settings.width := input.int(1, "Candle Width", minval = 1, maxval = 4)*2
settings.htf_label_show := input.bool(true, "HTF Label ", inline="HTFlabel")
settings.htf_label_color := input.color(color.new(color.black, 10), "", inline='HTFlabel')
settings.htf_label_size := input.string(size.large, "", , inline="HTFlabel")
//+------------------------------------------------------------------------------------------------------------+//
//+--- Variables ---+//
//+------------------------------------------------------------------------------------------------------------+//
Helper helper = Helper.new()
color color_transparent = #ffffff00
//+------------------------------------------------------------------------------------------------------------+//
//+--- Internal Functions ---+//
//+------------------------------------------------------------------------------------------------------------+//
method LineStyle(Helper helper, string style) =>
helper.name := style
out = switch style
'----' => line.style_dashed
'····' => line.style_dotted
=> line.style_solid
method ValidTimeframe(Helper helper, string HTF) =>
helper.name := HTF
if timeframe.in_seconds(HTF) >= timeframe.in_seconds("D") and timeframe.in_seconds(HTF) > timeframe.in_seconds()
true
else
n1 = timeframe.in_seconds()
n2 = timeframe.in_seconds(HTF)
n3 = n1 % n2
(n1 < n2 and math.round(n2/n1) == n2/n1)
method HTFName(Helper helper, string HTF) =>
helper.name := "HTFName"
formatted = HTF
seconds = timeframe.in_seconds(HTF)
if seconds < 60
formatted := str.tostring(seconds) + "s"
else if (seconds / 60) < 60
formatted := str.tostring((seconds/60)) + "m"
else if (seconds/60/60) < 24
formatted := str.tostring((seconds/60/60)) + "H"
formatted
method HTFEnabled(Helper helper) =>
helper.name := "HTFEnabled"
int enabled =0
enabled += htf1.settings.show ? 1 : 0
enabled += htf2.settings.show ? 1 : 0
enabled += htf3.settings.show ? 1 : 0
int last = math.min(enabled, settings.max_sets)
last
method CandleSetHigh(Helper helper, Candle candles, float h) =>
helper.name := "CandlesSetHigh"
float _h = h
if array.size(candles) > 0
for i = 0 to array.size(candles)-1
Candle c = array.get(candles, i)
if c.h > _h
_h := c.h
_h
method CandlesHigh(Helper helper, Candle candles) =>
helper.name := "CandlesHigh"
h = 0.0
int cnt = 0
int last = helper.HTFEnabled()
if htf1.settings.show and helper.ValidTimeframe(htf1.settings.htf)
h := helper.CandleSetHigh(htf1.candles, h)
cnt += 1
if htf2.settings.show and helper.ValidTimeframe(htf2.settings.htf) and cnt < last
h := helper.CandleSetHigh(htf2.candles, h)
cnt +=1
if htf3.settings.show and helper.ValidTimeframe(htf3.settings.htf) and cnt < last
h := helper.CandleSetHigh(htf3.candles, h)
cnt += 1
if array.size(candles) > 0
for i = 0 to array.size(candles)-1
Candle c = array.get(candles, i)
if c.h > h
h := c.h
h
method Reorder(CandleSet candleSet, int offset) =>
size = candleSet.candles.size()
if size > 0
for i = size-1 to 0
Candle candle = candleSet.candles.get(i)
t_buffer = offset + ((settings.width+settings.buffer)*(size-i-1))
box.set_left(candle.body, bar_index + t_buffer)
box.set_right(candle.body, bar_index + settings.width + t_buffer)
line.set_x1(candle.wick_up, bar_index+((settings.width)/2) + t_buffer)
line.set_x2(candle.wick_up, bar_index+((settings.width)/2) + t_buffer)
line.set_x1(candle.wick_down, bar_index+((settings.width)/2) + t_buffer)
line.set_x2(candle.wick_down, bar_index+((settings.width)/2) + t_buffer)
candleSet
top = helper.CandlesHigh(candleSet.candles)
left = bar_index + offset + ((settings.width+settings.buffer)*(size-1))/2
if settings.htf_label_show
var label l = candleSet.tfName
string lbl = helper.HTFName(candleSet.settings.htf)
if settings.htf_timer_show
lbl += "\n"
if not na(l)
label.set_xy(l, left, top)
else
l := label.new(left, top, lbl, color=color_transparent, textcolor = settings.htf_label_color, style=label.style_label_down, size = settings.htf_label_size)
if settings.htf_timer_show
var label t = candleSet.tfTimer
if not na(t)
label.set_xy(t, left, top)
candleSet
method FindImbalance(CandleSet candleSet) =>
if barstate.isrealtime or barstate.islast
if candleSet.imbalances.size() > 0
for i = candleSet.imbalances.size()-1 to 0
Imbalance del = candleSet.imbalances.get(i)
box.delete(del.b)
candleSet.imbalances.pop()
if candleSet.candles.size() > 3
for i = 1 to candleSet.candles.size() -3
candle1 = candleSet.candles.get(i)
candle2 = candleSet.candles.get(i+2)
candle3 = candleSet.candles.get(i+1)
method Monitor(CandleSet candleSet) =>
HTFBarTime = time(candleSet.settings.htf)
isNewHTFCandle = ta.change(HTFBarTime)
if isNewHTFCandle
Candle candle = Candle.new()
candle.o := open
candle.c := close
candle.h := high
candle.l := low
candle.o_idx := bar_index
candle.c_idx := bar_index
candle.h_idx := bar_index
candle.l_idx := bar_index
bull = candle.c > candle.o
candle.body := box.new(bar_index, math.max(candle.o, candle.c), bar_index+2, math.min(candle.o, candle.c), bull ? settings.bull_border : settings.bear_border, 1, bgcolor = bull ? settings.bull_body : settings.bear_body)
candle.wick_up := line.new(bar_index+1, candle.h, bar_index, math.max(candle.o, candle.c), color=bull ? settings.bull_wick : settings.bear_wick)
candle.wick_down := line.new(bar_index+1, math.min(candle.o, candle.c), bar_index, candle.l, color=bull ? settings.bull_wick : settings.bear_wick)
candleSet.candles.unshift(candle)
if candleSet.candles.size() > candleSet.settings.max_display
Candle delCandle = array.pop(candleSet.candles)
box.delete(delCandle.body)
line.delete(delCandle.wick_up)
line.delete(delCandle.wick_down)
candleSet
method Update(CandleSet candleSet, int offset, bool showTrace) =>
if candleSet.candles.size() > 0
Candle candle = candleSet.candles.first()
candle.h_idx := high > candle.h ? bar_index : candle.h_idx
candle.h := high > candle.h ? high : candle.h
candle.l_idx := low < candle.l ? bar_index : candle.l_idx
candle.l := low < candle.l ? low : candle.l
candle.c := close
candle.c_idx := bar_index
bull = candle.c > candle.o
box.set_top(candle.body, candle.o)
box.set_bottom(candle.body, candle.c)
box.set_bgcolor(candle.body, bull ? settings.bull_body : settings.bear_body)
box.set_border_color(candle.body, bull ? settings.bull_border : settings.bear_border)
line.set_color(candle.wick_up, bull ? settings.bull_wick : settings.bear_wick)
line.set_color(candle.wick_down, bull ? settings.bull_wick : settings.bear_wick)
line.set_y1(candle.wick_up, candle.h)
line.set_y2(candle.wick_up, math.max(candle.o, candle.c))
line.set_y1(candle.wick_down, candle.l)
line.set_y2(candle.wick_down, math.min(candle.o, candle.c))
if barstate.isrealtime or barstate.islast
candleSet.Reorder(offset)
candleSet
int cnt = 0
int last = helper.HTFEnabled()
int offset = settings.offset
if htf1.settings.show and helper.ValidTimeframe(htf1.settings.htf)
bool showTrace = false
if settings.trace_anchor == "First Timeframe"
showTrace := true
if settings.trace_anchor == "Last Timeframe" and settings.max_sets == 1
showTrace := true
htf1.Monitor().Update(offset, showTrace)
cnt +=1
offset += cnt > 0 ? (htf1.candles.size() * settings.width) + (htf1.candles.size() > 0 ? htf1.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
if htf2.settings.show and helper.ValidTimeframe(htf2.settings.htf) and cnt < last
bool showTrace = false
if settings.trace_anchor == "First Timeframe" and cnt == 0
showTrace := true
if settings.trace_anchor == "Last Timeframe" and cnt == last-1
showTrace := true
htf2.Monitor().Update(offset, showTrace)
cnt+=1
offset += cnt > 0 ? (htf2.candles.size() * settings.width) + (htf2.candles.size() > 0 ? htf2.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
if htf3.settings.show and helper.ValidTimeframe(htf3.settings.htf) and cnt < last
bool showTrace = false
if settings.trace_anchor == "First Timeframe" and cnt == 0
showTrace := true
if settings.trace_anchor == "Last Timeframe" and cnt == last-1
showTrace := true
htf3.Monitor().Update(offset, showTrace)
cnt+=1
offset += cnt > 0 ? (htf3.candles.size() * settings.width) + (htf3.candles.size() > 0 ? htf3.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
zigzagBool = input.bool(false, 'Show Market Structure', group = 'Price Action Toolkit Settings')
zigzagLen = input.int(9, 'ZigZag Length', group = 'Price Action Toolkit Settings')
liquidityBool = input.bool(true, 'Show Liquidity Sweeps', group = 'Liquidity Settings')
liquidity_len = input.int(30, 'Liquidity Length', minval = 5, group = 'Liquidity Settings')
orderblockBool = input.bool(true, 'Show Order Blocks', group = 'Order Block Settings')
numberObShow = input.int(2, 'Number of Order Blocks to Show', group = 'Order Block Settings', minval = 1, maxval = 10)
showTrendLines = input.bool(true, 'Show Trend Lines', group = 'Misc')
trendLineLength = input.int(20, 'Trend Line Detection Sensitivity', group = 'Misc', minval = 10)
upTlColor = input.color(color.new(color.teal, 15), title = 'Trend Line Colors', group = 'Misc', inline = 'tl')
downTlColor = input.color(color.new(color.red, 15), title = ' ', group = 'Misc', inline = 'tl')
upColor = input.color(color.new(#000000, 100), title = 'Market/Liquidity Colors', group = 'Visual Settings', inline = '1')
downColor = input.color(color.new(#000000, 100), title = ' ', group = 'Visual Settings', inline = '1')
bearishOrderblockColor = input.color(color.new(#e80000, 1), title = 'Order Block Colors ', group = 'Visual Settings', inline = '2')
bullishOrderblockColor = input.color(color.new(#33cb00, 0), title = ' ', group = 'Visual Settings', inline = '2')
hideWatermark = input.bool(false, title = 'Hide Watermark', group = 'Visual Settings')
type orderblock
float value
int barStart
int barEnd
box block
bool broken
type liquidity
float value
int barStart
int barEnd
line liquidityLine
bool broken
label sweep
type zone
float value
int barStart
int barEnd
box block
string zoneType
var array bullishOrderblock = array.new()
var array bearishOrderblock = array.new()
var array bullishLiquidity = array.new()
var array bearishLiquidity = array.new()
var array highValIndex = array.new()
var array lowValIndex = array.new()
var array highVal = array.new_float()
var array lowVal = array.new_float()
var bool drawUp = false
var bool drawDown = false
var string lastState = na
var bool to_up = false
var bool to_down = false
var int trend = 1
var float fibTopVal = na
var int fibTopIndex = na
var float fibBotVal = na
var int fibBotIndex = na
var float premiumVal = na
var float discountVal = na
var int premiumValIndex = na
var int discountValIndex = na
var box premiumBox = na
var box discountBox = na
var label premiumLabel = na
var label discountLabel = na
var string textOfPremium = na
var string textOfDiscount = na
var line newBearishTrendline = na
var line newBullishTrendline = na
atr = ta.atr(14)
to_up := high >= ta.highest(high, zigzagLen)
to_down := low <= ta.lowest(low, zigzagLen)
trend := trend == 1 and to_down ? -1 : trend == -1 and to_up ? 1 : trend
drawZigzag(x1, y1, x2, y2) =>
line.new(x1 = x1, y1 = y1, x2 = x2, y2 = y2, xloc = xloc.bar_time, width = 1)
if ta.change(trend) != 0 and trend == 1
array.push(highValIndex, time )
array.push(highVal, high )
if array.size(lowVal) > 1
lastLowVal = array.get(lowVal, array.size(lowVal) - 1)
lastLowIndex = array.get(lowValIndex, array.size(lowValIndex) - 1)
lastHighIndex = array.get(highValIndex, array.size(highValIndex) - 1)
lastHighVal = array.get(highVal, array.size(highVal) - 1)
if zigzagBool
drawZigzag(x1 = lastLowIndex, y1 = lastLowVal, x2 = lastHighIndex, y2 = lastHighVal)
drawUp := false
drawUp
fibTopIndex := time
fibTopVal := high
fibTopVal
if ta.change(trend) != 0 and trend == -1
array.push(lowValIndex, time )
array.push(lowVal, low )
if array.size(highVal) > 1
lastHighVal = array.get(highVal, array.size(highVal) - 1)
lastHighIndex = array.get(highValIndex, array.size(highValIndex) - 1)
lastLowIndex = array.get(lowValIndex, array.size(lowValIndex) - 1)
lastLowVal = array.get(lowVal, array.size(lowVal) - 1)
if zigzagBool
drawZigzag(x1 = lastHighIndex, y1 = lastHighVal, x2 = lastLowIndex, y2 = lastLowVal)
drawDown := false
drawDown
fibBotIndex := time
fibBotVal := low
fibBotVal
if array.size(lowVal) > 1 and drawDown == false
if close < array.get(lowVal, array.size(lowVal) - 1)
line.new(x1 = array.get(lowValIndex, array.size(lowValIndex) - 1), y1 = array.get(lowVal, array.size(lowVal) - 1), x2 = time, y2 = array.get(lowVal, array.size(lowVal) - 1), width = 1, xloc = xloc.bar_time)
label.new(x = (array.get(lowValIndex, array.size(lowValIndex) - 1) + time) / 2, y = array.get(lowVal, array.size(lowVal) - 1), text = na(lastState) or lastState == 'up' ? 'CHoCH' : 'BoS', xloc = xloc.bar_time, style = label.style_label_up, textcolor = downColor, color = color.new(color.white, 100))
drawDown := true
lastState := 'down'
if orderblockBool
orderblock newOrderblock = orderblock.new()
float max = 0
int bar = na
for i = (time - array.get(lowValIndex, array.size(lowValIndex) - 1) - (time - time )) / (time - time ) to 0 by 1
if high > max
max := high
bar := time
bar
newOrderblock.barStart := bar
newOrderblock.barEnd := time
newOrderblock.broken := false
newOrderblock.value := max
newOrderblock.block := box.new(left = newOrderblock.barStart, top = newOrderblock.value - atr, right = newOrderblock.barEnd, bottom = newOrderblock.value, xloc = xloc.bar_time, bgcolor = bearishOrderblockColor, border_width = 1, border_color = bearishOrderblockColor)
array.push(bearishOrderblock, newOrderblock)
if array.size(bearishOrderblock) > 20
array.shift(bearishOrderblock)
if array.size(highVal) > 1 and drawUp == false
if close > array.get(highVal, array.size(highVal) - 1)
line.new(x1 = array.get(highValIndex, array.size(highValIndex) - 1), y1 = array.get(highVal, array.size(highVal) - 1), x2 = time, y2 = array.get(highVal, array.size(highVal) - 1), width = 1, xloc = xloc.bar_time)
label.new(x = (array.get(highValIndex, array.size(highValIndex) - 1) + time) / 2, y = array.get(highVal, array.size(highVal) - 1), text = na(lastState) or lastState == 'down' ? 'CHoCH' : 'BoS', xloc = xloc.bar_time, style = label.style_label_down, textcolor = upColor, color = color.new(color.white, 100))
drawUp := true
lastState := 'up'
if orderblockBool
orderblock newOrderblock = orderblock.new()
float min = 999999999
int bar = na
for i = (time - array.get(highValIndex, array.size(highValIndex) - 1) - (time - time )) / (time - time ) to 0 by 1
if low < min
min := low
bar := time
bar
newOrderblock.barStart := bar
newOrderblock.barEnd := time
newOrderblock.broken := false
newOrderblock.value := min
newOrderblock.block := box.new(left = newOrderblock.barStart, top = newOrderblock.value + atr, right = newOrderblock.barEnd, bottom = newOrderblock.value, xloc = xloc.bar_time, bgcolor = bullishOrderblockColor, border_width = 1, border_color = bullishOrderblockColor)
array.push(bullishOrderblock, newOrderblock)
if array.size(bullishOrderblock) > 20
array.shift(bullishOrderblock)
// Order block
//update orderblock
if array.size(bullishOrderblock) > 0
orderblock testOrderblock = na
int counter = 0
for i = array.size(bullishOrderblock) - 1 to 0 by 1
testOrderblock := array.get(bullishOrderblock, i)
if counter < numberObShow
testOrderblock.block.set_right(time)
if close < testOrderblock.value
testOrderblock.block.delete()
array.remove(bullishOrderblock, i)
counter := counter + 1
counter
else
testOrderblock.block.set_right(testOrderblock.barStart)
if array.size(bearishOrderblock) > 0
orderblock testOrderblock = na
int counter = 0
for i = array.size(bearishOrderblock) - 1 to 0 by 1
testOrderblock := array.get(bearishOrderblock, i)
if counter < numberObShow
testOrderblock.block.set_right(time)
if close > testOrderblock.value
testOrderblock.block.delete()
array.remove(bearishOrderblock, i)
counter := counter + 1
counter
else
testOrderblock.block.set_right(testOrderblock.barStart)
// Liquidity
phLiquidity = ta.pivothigh(high, liquidity_len, liquidity_len)
plLiquidity = ta.pivotlow(low, liquidity_len, liquidity_len)
if not na(phLiquidity) and liquidityBool
liquidity newLiquidity = liquidity.new()
newLiquidity.value := high
newLiquidity.barStart := time
newLiquidity.barEnd := time
newLiquidity.broken := false
newLiquidity.liquidityLine := line.new(x1 = newLiquidity.barStart, y1 = newLiquidity.value, x2 = newLiquidity.barEnd, y2 = newLiquidity.value, xloc = xloc.bar_time, color = downColor, width = 1)
array.push(bearishLiquidity, newLiquidity)
if array.size(bearishLiquidity) > 7
deletedLiquidity = array.shift(bearishLiquidity)
deletedLiquidity.liquidityLine.delete()
if not na(plLiquidity) and liquidityBool
liquidity newLiquidity = liquidity.new()
newLiquidity.value := low
newLiquidity.barStart := time
newLiquidity.barEnd := time
newLiquidity.broken := false
newLiquidity.liquidityLine := line.new(x1 = newLiquidity.barStart, y1 = newLiquidity.value, x2 = newLiquidity.barEnd, y2 = newLiquidity.value, xloc = xloc.bar_time, color = upColor, width = 1)
array.push(bullishLiquidity, newLiquidity)
if array.size(bullishLiquidity) > 7
deletedLiquidity = array.shift(bullishLiquidity)
deletedLiquidity.liquidityLine.delete()
// Update liquidity
if array.size(bearishLiquidity) > 0
liquidity testLiquidity = na
for i = array.size(bearishLiquidity) - 1 to 0 by 1
testLiquidity := array.get(bearishLiquidity, i)
if high > testLiquidity.value
testLiquidity.liquidityLine.set_x2(time)
testLiquidity.liquidityLine.set_style(line.style_dashed)
array.remove(bearishLiquidity, i)
if close < testLiquidity.value
testLiquidity.sweep := label.new(x = time, y = high, text = 'x', xloc = xloc.bar_time, style = label.style_label_down, size = size.normal, textcolor = color.new(#e8e8e8, 0), color = color.new(color.white, 100))
testLiquidity.sweep
else
testLiquidity.liquidityLine.set_x2(time)
if array.size(bullishLiquidity) > 0
liquidity testLiquidity = na
for i = array.size(bullishLiquidity) - 1 to 0 by 1
testLiquidity := array.get(bullishLiquidity, i)
if low < testLiquidity.value
testLiquidity.liquidityLine.set_x2(time)
testLiquidity.liquidityLine.set_style(line.style_dashed)
array.remove(bullishLiquidity, i)
if close > testLiquidity.value
testLiquidity.sweep := label.new(x = time, y = low, text = 'x', xloc = xloc.bar_time, style = label.style_label_up, size = size.normal, textcolor = color.new(#e2e2e2, 0), color = color.new(color.white, 100))
testLiquidity.sweep
else
testLiquidity.liquidityLine.set_x2(time)
悟隐高阶战法//@version=5
indicator("悟隐高阶战法", shorttitle='HT', overlay=true, max_labels_count=500, max_bars_back=5000)
// 输入参数
count_bull = input.int(3, title='非连续阳线数量', group='设置')
count_bear = input.int(3, title='非连续阴线数量', group='设置')
show_points = input.bool(true, title='显示高低点')
show_lines = input.bool(true,title = '显示线条')
max_points = input.int(200, title='最大点数')
line_color = input.color(color.purple, "连线颜色")
line_width = input.int(2, "线宽", minval=1, maxval=4)
h_color=input.color(color.red,title = 'H点颜色')
h_trs=input.float(80,title = 'h点透明度')
l_color=input.color(color.green,title = 'L点颜色')
l_trs=input.float(80,title = 'L点透明度')
// 警报设置
enable_alerts = input.bool(true, title='启用警报', group='警报设置')
show_signals = input.bool(true, title='显示BUY/SELL标记', group='信号显示设置')
signal_size = input.string('normal', title='信号标记大小', options= , group='信号显示设置')
signal_distance = input.float(0.1, title='信号标记距K线距离(%)', minval=0.05, maxval=0.5, group='信号显示设置')
// 各信号显示开关
show_signal_yyx = input.bool(true, title='显示看跌【阴阳阴】', group='信号开关')
show_signal_ayy = input.bool(true, title='显示看涨【阳阴阳】', group='信号开关')
show_signal_bull_1v2 = input.bool(true, title='显示看涨【一大于二】', group='信号开关')
show_signal_bear_1v2 = input.bool(true, title='显示看跌【一大于二】', group='信号开关')
show_signal_bear_2v2 = input.bool(true, title='显示看跌【二大于二】', group='信号开关')
show_signal_bull_2v2 = input.bool(true, title='显示看涨【二大于二】', group='信号开关')
show_signal_bull_engulf = input.bool(true, title='显示看涨吞没【吞没随阴线】', group='信号开关')
show_signal_bear_engulf = input.bool(true, title='显示看跌【吞没随阳线】', group='信号开关')
// 子条件显示开关
show_signal_bear_2v2_c1 = input.bool(true, title='看跌【二大于二】-条件1', group='子条件开关')
show_signal_bear_2v2_c2 = input.bool(true, title='看跌【二大于二】-条件2', group='子条件开关')
show_signal_bull_2v2_c1 = input.bool(true, title='看涨【二大于二】-条件1', group='子条件开关')
show_signal_bull_2v2_c2 = input.bool(true, title='看涨【二大于二】-条件2', group='子条件开关')
// ------------------ 自定义数据类型 ------------------
type RecordPrice
int bar_index
float open_price
float high_price
float low_price
float close_price
type Extremum
chart.point pt
string kind // "high" 或 "low"
type ABCPoints
float price_a
int index_a
float price_b
int index_b
float price_c
int index_c
string trend_type // "bull" 或 "bear"
bool broken // 是否被突破
// ------------------ 数组初始化 ------------------
var bullRecords = array.new()
var bearRecords = array.new()
var allPoints = array.new() // 存储所有高低点
var label pointLabels = array.new() // 存储绘制的标签,方便清理
var abcBullPoints = ABCPoints.new() // 存储牛市ABC点
var abcBearPoints = ABCPoints.new() // 存储熊市ABC点
// 存储黄线和标签的引用
var line yellowLines = array.new()
var label yellowLabels = array.new()
// 存储绿线和标签的引用
var line greenLines = array.new()
var label greenLabels = array.new()
// 突破状态变量
var bool cBroken = false
var int breakBarIndex = na
var bool fBroken = false
var int breakBarIndexBear = na
// 信号检测变量
var string currentSignal = ""
var string alertMessage = ""
var bool buySignal = false
var bool sellSignal = false
// ------------------ 状态变量 ------------------
var string lastPosition = "none"
var float lastHigh = na
var int lastHighBarIndex = na
var float lastLow = na
var int lastLowBarIndex = na
var float currentHigh = 0.0
var float currentLow = 0.0
var int currentHighBar = 0
var int currentLowBar = 0
// 使用Map存储每根K线是否创新高/新低
var map newHighMap = map.new()
var map newLowMap = map.new()
// 初始化
if barstate.isfirst
currentHigh := high
currentLow := low
currentHighBar := bar_index
currentLowBar := bar_index
// 更新区间高低并标记
bool isNewHigh = false
bool isNewLow = false
if high > currentHigh
currentHigh := high
currentHighBar := bar_index
isNewHigh := true
if low < currentLow
currentLow := low
currentLowBar := bar_index
isNewLow := true
// 存储当前K线的标记
map.put(newHighMap, bar_index, isNewHigh)
map.put(newLowMap, bar_index, isNewLow)
// ------------------ 方法 ------------------
method putRecord(array arr, int bar_idx, float open_pr, float high_pr, float low_pr, float close_pr) =>
newRecord = RecordPrice.new()
newRecord.bar_index := bar_idx
newRecord.open_price := open_pr
newRecord.high_price := high_pr
newRecord.low_price := low_pr
newRecord.close_price := close_pr
array.push(arr, newRecord)
method getRecord(array arr, int index) =>
if array.size(arr) > index and index >= 0
array.get(arr, index)
else
na
method removeRecord(array arr, int index) =>
if array.size(arr) > index and index >= 0
array.remove(arr, index)
method getLastRecord(array arr) =>
int size = array.size(arr)
if size > 0
array.get(arr, size - 1)
else
na
method isIncreasingLastN(array arr, int N) =>
if array.size(arr) < N
false
else
inc = true
for i = array.size(arr) - N to array.size(arr) - 2
prev = arr.getRecord(i)
curr = arr.getRecord(i + 1)
if curr.high_price <= prev.high_price
inc := false
break
inc
method isDecreasingLastN(array arr, int N) =>
if array.size(arr) < N
false
else
dec = true
for i = array.size(arr) - N to array.size(arr) - 2
prev = arr.getRecord(i)
curr = arr.getRecord(i + 1)
if curr.low_price >= prev.low_price
dec := false
break
dec
// 删除所有黄线和标签的方法
deleteYellowLinesAndLabels() =>
// 删除黄线
if array.size(yellowLines) > 0
for i = 0 to array.size(yellowLines) - 1
line l = array.get(yellowLines, i)
if not na(l)
line.delete(l)
array.clear(yellowLines)
// 删除标签
if array.size(yellowLabels) > 0
for i = 0 to array.size(yellowLabels) - 1
label lab = array.get(yellowLabels, i)
if not na(lab)
label.delete(lab)
array.clear(yellowLabels)
// 删除所有绿线和标签的方法
deleteGreenLinesAndLabels() =>
// 删除绿线
if array.size(greenLines) > 0
for i = 0 to array.size(greenLines) - 1
line l = array.get(greenLines, i)
if not na(l)
line.delete(l)
array.clear(greenLines)
// 删除标签
if array.size(greenLabels) > 0
for i = 0 to array.size(greenLabels) - 1
label lab = array.get(greenLabels, i)
if not na(lab)
label.delete(lab)
array.clear(greenLabels)
// 辅助函数:判断K线类型
isBullish(int offset = 0) =>
close > open
isBearish(int offset = 0) =>
close < open
// 辅助函数:获取当前趋势
getCurrentTrend() =>
if lastPosition == "low"
"uptrend" // 上涨趋势
else if lastPosition == "high"
"downtrend" // 下跌趋势
else
"none"
// 辅助函数:检查指定偏移的K线是否创过新高
wasNewHigh(int offset) =>
int targetBarIndex = bar_index - offset
bool result = false
if map.contains(newHighMap, targetBarIndex)
result := map.get(newHighMap, targetBarIndex)
result
// 辅助函数:检查指定偏移的K线是否创过新低
wasNewLow(int offset) =>
int targetBarIndex = bar_index - offset
bool result = false
if map.contains(newLowMap, targetBarIndex)
result := map.get(newLowMap, targetBarIndex)
result
// 辅助函数:检查过去N根K线中是否有创新高
hasNewHigh(int lookback = 3) =>
bool newHigh = false
for i = 0 to lookback - 1
if wasNewHigh(i)
newHigh := true
break
newHigh
// 辅助函数:检查过去N根K线中是否有创新低
hasNewLow(int lookback = 3) =>
bool newLow = false
for i = 0 to lookback - 1
if wasNewLow(i)
newLow := true
break
newLow
// 辅助函数:在过去5根K线中检查阴阳阴组合且有新高(相对于趋势起点)
checkBearishYYXPattern() =>
bool hasPattern = false
bool hasHighInRange = false
// 检查过去5根K线中是否有创新高
for i = 0 to 4
if wasNewHigh(i)
hasHighInRange := true
break
if hasHighInRange
// 检查过去3根K线的阴阳阴组合
if isBearish(0) and isBullish(1) and isBearish(2)
hasPattern := true
hasPattern
// 辅助函数:在过去5根K线中检查阳阴阳组合且有新低(相对于趋势起点)
checkBullishAYYPattern() =>
bool hasPattern = false
bool hasLowInRange = false
// 检查过去5根K线中是否有创新低
for i = 0 to 4
if wasNewLow(i)
hasLowInRange := true
break
if hasLowInRange
// 检查过去3根K线的阳阴阳组合
if isBullish(0) and isBearish(1) and isBullish(2)
hasPattern := true
hasPattern
// 辅助函数:检查是否是看涨吞没形态
isBullishEngulf(int offset = 0) =>
// 当前K线是阳线
isBullish(offset) and
// 吞没前一根K线
high > high and low < low and
// 确保只吞没前一根,不吞没前二根
not (high > high and low < low )
// 辅助函数:检查是否是看跌吞没形态
isBearishEngulf(int offset = 0) =>
// 当前K线是阴线
isBearish(offset) and
// 吞没前一根K线
high > high and low < low and
// 确保只吞没前一根,不吞没前二根
not (high > high and low < low )
// ------------------ 阳线/阴线处理 ------------------
if close > open
bullRecords.putRecord(bar_index, open, high, low, close)
if array.size(bullRecords) > count_bull
bullRecords.removeRecord(0)
if close < open
bearRecords.putRecord(bar_index, open, high, low, close)
if array.size(bearRecords) > count_bear
bearRecords.removeRecord(0)
// 做一个统计 ,记录当时的高价
var int count_long=na
var int count_short=na
var float high_price=na
var float low_price=na
// ------------------ 寻找低点 ------------------
if array.size(bullRecords) >= count_bull and bullRecords.isIncreasingLastN(count_bull) and close > open
if (lastPosition == "none" or lastPosition == "high") and low!=currentLow and bullRecords.first().bar_index >= currentLowBar
lastPosition := "low"
lastLow := currentLow
lastLowBarIndex := currentLowBar
if array.size(allPoints) >= max_points
array.shift(allPoints)
array.push(allPoints, Extremum.new(chart.point.from_index(lastLowBarIndex, lastLow), "low"))
currentHigh := high
currentHighBar := bar_index
count_long:=0
high_price:=high
// ------------------ 寻找高点 ------------------
if array.size(bearRecords) >= count_bear and bearRecords.isDecreasingLastN(count_bear) and close < open
if (lastPosition == "none" or lastPosition == "low") and high!=currentHigh and bearRecords.first().bar_index >= currentHighBar
lastPosition := "high"
lastHigh := currentHigh
lastHighBarIndex := currentHighBar
if array.size(allPoints) >= max_points
array.shift(allPoints)
array.push(allPoints, Extremum.new(chart.point.from_index(lastHighBarIndex, lastHigh), "high"))
currentLow := low
currentLowBar := bar_index
count_short:=0
low_price:=low
// ------------------ 绘制 ------------------
if barstate.islast and array.size(allPoints) > 1
// 删除旧的标签
for l in pointLabels
label.delete(l)
array.clear(pointLabels)
// 历史折线
if array.size(allPoints) > 2 and show_lines
tmpPts = array.new()
for i = 0 to array.size(allPoints)-2
ex = array.get(allPoints, i)
array.push(tmpPts, ex.pt)
polyline.new(tmpPts, xloc=xloc.bar_index, line_color=line_color, line_width=line_width)
// 最后一段线
if array.size(allPoints) >= 2 and show_lines
ex1 = array.get(allPoints, array.size(allPoints)-2)
ex2 = array.get(allPoints, array.size(allPoints)-1)
line.new(x1=ex1.pt.index, y1=ex1.pt.price, x2=ex2.pt.index, y2=ex2.pt.price,
xloc=xloc.bar_index, color=line_color, width=line_width)
// 高低点标签
if show_points
for i = 0 to array.size(allPoints)-1
ex = array.get(allPoints, i)
label lbl = na
if ex.kind == "low"
lbl := label.new(ex.pt.index, ex.pt.price, text=str.tostring(ex.pt.price),
style=label.style_label_up, color=color.new(color.green,80), textcolor=color.white)
else
lbl := label.new(ex.pt.index, ex.pt.price, text=str.tostring(ex.pt.price),
style=label.style_label_down, color=color.new(color.red,80), textcolor=color.white)
array.push(pointLabels,lbl)
// ------------------ 虚线预测段 ------------------
var line lastDashedLine = na
var label lastDashedLabel = na
if barstate.islast and array.size(allPoints) > 0
lastEx = array.get(allPoints, array.size(allPoints)-1)
if lastEx.kind == "low" and show_lines
if not na(lastDashedLine)
line.delete(lastDashedLine)
lastDashedLine := line.new(lastEx.pt.index, lastEx.pt.price, currentHighBar, currentHigh,
xloc=xloc.bar_index, color=line_color, width=line_width, style=line.style_dashed)
if show_points
if not na(lastDashedLabel)
label.delete(lastDashedLabel)
lastDashedLabel := label.new(lastEx.pt.index, lastEx.pt.price, text='H',
style=label.style_label_down, color=color.new(h_color,h_trs), textcolor=color.white)
if lastEx.kind == "high" and show_lines
if not na(lastDashedLine)
line.delete(lastDashedLine)
lastDashedLine := line.new(lastEx.pt.index, lastEx.pt.price, currentLowBar, currentLow,
xloc=xloc.bar_index, color=line_color, width=line_width, style=line.style_dashed)
if show_points
if not na(lastDashedLabel)
label.delete(lastDashedLabel)
lastDashedLabel := label.new(currentLowBar, currentLow, text='L',
style=label.style_label_up, color=color.new(l_color,l_trs), textcolor=color.white)
// ------------------ 信号检测逻辑 ------------------
// 重置信号
buySignal := false
sellSignal := false
currentSignal := ""
alertMessage := ""
if enable_alerts and bar_index >= 2
// 获取当前趋势
trend = getCurrentTrend()
// 信号1:看跌【阴阳阴】- 上涨趋势中,过去5根K线中有新高且出现阴线-阳线-阴线组合
if show_signal_yyx and trend == "uptrend" and checkBearishYYXPattern()
sellSignal := true
currentSignal := "SELL"
alertMessage := "看跌【阴阳阴】"
// 信号2:看涨【阳阴阳】- 下跌趋势中,过去5根K线中有新低且出现阳线-阴线-阳线组合
if show_signal_ayy and trend == "downtrend" and checkBullishAYYPattern()
buySignal := true
currentSignal := "BUY"
alertMessage := "看涨【阳阴阳】"
// 信号3:看涨【一大于二】- 下跌趋势中创新低,出现阳线,左边2根K至少有一根阴线
if show_signal_bull_1v2 and trend == "downtrend" and isBullish(0) and (isBearish(1) or isBearish(2)) and hasNewLow(3)
// 条件1:阳线实体最高价(收盘价)大于左边2根K实体最高价且实体最低价(开盘价)小于左边2根K实体最低价
condition1 = close > math.max(close , open ) and close > math.max(close , open ) and
open < math.min(close , open ) and open < math.min(close , open )
// 条件2:阳线最高价分别大于左边2根K最高价且最低价分别小于左边2根K最低价
condition2 = high > high and high > high and low < low and low < low
if condition1 or condition2
buySignal := true
currentSignal := "BUY"
alertMessage := "看涨【一大于二】"
// 信号4:看跌【一大于二】- 上涨趋势中,出现阴线,左边2根K至少有一根阳线
if show_signal_bear_1v2 and trend == "uptrend" and isBearish(0) and (isBullish(1) or isBullish(2)) and hasNewHigh(3)
// 条件1:阴线实体最高价(开盘价)大于左边2根K实体最高价且实体最低价(收盘价)小于左边2根K实体最低价
condition1 = open > math.max(close , open ) and open > math.max(close , open ) and
close < math.min(close , open ) and close < math.min(close , open )
// 条件2:阴线最高价分别大于左边2根K最高价且最低价分别小于左边2根K最低价
condition2 = high > high and high > high and low < low and low < low
if condition1 or condition2
sellSignal := true
currentSignal := "SELL"
alertMessage := "看跌【一大于二】"
// 信号5:看跌【二大于二】- 上涨趋势中
if show_signal_bear_2v2 and trend == "uptrend" and bar_index >= 3
// 条件1:连续2根阴线收盘价低于左边2根K线,且4根K线前3根必须有一根创新高(相对于趋势起点)
condition1 = show_signal_bear_2v2_c1 and isBearish(0) and isBearish(1) and
close < close and close < close and close < close and close < close and
(wasNewHigh(1) or wasNewHigh(2) or wasNewHigh(3))
// 条件2:连续2根阳线后再连续2根阴线,2根阴线最低价低于前面2根阳线最低价,最高价大于前面2根阳线最高价,中间2根K必须有一根创新高(相对于趋势起点)
condition2 = show_signal_bear_2v2_c2 and isBearish(0) and isBearish(1) and isBullish(2) and isBullish(3) and
math.min(low, low ) < math.min(low , low ) and
math.max(high, high ) > math.max(high , high ) and
(wasNewHigh(1) or wasNewHigh(2))
if condition1 or condition2
sellSignal := true
currentSignal := "SELL"
alertMessage := "看跌【二大于二】" + (condition1 ? "-条件1" : "") + (condition2 ? "-条件2" : "")
// 信号6:看涨【二大于二】- 下跌趋势中
if show_signal_bull_2v2 and trend == "downtrend" and bar_index >= 3
// 条件1:连续2根阳线收盘价高于左边2根K线,且4根K线前3根必须有一根创新低(相对于趋势起点)
condition1 = show_signal_bull_2v2_c1 and isBullish(0) and isBullish(1) and
close > close and close > close and close > close and close > close and
(wasNewLow(1) or wasNewLow(2) or wasNewLow(3))
// 条件2:连续2根阴线后再连续2根阳线,2根阳线最低价低于前面2根阴线最低价,最高价大于前面2根阴线最高价,中间2根K必须有一根创新低(相对于趋势起点)
condition2 = show_signal_bull_2v2_c2 and isBullish(0) and isBullish(1) and isBearish(2) and isBearish(3) and
math.min(low, low ) < math.min(low , low ) and
math.max(high, high ) > math.max(high , high ) and
(wasNewLow(1) or wasNewLow(2))
if condition1 or condition2
buySignal := true
currentSignal := "BUY"
alertMessage := "看涨【二大于二】" + (condition1 ? "-条件1" : "") + (condition2 ? "-条件2" : "")
// 信号7:看跌【吞没随阴线】- 上涨趋势中阳线吞没前一根K线,阳线后出现阴线,且有一根K创新高
if show_signal_bull_engulf and trend == "uptrend" and bar_index >= 2 and
isBullishEngulf(1) and isBearish(0) and hasNewHigh(3)
sellSignal := true
currentSignal := "SELL"
alertMessage := "看跌【吞没随阴线】"
// 信号8:看涨【吞没随阳线】- 下跌趋势中阴线吞没前一根K线,阴线后出现阳线,且有一根K创新低
if show_signal_bear_engulf and trend == "downtrend" and bar_index >= 2 and
isBearishEngulf(1) and isBullish(0) and hasNewLow(3)
buySignal := true
currentSignal := "BUY"
alertMessage := "看涨【吞没随阳线】"
// ------------------ BUY/SELL标记显示 ------------------
if show_signals
// 根据signal_size设置标记大小
labelSize = switch signal_size
"tiny" => size.tiny
"small" => size.small
"normal" => size.normal
"large" => size.large
"huge" => size.huge
=> size.normal
// 显示BUY信号
if buySignal
label.new(bar_index, low - (high - low) * signal_distance, text="BUY",
style=label.style_label_up, color=color.new(color.green, 0),
textcolor=color.white, size=labelSize, tooltip=alertMessage)
// 显示SELL信号
if sellSignal
label.new(bar_index, high + (high - low) * signal_distance, text="SELL",
style=label.style_label_down, color=color.new(color.red, 0),
textcolor=color.white, size=labelSize, tooltip=alertMessage)
// ------------------ TradingView警报条件 ------------------
// 检查是否有启用的买入/卖出信号(包括子条件)
enabledBuySignals = show_signal_ayy or
(show_signal_bull_1v2 ) or
(show_signal_bull_2v2 and (show_signal_bull_2v2_c1 or show_signal_bull_2v2_c2)) or
show_signal_bear_engulf
enabledSellSignals = show_signal_yyx or
(show_signal_bear_1v2) or
(show_signal_bear_2v2 and (show_signal_bear_2v2_c1 or show_signal_bear_2v2_c2)) or
show_signal_bull_engulf
// 买入信号警报
alertcondition(enable_alerts and enabledBuySignals and buySignal, title="买入信号", message="{{alertMessage}}")
// 卖出信号警报
alertcondition(enable_alerts and enabledSellSignals and sellSignal, title="卖出信号", message="{{alertMessage}}")
// 所有信号的通用警报
alertcondition(enable_alerts and (enabledBuySignals and buySignal or enabledSellSignals and sellSignal), title="所有交易信号",
message="信号类型: {{currentSignal}}, 详情: {{alertMessage}}")
// 具体的信号类型警报
alertcondition(enable_alerts and show_signal_ayy and buySignal and str.contains(alertMessage, "阳阴阳"), title="看涨【阳阴阳】", message="看涨【阳阴阳】")
alertcondition(enable_alerts and show_signal_yyx and sellSignal and str.contains(alertMessage, "阴阳阴"), title="看跌【阴阳阴】", message="看跌【阴阳阴】")
alertcondition(enable_alerts and show_signal_bull_1v2 and buySignal and str.contains(alertMessage, "一大于二"), title="看涨【一大于二】", message="看涨【一大于二】")
alertcondition(enable_alerts and show_signal_bear_1v2 and sellSignal and str.contains(alertMessage, "一大于二"), title="看跌【一大于二】", message="看跌【一大于二】")
alertcondition(enable_alerts and show_signal_bull_2v2 and buySignal and str.contains(alertMessage, "二大于二"), title="看涨【二大于二】", message="看涨【二大于二】")
alertcondition(enable_alerts and show_signal_bear_2v2 and sellSignal and str.contains(alertMessage, "二大于二"), title="看跌【二大于二】", message="看跌【二大于二】")
alertcondition(enable_alerts and show_signal_bull_engulf and sellSignal and str.contains(alertMessage, "吞没随阴线"), title="看涨吞没【吞没随阴线】", message="看涨吞没【吞没随阴线】")
alertcondition(enable_alerts and show_signal_bear_engulf and buySignal and str.contains(alertMessage, "吞没随阳线"), title="看跌【吞没随阳线】", message="看跌【吞没随阳线】")
TrendPredator PROThe TrendPredator PRO
Stacey Burke, a seasoned trader and mentor, developed his trading system over the years, drawing insights from influential figures such as George Douglas Taylor, Tony Crabel, Steve Mauro, and Robert Schabacker. His popular system integrates select concepts from these experts into a consistent framework. While powerful, it remains highly discretionary, requiring significant real-time analysis, which can be challenging for novice traders.
The TrendPredator indicators support this approach by automating the essential analysis required to trade the system effectively and incorporating mechanical bias and a multi-timeframe concept. They provide value to traders by significantly reducing the time needed for session preparation, offering all relevant chart analysis and signals for live trading in real-time.
The PRO version offers an advanced pattern identification logic that highlights developing context as well as setups related to the constellation of the signals provided. It provides real-time interpretation of the multi-timeframe analysis table, following an extensive underlying logic with more than 150 different setup variations specifically developed for the system and indicator. These setups are constantly back- and forward-tested and updated according to the results. This version is tailored to traders primarily trading this system and following the related setups in detail.
The former TrendPredator ES version does not provide that option. It is significantly leaner and is designed for traders who want to use the multi-timeframe logic as additional confluence for their trading style. It is very well suited to support many other trading styles, including SMC and ICT.
The Multi-timeframe Master Pattern
Inspired by Taylor’s 3-day cycle and Steve Mauro’s work with “Beat the Market Maker,” Burke’s system views markets as cyclical, driven by the manipulative patterns of market makers. These patterns often trap traders at the extremes of moves above or below significant levels with peak formations, then reverse to utilize their liquidity, initiating the next phase. Breakouts away from these traps often lead to range expansions, as described by Tony Crabel and Robert Schabacker. After multiple consecutive breakouts, especially after the psychological number three, overextension might develop. A break in structure may then lead to reversals or pullbacks. The TrendPredator Indicator and the related multi-timeframe trading system are designed to track these cycles on the daily timeframe and provide signals and trade setups to navigate them.
Bias Logic and Multi-Timeframe Concept
The indicator covers the basic signals of Stacey Burke's system:
- First Red Day (FRD): Bearish break in structure, signalling weak longs in the market.
- First Green Day (FGD): Bullish break in structure signalling weak shorts in the markt.
- Three Days of Longs (3DL): Overextension signalling potential weak longs in the market.
- Three Days of Shorts (3DS): Overextension signalling potential weak shorts in the market.
- Inside Day (ID): Contraction, signalling potential impulsive reversal or range expansion move.
It enhances the original system by introducing:
Structured Bias Logic:
Tracks bias by following how price trades concerning the last previous candle high or low that was hit. For example if the high was hit, we are bullish above and bearish below.
- Bullish state: Breakout (BO), Fakeout Low (FOL)
- Bearish state: Breakdown (BD), Fakeout High (FOH)
Multi-Timeframe Perspective:
- Tracks all signals across H4, H8, D, W, and M timeframes, to look for alignment and follow trends and momentum in a mechanical way.
Developing Context:
- Identifies specific predefined context states based on the monthly, weekly and daily bias.
Developing Setups:
- Identifies specific predefined setups based on context and H8 bias as well as SB signals.
The indicator monitors the bias and signals of the system across all relevant timeframes and automates the related graphical chart analysis as well as context and setup zone identification. In addition to the master pattern, the system helps to identify the higher timeframe situation and follow the moves driven by other timeframe traders to then identify favourable context and setup situations for the trader.
Example: Full Bullish Cycle on the Daily Timeframe with Multi-Timeframe Signals
- The Trap/Peak Formation
The market breaks down from a previous day’s and maybe week’s low—potentially after multiple breakdowns—but fails to move lower and pulls back up to form a peak formation low and closes as a first green day.
MTF Signals: Bullish daily and weekly fakeout low; three consecutive breakdown days (1W Curr FOL, 1D Curr FOL, BO 3S).
Context: Reversal (REV)
Setup: Fakeout low continuation low of day (FOL Cont LOD)
- Pullback and Consolidation
The next day pulls further up after first green day signal, potentially consolidates inside the previous day’s range.
MTF Signals: Fakeout low and first green day closing as an inside day (1D Curr IS, Prev FOL, First G).
Context: Reversal continuation (REV Cont)
Setup: Previous fakeout low continuation low handing fruit (Prev FOL Cont LHF)
- Range Expansion/Trend
The following day breaks up through the previous day’s high, launching a range expansion away from the trap.
MTF Signals: Bullish daily breakout of an inside day (1D Curr BO, Prev IS).
Context: Uptrend healthy (UT)
Setup: Breakout continuation low hanging fruit (BO Cont LHF)
- Overextension
After multiple consecutive breakouts, the market reaches a state of overextension, signalling a possible reversal or pullback.
MTF Signals: Three days of breakout longs (1D Curr BO, Prev BO, BO 3L).
Context: Uptrend extended (UT)
- Reversal
After a breakout of previous days high that fails, price pulls away from the high showing a rollover of momentum across all timeframes and a potential short setup.
MTF Signals: Three days of breakout longs, daily fakeout high (1D 3L, FOH)
Context: Reversal countertrend (REV)
Setup: Fakeout high continuation high of day (FOH Cont HOD)
Note: This is only one possible illustrative scenario; there are many variations and combinations.
Example Chart: Full Bullish Cycle with Correlated Signals
Multi-Timeframe Signals examples:
Context and Setups examples:
Note: The signals shown along the move are manually added illustrations. The indicator shows these in realtime in the table at top and bottom right. This is only one possible scenario; there are many variations and combinations.
Due to the fractal nature of markets, this cycle can be observed across all timeframes. The strongest setups occur when there is multi-timeframe alignment. For example, a peak formation and potential reversal on the daily timeframe have higher probability and follow-through when they align with bearish signals on higher timeframes (e.g., weekly/monthly BD/FOH) and confirmation on lower timeframes (H4/H8 FOH/BD). With this perspective, the system enables the trader to follow the trend and momentum while identifying rollover points in a highly differentiated and precise way.
Using the Indicator for Trading
The automated analysis provided by the indicator can be used for thesis generation in preparation for a session as well as for live trading, leveraging the real-time updates as well as the context and setup indicated or alerted. It is recommended to customize the settings deeply, such as hiding the lower timeframes for thesis generation or the specific alert time window and settings to the specific trading schedule and playbook of the trader.
1. Context Assessment:
Evaluate alignment of higher timeframes (e.g., Month/Week, Week/Day). More alignment → Stronger setups.
- The context table offers an interpretation of the higher timeframe automatically. See below for further details.
2. Setup Identification:
Follow the bias of daily and H8 timeframes. A setup mostly requires alignment of these.
Setup Types:
- Trend Trade: Trade in alignment with the previous day’s trend.
Example: Price above the previous day’s high → Focus on long setups (dBO, H8 FOL) until overextension or reversal signs appear (H8 BO 3L, First R).
- Reversal Trade: Identify reversal setups when lower timeframes show rollovers after higher timeframe weakness.
Example: Price below the previous day’s high → Look for reversal signals at the current high of day (H8 FOH, BO 3L, First R).
- The setup table shows potential setups for the specific price zone in the table automatically. See below for further details.
3. Entry Confirmation:
Confirm entries based on H8 and H4 alignment, candle closes and lower timeframe fakeouts.
- H8 and H4 should always align for a final confirmation, meaning the breach lines should be both in the back of a potential trade setup.
- M15/ 5 candle close can be seen as acceptance beyond a level or within the setup zone.
- M15/5 FOH/ FOL signals lower timeframe traps potentially indicating further confirmation.
Example Chart Reversal Trade:
Context: REV (yellow), Reversal counter trend, Month in FOL with bearish First R, Week in BO but bearishly overextended with BO 3L, Day in Fakeout high reversing bearishly.
Setup: FOH Cont HOD (red), Day in Fakeout high after BO 3L overextension, confirmed by H8 FOH high of day, First R as further confluence. Two star quality and countertrend.
Entry: H4 BD, M15 close below followed by M15 FOH.
Detailed Features and Options
1. Context and Setup table
The Context and Setup Table is the core feature of the TrendPredator PRO indicator. It delivers real-time interpretation of the multi-timeframe analysis based on an extensive underlying logic table with over 150 variations, specifically developed for this system and indicator. This logic is continuously updated and optimized to ensure accuracy and performance.
1.1. Developing Context
States for developing higher timeframe context are determined based on signals from the monthly, weekly, and daily timeframes.
- Green and Red indicate alignment and potentially interesting developing setups.
- Yellow signals a mixed or conflicting bias, suggesting caution when taking trades.
The specific states are:
- UT (yellow): Uptrend extended
- UT (green): Uptrend healthy
- REV (yellow): Reversal day counter trend
- REV (green): Reversal day mixed trend
- REV Cont (green): Reversal continuation mixed trend
- REV Cont (yellow): Reversal continuation counter trend
- REV into UT (green): Reversal day into uptrend
- REV Cont into UT (green): Reversal continuation into uptrend
- UT Pullback (yellow): Counter uptrend breakdown day
- Conflicting (yellow): Conflicting signals
- Consolidating (yellow): Consolidating sideways
- Inside (yellow): Trading inside after an inside week
- DT Pullback (yellow): Counter downtrend breakout day
- REV Cont into DT (red): Reversal continuation into downtrend
- REV into DT (red): Reversal day into downtrend
- REV Cont (yellow): Reversal continuation counter trend
- REV Cont (red): Reversal continuation mixed trend
- REV (red): Reversal day mixed trend
- REV (yellow): Reversal day countertrend
- DT (red): Downtrend healthy
- DT (yellow): Downtrend extended
Example: Uptrend
The Uptrend Context (UT, green) indicates a healthy uptrend with all timeframes aligning bullishly. In this case, the monthly is in a Fakeout Low (FOL) and currently inside the range, while the weekly and daily are both in Breakout (BO) states. This context is favorable for developing long setups in the direction of the trend.
Example: Uptrend pullback
The Uptrend Pullback Context (UT Pullback, yellow) indicates a Breakdown (BD) on the daily timeframe against a higher timeframe uptrend. In this case, the monthly is in a Fakeout Low (FOL) and currently inside its range, the weekly is in Breakout (BO) and also currently inside, while the daily is in Breakdown (BD). This context reflects a conflicting situation—potentially signaling either an early reversal back into the uptrend or, if the breakdown extends, the beginning of a possible trend change.
Example: Reversal into Uptrend
The Reversal into Uptrend Context (REV into UT, green) indicates a lower timeframe reversal aligning with a higher timeframe uptrend. In this case, the monthly is in Breakout (BO), the weekly is in Breakout (BO) and currently inside its range, while the daily is showing a bullish Fakeout Low (FOL) reversal. This context is potentially very favorable for long setups, as it signals a strong continuation of the uptrend supported across multiple timeframes.
Example: Reversal
The Bearish Reversal Context indicates a lower timeframe rollover within an ongoing higher timeframe uptrend. In this case, the monthly remains in Breakout (BO), the weekly has shifted into a Fakeout High (FOH) after three weeks of breakout longs, and the daily is already in Breakdown (BD). This context suggests a potentially favorable developing short setup, as early signs of weakness appear across timeframes.
1.2. Developing Setup
The states for specific setups are based on the context and the signals from the daily timeframe and H8, indicating that price is in the zone of alignment. The setup description refers to the state of the daily timeframe, while the suffix relates to the H8 timeframe. For example, "prev FOH Cont LHF" means that the previous day is in FOH (Fakeout High) relative to yesterday's breakout level, currently trading inside, and we are in an H8 breakdown, indicating a potential LHF (Lower High Formation) short trade if the entry confirms. The suffix HOD means that H8 is in FOH or BO (Breakout).
The specific states are:
- REV HOD (red): Reversal high of day
- REV Cont LHF (red): Reversal continuation low hanging fruit
- BO Cont LHF (green): Breakout continuation low hanging fruit
- BO Cont LOD (green): Breakout continuation low of day
- FOH Cont HOD (red): Fakeout high continuation high of day
- FOH Cont LHF ((red): Fakeout high continuation low hanging fruit
- prev BD Cont HOD (red): Previous breakdown continuation high of day
- prev BD Cont LHF (red): Previous breakdown continuation low hanging fruit
- prev FOH Cont HOD (red): Previous fakeout high continuation high of day
- prev FOH Cont LHF (red): Previous fakeout high continuation low hanging fruit
- prev FOL Cont LOD (green): Previous fakeout low continuation low of day
- prev FOL Cont LHF (green): Previous fakeout low continuation low hanging fruit
- prev BO Cont LOD (green): Previous breakout continuation low of day
- prev BO Cont LHF (green): Previous breakout continuation low hanging fruit
- FOL Cont LHF (green): Fakeout low continuation low hanging fruit
- FOL Cont LOD (green): Fakeout low continuation low of day
- BD Cont LHF (red): BD continuation low hanging fruit
- BD Cont LOD (red): Breakdown continuation low of day
- REV Cont LHF (green): Reversal continuation low hanging fruit
- REV LOD (green): Reversal low of day
- Inside: Trading inside after an inside day
Type: Indicates the situation of the indicated setup concerning:
- Trend: Following higher timeframe trend
- Mixed: Mixed higher timeframe signals
- Counter: Against higher timeframe bias
Quality: Indicates the quality of the indicated setup according to the specified logic table
No star: Very low quality
* One star: Low quality
** Two star: Medium quality
*** Three star: High quality
Example: Breakout Continuation Trend Setup
This setup highlights a healthy uptrend where the month is in a breakout, the week is in a fakeout low, and the day is in a breakout after a first green day. As the H8 breaks out to the upside, a long setup zone is triggered, presenting a breakout continuation low-hanging fruit trade. This is a trend trade in an overextended situation on the H8, with an H8 3L, resulting in an overall quality rating of one star.
Example: Fakeout Low Continuation Trend Setup
This setup shows a reversal into uptrend, with the month in a breakout, the week in a breakout, and the day in a fakeout low after breaking down the previous day and now reversing back up. As H8 breaks out to the upside, a long setup zone is triggered, presenting a previous fakeout low continuation, low-hanging fruit trade. This is a medium-quality trend trade.
Example: Reversal Setup - Mixed Trend
This setup shows a reversal setup in line with the weekly trend, with the month in a fakeout low, the week in a fakeout high, and the day in a fakeout high after breaking out earlier in the day and now reversing back down. As H8 loses the previous breakout level after 3 breakouts (with H8 3L), a short setup zone is triggered, presenting a fakeout high continuation at the high of the day. This is a high-quality trade in a mixed trend situation.
Setup Alerts:
Alerts can be activated for setups freshly triggered on the chart within your trading window.
Detailed filter logic for setup alerts:
- Setup quality: 1-3 star
- Setup type: Counter, Mixed and Trend
- Setup category: e.g. Reversal Bearish, Breakout, Previous Fakeout High
- 1D BO and First signals: 3DS, 3DL, FRD, FGD, ID
Options:
- Alerts on/ off
- Alert time window (from/ to)
- Alert filter customization
Note: To activate alerts from a script in TradingView, some settings need to be adjusted. Open the "Create Alert" dialog and select the option "Any alert() function call" in the "Condition" section. Choose "TrendPredator PRO" to ensure that alerts trigger properly from the code. Alerts can be activated for entire watchlists or individual pairs. Once activated, the alerts run in the background and notify the user whenever a setup is freshly triggered according to the filter settings.
2. Multi-Timeframe Table
Provides a real-time view of system signals, including:
Current Timeframe (Curr): Bias states.
- Breakout (green BO): Bullish after breaking above the previous high.
- Fakeout High (red FOH): Bearish after breaking above the previous high but pulling back down.
- Breakdown (red BD): Bearish after breaking below the previous low.
- Fakeout Low (green FOL): Bullish after breaking below the previous low but pulling back up.
- Inside (IS): Price trading neutral inside the previous range, taking the previous bias (color indicates the previous bias).
Previous Timeframe (Prev): Tracks last candle bias state and transitions dynamically.
- Bias for last candle: BO, FOH, BD, FOL in respective colors.
- Inside bar (yellow IS): Indicated as standalone signal.
Note: Also previous timeframes get constantly updated in real time to track the bias state in relation to the level that was hit. This means a BO can still lose the level and become a FOH, and vice versa, and a BD can still become a FOL, and vice versa. This is critical to see for example if traders that are trapped in that timeframe with a FOH or FOL are released. An inside bar stays fixed, though, since no level was hit in that timeframe.
Breakouts (BO): Breakout count 3 longs and 3 shorts.
- 3 Longs (red 3L): Bearish after three breakouts without hitting a previous low.
- 3 Shorts (green 3S): Bullish after three breakdowns without hitting a previous high.
First Countertrend Close (First): Tracks First Red or Green Day.
- First Green (G): After two consecutive red closes.
- First Red (R): After two consecutive green closes.
Options: Customizable font size and label colors.
3. Historic Highs and Lows
Displays historic highs and lows per timeframe for added context, enabling users to track sequences over time.
Timeframes: H4, H8, D, W, M
Options: Customize for timeframes shown, number of historic candles per timeframe, colors, formats, and labels.
4. Previous High and Low Extensions
Displays extended previous levels (high, low, and close) for each timeframe to assess how price trades relative to these levels.
H4: P4H, P4L, P4C
H8: P8H, P8L, P8C
Daily: PDH, PDL, PDC
Weekly: PWH, PWL, PWC
Monthly: PMH, PML, PMC
Options: Fully customizable for timeframes shown, colors, formats, and labels.
5. Breach Lines
Tracks live market reactions (e.g., breakouts or fakeouts) per timeframe for the last previous high or low that was hit, highlighting these levels originating at the breached candle to indicate bias (color-coded).
Red: Bearish below
Green: Bullish above
H4: 4FOL, 4FOH, 4BO, 4BD
H8: 8FOL, 8FOH, 8BO, 8BD
D: dFOL, dFOH, dBO, dBD
W: wFOL, wFOH, wBO, wBD
M: mFOL, mFOH, mBO, mBD
Options: Fully customizable for timeframes shown, colors, formats, and labels.
Overall Options:
Toggle single feature groups on/off.
Customize H8 open/close time as an offset to UTC to be provider independent.
Colour settings con be adjusted for dark or bright backgrounds.
Higher Timeframe Use Case Examples
Example Use Case: Weekly Template Analysis
The Weekly Template is a core concept in Stacey Burke’s trading style. The analysis is conducted on the daily timeframe, focusing on the higher timeframe bias and identifying overextended conditions within the week—such as multiple breakouts and peak formations signaling potential reversals.
In this example, the candles are colored by the TrendPredator FO indicator, which highlights the state of individual candles. This allows for precise evaluation of both the trend state and the developing weekly template. It is a valuable tool for thesis generation before a trading session and for backtesting purposes.
Example Use Case: High Timeframe 5-Star Setup Analysis (Stacey Burke "ain't coming back" ACB Template)
This analysis identifies high-probability trade opportunities when daily breakout or breakdown closes occur near key monthly levels mid-week, signaling overextensions and potentially large parabolic moves. The key signal to look for is a breakout or breakdown close on a Wednesday. This is useful for thesis generation before a session and also for backtesting.
In this example, the TrendPredator FO indicator colors the candles to highlight individual candle states, particularly those that close in breakout or breakdown. Additionally, an indicator is shown on the chart shading every Wednesday, making it easier to visually identify the signals.
5 Star Alerts:
Alerts can be activated for this potential 5-Star setup constellation. The alert is triggered when there is a breakout or breakdown close on a Wednesday.
Further recommendations:
- Higher timeframe context: TPO or volume profile indicators can be used to gain an even better overview.
- Late session trading: Entries later in the session, such as during the 3rd hour of the NY session, offer better analysis and follow-through on setups.
- Entry confirmation: Momentum indicators like VWAP, Supertrend, or EMA are helpful for increasing precision. Additionally, tracking lower timeframe fakeouts can provide powerful confluence. To track those the TrendPredator Fakeout Highlighter (FO), that has been specifically developed for this can be of great help:
Limitations:
Data availability using TradingView has its limitations. The indicator leverages only the real-time data available for the specific timeframe being used. This means it cannot access data from timeframes lower than the one displayed on the chart. For example, if you are on a daily chart, it cannot use H8 data. Additionally, on very low timeframes, the historical availability of data might be limited, making higher timeframe signals unreliable.
To address this, the indicator automatically hides the affected columns in these specific situations, preventing false signals.
Disclaimer
This indicator is for educational purposes only and does not guarantee profits.
None of the information provided shall be considered financial advice.
The indicator does not provide final buy or sell signals but highlights zones for potential setups.
Users are fully responsible for their trading decisions and outcomes.
Smart Market Structure and Swing Points, version 1.0Smart Market Structure and Swing Points, Version 1.0
Overview
The Smart Market Structure and Swing Points script is designed to provide advanced insights into market structure and key swing points. This script helps identify important highs and lows, trend direction changes (structure breaks), and swing points, enhancing decision-making for both trend-following and reversal strategies. See below for detail presentation and why it has unique features.
Unique Features of the New Script
Market Structure Identification : Analyzes and marks key highs and lows to determine market structure, including higher highs, lower highs, higher lows, and lower lows.
Customizable Detection Length : Allows users to set the length for detecting highs and lows, providing flexibility to adapt to different market conditions and timeframes. Default value is 5 bars, but can be changed if needed.
Visual Signal Indicators (Labels) : Plots labels on the chart to indicate higher highs (HH), lower highs (LH), higher lows (HL), and lower lows (LL), along with corresponding RSI values, offering clear visual cues for market structure analysis. The indication of RSI values directly on high and low points enables to better judge whether the points are strong references (extreme RSI values) or weak references (middle RSI values)
Dynamic Trend Lines : Draws solid and dotted lines to connect significant highs and lows, visually representing the current trend direction and potential trend changes. Dashed lines indicates structure breaks.
Swing High and Swing Low Detection : Identifies and marks the most recent swing highs and swing lows, helping traders spot potential reversal points and key levels for setting stop losses or take profit targets .
Originality and Usefulness
This script combines market structure, trend breaks and RSI to provide a more robust view of market dynamic by indicating the strength or weakness of swing points , in that way the script is unique.
Signal Description
The script includes various signal features that highlight potential trading opportunities based on market structure:
Higher Highs (HH) and Higher Lows (HL) : These labels are plotted when new highs or lows are formed, indicating a continuation of an uptrend. The labels are positioned with consideration of the Average True Range (ATR) for better visibility.
Lower Highs (LH) and Lower Lows (LL) : These labels are plotted when new highs or lows are formed, indicating a continuation of a downtrend. The labels include RSI values to provide additional information on the strength or weakness of the points.
Trend Direction Change : Dotted lines are drawn to indicate potential trend direction changes when the script detects significant shifts in market structure.
Swing Highs and Swing Lows : These are identified based on a customizable swing length, marking recent significant highs and lows to highlight potential reversal points.
These signals help identify high-probability turning points and confirm trend direction by ensuring that the market structure aligns with the trading strategy.
Detailed Description
Input Variables
Length for High/Low Detection (`length`) : Defines the range to check for highs and lows. Default is 5.
RSI Length (`rsilength`) : The number of periods to calculate the RSI. Default is 14.
Functionality
Market Structure Calculation : The script determines the highest high and lowest low within the specified range to identify key points in market structure.
```pine
h = ta.highest(high, length * 2 + 1)
l = ta.lowest(low, length * 2 + 1)
```
Directional Logic : Variables and functions manage the state of the indicator, updating highs and lows based on the current trend direction.
```pine
var bool dirUp = false
var float lastLow = high * 100
var float lastHigh = 0.0
// Additional variables for tracking state
```
Drawing Lines and Labels : Functions draw lines and labels on the chart to visualize market structure and trend changes.
```pine
f_drawLine() =>
_li_color = dirUp ? color.red : color.lime
line.new(x1=timeHigh - length, y1=lastHigh, x2=timeLow - length, y2=lastLow, color=_li_color, width=3, style=line.style_solid, xloc=xloc.bar_index)
f_drawLastLine() =>
_li_color = dirUp ? color.blue : color.blue
if timeHigh > timeLow
line.new(x1=timeHigh - length, y1=lastHigh, x2=bar_index, y2=low, color=_li_color, width=2, style=line.style_dotted, xloc=xloc.bar_index)
else
line.new(x1=timeLow - length, y1=lastLow, x2=bar_index, y2=high, color=_li_color, width=2, style=line.style_dotted, xloc=xloc.bar_index)
```
Updating Highs and Lows : The main logic updates highs and lows based on the current trend direction, adding labels for new higher highs, lower highs, higher lows, and lower lows.
```pine
if dirUp
if f_isMin(length)
lastLow := low
// Additional logic for updating lows and labels
if f_isMax(length) and high > lastLow
lastHigh := high
// Additional logic for updating highs and labels
dirUp := false
li := f_drawLine()
```
Swing Highs and Lows : The script identifies recent swing highs and swing lows based on a customizable swing length, drawing lines to mark these points.
```pine
swingLength = 3 * length
isSwingHigh = ta.highestbars(high, swingLength) == 0
isSwingLow = ta.lowestbars(low, swingLength) == 0
if (isSwingHigh)
if (na(highLine))
highLine := line.new(bar_index, high, bar_index, high, color=color.green, style=line.style_solid, width=1)
else
line.set_xy1(highLine, bar_index, high)
line.set_xy2(highLine, bar_index + swingLength, high)
if (isSwingLow)
if (na(lowLine))
lowLine := line.new(bar_index, low, bar_index, low, color=color.red, style=line.style_solid, width=1)
else
line.set_xy1(lowLine, bar_index, low)
line.set_xy2(lowLine, bar_index + swingLength, low)
```
How to Use
Configuring Inputs : Adjust the detection length and RSI length as needed. Modify the lookback periods to suit your trading strategy. The indicator is adaptable and can be used on any timeframe.
Interpreting the Indicator : Use the labels and lines to gauge market structure and trend direction. Look for higher highs, lower highs, higher lows, and lower lows to confirm market structure.
Signal Confirmation : Pay attention to the labels and lines that provide signals for potential trend changes and swing points. Use these signals to better time entries and exits.
This script provides a detailed view of market structure and swing points, helping make more informed decisions by considering key highs and lows, trend direction changes, and the strength or weakness of swing points.
DrFX MACD-RSI Reversal Algo with Dynamic ZonesOverview
This indicator identifies high-probability reversal points by combining MACD momentum crossovers with RSI trend confirmation, enhanced by dynamically calculated support and resistance zones. Unlike standard MACD crossover systems that generate numerous false signals in ranging markets, this approach adds three layers of confirmation: RSI directional bias, adaptive volatility zones, and Kalman-filtered zone boundaries to improve signal reliability.
Core Methodology
1. MACD Momentum Detection System
The indicator uses a customizable MACD configuration (default: 20-period fast, 50-period slow, 12-period signal smoothing) that is slower than the standard 12/26/9 setup. This longer timeframe reduces noise and focuses on more significant trend changes rather than short-term fluctuations.
Signal Generation Logic:
Buy Signal: MACD line crosses above signal line (momentum shifts bullish)
Sell Signal: MACD line crosses below signal line (momentum shifts bearish)
The MACD histogram's absolute value determines the "power" or strength of the current momentum, which is used for visual gradient effects and can help traders assess signal conviction.
2. RSI Trend Confirmation Layer
A 14-period RSI adds directional context to MACD crossovers by measuring whether price momentum aligns with the signal. The RSI value is normalized by subtracting 50, creating a zero-centered oscillator where:
Positive values indicate bullish bias (RSI > 50)
Negative values indicate bearish bias (RSI < 50)
Signal Classification System:
The combination of MACD crossover direction and RSI bias creates four signal types:
Strong Buy (Large green triangle): MACD crosses up + RSI > 50 = Bullish reversal with momentum confirmation
Buy (Small green triangle): MACD crosses up + RSI ≤ 50 = Bullish reversal without full momentum (weaker signal)
Strong Sell (Large red triangle): MACD crosses down + RSI < 50 = Bearish reversal with momentum confirmation
Sell (Small red triangle): MACD crosses down + RSI ≥ 0 = Bearish reversal without full momentum (weaker signal)
This tiered approach allows traders to prioritize "Strong" signals while still being aware of weaker setup opportunities.
3. Dynamic Support and Resistance Zone System
The indicator calculates adaptive support and resistance zones using a multi-step process:
Step A - Volatility Band Creation:
Uses ATR (Average True Range) with customizable period (default: 10 bars)
Calculates midpoint as (high + low) / 2
Creates upper and lower bands: midpoint ± (ATR × multiplier, default 5.0)
Step B - Swing Level Integration:
Identifies 20-period swing high (resistance reference)
Identifies 20-period swing low (support reference)
Combines these swing levels with the volatility bands to create zone boundaries
Step C - Kalman Filter Smoothing:
The raw zone boundaries are smoothed using a Kalman filter algorithm with parameters Q=0.01 (process noise) and R=0.1 (measurement noise). This removes erratic fluctuations while allowing the zones to adapt gradually to changing market structure.
The Kalman filter is a recursive algorithm that estimates the true position of a moving target from noisy measurements. In this context, it prevents the support/resistance zones from jumping erratically on each bar while still tracking genuine level shifts. The result is stable, predictable zone boundaries that move smoothly rather than making sudden adjustments.
4. Optional Zone Filter
Traders can enable an additional filter requiring:
Buy signals: Price must be above the support zone (confirming breakout potential)
Sell signals: Price must be below the resistance zone (confirming breakdown potential)
This filter eliminates signals that occur within the consolidation zones, focusing only on breakout opportunities.
5. Visual Momentum Feedback
Bar colors provide real-time feedback on trend strength:
Green gradient: Bullish (MACD histogram positive and rising + RSI > 50) - intensity increases with histogram strength
Red gradient: Bearish (MACD histogram negative and falling + RSI < 50) - intensity increases with histogram strength
Mixed colors: Consolidation phase (MACD and RSI not aligned) - transitions from red to green based on histogram power
The gradient range (default: 2000) controls how quickly colors intensify. Lower values create more dramatic color changes; higher values create subtler gradients.
Why This Combination Works
Standard MACD crossovers generate excessive signals in sideways markets because momentum oscillates frequently around the zero line. By requiring RSI confirmation, the indicator ensures that signals occur in the direction of the prevailing momentum, reducing counter-trend whipsaws by approximately 40-50%.
The dynamic zone system addresses another weakness of pure oscillator strategies: they don't account for price structure. By overlaying support/resistance zones, traders can distinguish between:
Signals occurring at established levels (higher probability)
Signals occurring mid-range (lower probability)
The Kalman filter smoothing is crucial because raw ATR bands can be choppy, causing zones to flash on and off the chart. The filtered zones remain stable enough for traders to use as actual reference levels rather than just visual noise.
How to Use This Indicator
Signal Interpretation Hierarchy:
Highest Priority: Strong Buy/Sell signals occurring at zone boundaries (confluence of momentum, trend, and structure)
Medium Priority: Strong Buy/Sell signals within zones (momentum + trend confirmation, but no structural support)
Lower Priority: Regular Buy/Sell signals at any location (divergent momentum, weaker setup)
Recommended Workflow:
Wait for a Strong Buy or Strong Sell signal (large triangle)
Verify price is near a support/resistance zone (or enable the zone filter)
Confirm bar color gradient shows intensifying momentum
Enter on signal bar close or on next bar open
Place stop loss beyond the opposite zone boundary
Target the opposite zone or use trailing stop once price enters profit zone
Parameter Optimization by Asset:
Forex Majors: Default settings work well; consider 15/35/9 MACD for faster signals on M15-H1
Gold/Metals: Increase ATR multiplier to 6-7 for wider zones; use 25/60/15 MACD for smoother signals
Indices: Reduce volatility period to 5-7 bars; keep default MACD
Cryptocurrencies: Increase ATR multiplier to 7-10 for extreme volatility; consider 14/35/7 MACD
Timeframe Recommendations:
M15-H1: Best for intraday reversal trading
H4-D1: Best for swing trading major turns
Weekly: Generates infrequent but high-quality macro reversal signals
Understanding the Visual Elements
Chart Overlays:
Blue shaded zone: Dynamic support area (safe zone for longs)
Red shaded zone: Dynamic resistance area (safe zone for shorts)
Green triangles: Buy signals (large = strong, small = regular)
Red triangles: Sell signals (large = strong, small = regular)
Bar Colors:
Bright green: Strong bullish momentum (both MACD and RSI bullish)
Dark green: Moderate bullish momentum
Bright red: Strong bearish momentum (both MACD and RSI bearish)
Dark red: Moderate bearish momentum
Mixed/transitional colors: Consolidation or conflicting indicators
What Makes This Original
While MACD, RSI, and ATR are standard indicators, this script's originality comes from:
The Kalman filter implementation for zone smoothing - not commonly applied to support/resistance in Pine Script
The four-tier signal classification system that combines MACD crossover direction with RSI positioning to create distinct signal strengths
The hybrid zone calculation merging ATR volatility bands with swing high/low levels, then applying recursive filtering
The gradient bar coloring system that visualizes momentum intensity rather than simple binary color switches
The zone-filtered alert system that optionally requires structural confirmation for signal validity
The combination transforms basic crossover signals into a context-aware reversal detection system that accounts for trend, momentum, and market structure simultaneously.
Practical Application Examples
Scenario 1 - Trending Market:
Price in uptrend, bounces off blue support zone
Strong Buy signal appears (MACD crosses up, RSI > 50)
Bar color shifts to bright green
Action: Enter long, stop below support zone, target resistance zone
Scenario 2 - Range-Bound Market:
Price oscillating between zones
Regular Buy signal appears mid-range (MACD up, RSI < 50)
Bar color mixed/transitional
Action: Skip signal or wait for Strong signal at zone boundary
Scenario 3 - False Breakout:
Price breaks above resistance zone briefly
Strong Sell signal appears (MACD crosses down, RSI < 50)
Bar color shifts to red
Action: Short opportunity on failed breakout
Alert System
The indicator includes built-in alerts with detailed information:
Symbol and timeframe identification
Current price level
Signal type (Buy or Sell)
Optional zone filtering applied
Alerts fire once per bar close (not on every tick) to prevent spam and ensure confirmed signals.
Important Notes
This is a reversal indicator, not a trend-following system - works best for catching turning points, not riding established trends
Strong signals have approximately 60-70% reliability; regular signals approximately 45-55% (varies by market)
Zone filtering significantly improves signal quality but reduces frequency (roughly 40% fewer signals)
The Kalman filter introduces minor lag (1-2 bars) in zone adaptation - this is intentional to prevent false level breaks
Performance degrades during low-volatility periods when MACD oscillates frequently around the zero line
Not suitable for news events or gap trading - designed for technical reversal scenarios
Customization Tips
For More Signals (Less Selective):
Reduce MACD slow length to 35-40
Disable zone filter
Reduce ATR multiplier to 3-4
For Fewer, Higher-Quality Signals:
Increase MACD slow length to 60-70
Enable zone filter
Increase ATR multiplier to 6-8
Focus only on Strong Buy/Sell signals
Trade PullBack - EMA Pullback System with Auto Risk-Reward# Trade Pull Back - Professional Pullback Trading System
## 📊 Overview
**Trade Pull Back** is a comprehensive pullback trading system that combines trend-following principles with precise entry timing using candlestick pattern confirmation. This indicator is designed for traders who want to enter trending markets at optimal retracement levels with pre-calculated risk-reward ratios.
---
## 🎯 Core Methodology
### Why This System Works
Most traders struggle with two key challenges:
1. **Entering too early** - jumping into trades before the pullback completes
2. **Entering too late** - missing the momentum after the pullback reverses
This system solves both problems by using a **3-Phase Confirmation Process**:
**Phase 1: Trend Identification** → **Phase 2: Pullback Detection** → **Phase 3: Reversal Confirmation**
---
## 🔧 How It Works
### 1. Triple EMA Framework (The Foundation)
Unlike traditional single EMA systems, this indicator uses **3 separate EMAs** with different purposes:
- **EMA Trend (default: 50)** - Determines the overall market direction
- Source: HL/2 for balanced trend reading
- Acts as the primary filter - we only trade in its direction
- **EMA High (default: 20)** - Dynamic resistance in uptrends
- Source: High prices for accurate resistance mapping
- Entry trigger for bullish setups when price closes above it
- **EMA Low (default: 20)** - Dynamic support in downtrends
- Source: Low prices for accurate support mapping
- Entry trigger for bearish setups when price closes below it
**Why 3 EMAs?**
- Single EMA can't distinguish between trend and pullback zones
- Two EMAs (like MACD) don't provide clear entry/exit levels
- Three EMAs create a **channel system** that identifies both trend direction AND optimal entry zones
### 2. Pattern Recognition Engine
The system detects two high-probability reversal patterns:
#### Engulfing Patterns
- **Bullish Engulfing**: Previous bearish candle completely engulfed by bullish candle
- **Bearish Engulfing**: Previous bullish candle completely engulfed by bearish candle
- Validates: Strong momentum reversal with volume confirmation
#### Pin Bar Patterns
- **Bullish Pin Bar (Hammer)**: Long lower wick (60%+ of total range) rejecting lower prices
- **Bearish Pin Bar (Inverted Hammer)**: Long upper wick (60%+ of total range) rejecting higher prices
- Validates: Institutional rejection at support/resistance levels
**Pattern Quality Filter:**
- Body-to-wick ratio must meet minimum standards
- Checks previous candle momentum
- Requires trend alignment before signaling
### 3. Pullback Confirmation System
The system includes **5 mandatory conditions** before generating a signal:
#### For Bullish Signals (BUY):
1. ✅ Close > EMA Trend (uptrend confirmed)
2. ✅ EMA High > EMA Trend AND EMA Low > EMA Trend (healthy trend structure)
3. ✅ Bullish Engulfing OR Bullish Pin Bar (pattern detected)
4. ✅ Close > EMA High (breakout confirmation)
5. ✅ Optional: Low < EMA High (pullback occurred)
#### For Bearish Signals (SELL):
1. ✅ Close < EMA Trend (downtrend confirmed)
2. ✅ EMA High < EMA Trend AND EMA Low < EMA Trend (healthy trend structure)
3. ✅ Bearish Engulfing OR Bearish Pin Bar (pattern detected)
4. ✅ Close < EMA Low (breakdown confirmation)
5. ✅ Optional: High > EMA Low (pullback occurred)
**Additional Filters:**
- **Consecutive Bars Check**: Ensures pullback had momentum (1-5 bearish/bullish bars)
- **Signal Spacing**: Minimum 4 bars between signals to avoid noise
- **Confirmation Delay**: Signal appears only AFTER bar closes (no repainting)
---
## 💰 Automatic Risk-Reward Calculator
### Smart Position Sizing
When a signal triggers, the system automatically calculates:
**For Long Positions:**
- **Entry**: High of signal candle
- **Stop Loss**: Lower of last 2 candle lows (protects against false breakouts)
- **Target 1 (1R)**: Entry + 1x Risk
- **Target 2 (2R)**: Entry + 2x Risk
- **Target 3 (3R)**: Entry + 3x Risk
**For Short Positions:**
- **Entry**: Low of signal candle
- **Stop Loss**: Higher of last 2 candle highs
- **Targets**: Calculated based on risk multiple
### Auto-Remove Feature
Lines and labels automatically disappear when:
- Price hits Stop Loss (trade invalidated)
- Price reaches 3R target (trade complete)
This keeps your chart clean and focuses only on active trades.
---
## 📈 Multi-Timeframe Trend Analysis
### Confluence Trading
The built-in MTF trend box shows trend status across 7 timeframes simultaneously:
- M1, M5, M15, M30, H1, H4, D1
**Color Coding:**
- 🟢 **Green**: Uptrend (Price > EMA Trend AND EMAs aligned bullish)
- 🔴 **Red**: Downtrend (Price < EMA Trend AND EMAs aligned bearish)
- ⚪ **Gray**: No clear trend
**Why This Matters:**
- Trade with higher timeframe trends for better win rate
- Avoid counter-trend trades when all timeframes show same direction
- Identify divergences between timeframes for reversal opportunities
---
## 🎨 Customization Options
### EMA Settings
- Adjust periods for different trading styles (scalping vs swing trading)
- Choose price sources (HL/2, Close, HLC/3) for sensitivity tuning
### Pattern Selection
- Enable/disable Engulfing patterns
- Enable/disable Pin Bar patterns
- Trade only your preferred pattern type
### Signal Filters
- **Require Pullback**: Force pullback condition (stricter entries)
- **Consecutive Bars**: Set momentum requirement (1-5 bars)
### Display Options
- Show/hide EMA lines
- Show/hide signals
- Enable/disable alerts
- Customize Risk-Reward line styles and extensions
---
## 📋 How to Use This Indicator
### Step 1: Identify the Trend
- Wait for price to establish clear direction relative to EMA Trend (50)
- Check MTF box to confirm higher timeframe alignment
### Step 2: Wait for Pullback
- In uptrend: Watch for price to pull back toward EMA High
- In downtrend: Watch for price to pull back toward EMA Low
### Step 3: Pattern Confirmation
- Look for Engulfing or Pin Bar pattern (triangle/diamond markers)
- Ensure pattern forms at or near the EMA High/Low zone
### Step 4: Entry & Risk Management
- Enter when signal appears (after bar closes)
- Use displayed Stop Loss and Take Profit levels
- Consider partial profits at 1R and 2R, let remainder run to 3R
### Step 5: Trade Management
- If price hits SL, lines disappear automatically (trade invalidated)
- If price reaches 3R, lines disappear (trade complete)
- Consider trailing stop after 1R is reached
---
## ⚙️ Recommended Settings
### For Scalping (M1-M5)
- EMA Trend: 20-30
- EMA High/Low: 10-15
- Require Pullback: OFF
- Consecutive Bars: 1
### For Day Trading (M15-H1)
- EMA Trend: 50 (default)
- EMA High/Low: 20 (default)
- Require Pullback: ON
- Consecutive Bars: 2-3
### For Swing Trading (H4-D1)
- EMA Trend: 100-200
- EMA High/Low: 50
- Require Pullback: ON
- Consecutive Bars: 3-5
---
## ✅ What Makes This Script Original
### 1. Systematic Approach
This isn't just a collection of indicators. It's a **complete trading system** with:
- Defined entry rules (5-point confirmation checklist)
- Automatic risk management (SL/TP calculation)
- Trade validation (consecutive bars, signal spacing)
### 2. Smart EMA Framework
The 3-EMA system creates a **dynamic channel** that adapts to market conditions:
- Trend EMA = Direction filter
- High/Low EMAs = Entry/Exit zones
- Together they form a "trade zone" that standard EMAs can't provide
### 3. Pattern Quality Control
Not all Engulfing or Pin Bar patterns are equal. This system:
- Validates body-to-wick ratios
- Checks previous candle momentum
- Requires trend alignment before signaling
### 4. Auto Risk-Reward Management
Most indicators just show signals. This one:
- Calculates exact entry prices
- Places stop loss at optimal location (lower of 2 lows)
- Projects 3 profit targets based on risk
- Auto-removes when trade is complete/invalidated
### 5. No Repainting
- All signals appear AFTER bar closes
- No future data leaking
- What you see in backtest = what you get in real-time
---
## 🚨 Alerts
Built-in alerts notify you when:
- Bullish signal confirmed
- Bearish signal confirmed
Alerts fire once per bar (no spam) and only after bar closes (no false alerts).
---
## 📊 Best Practices
### ✅ DO:
- Trade in direction of higher timeframe trends
- Wait for full confirmation (all 5 conditions met)
- Use proper position sizing (1-2% risk per trade)
- Let winners run to at least 2R
### ❌ DON'T:
- Trade against major trend on MTF box
- Enter before signal bar closes
- Ignore the Stop Loss level
- Overtrade - respect the 4-bar minimum spacing
---
## 🔍 Limitations
This indicator is a **tool**, not a crystal ball:
- No indicator wins 100% of the time
- False signals occur in choppy/ranging markets
- Best results in trending conditions
- Requires proper risk management
- Should be combined with fundamental analysis and market context
---
## 📚 Educational Value
This script teaches:
- How to combine trend following with mean reversion
- Pattern recognition and validation
- Risk-reward ratio calculation
- Multi-timeframe analysis
- Proper trade entry timing
---
## 🎓 Credits & Disclaimer
**Original Work**: All code written from scratch
**Methodology**: Based on classical technical analysis principles (EMA crossovers, candlestick patterns, support/resistance)
**Disclaimer**: This indicator is for educational purposes. Past performance does not guarantee future results. Always practice proper risk management.
---
## 📞 Support
If you find this indicator helpful:
- Leave a review
- Share with fellow traders
- Provide feedback for improvements
**Note**: This is a closed-source script to protect the proprietary signal logic and filtering algorithms. The description above provides comprehensive understanding of the methodology without revealing exact implementation details.
---
**Version**: 1.0
**Pine Script Version**: 5
**Type**: Indicator (Overlay)
**Category**: Trend Following + Pattern Recognition
---
*Happy Trading! 🚀*
# 🇹🇭 คู่มือภาษาไทย / Thai Guide
# Trade Pull Back - คู่มือภาษาไทย
## 📊 ภาพรวม
**Trade Pull Back** เป็นระบบเทรด Pullback ที่ผสมผสานการเทรดตามเทรนด์กับการจับจังหวะเข้าออเดอร์ด้วย Candlestick Pattern พร้อมคำนวณ Risk-Reward อัตโนมัติ
---
## 🎯 หลักการทำงาน
### ทำไมระบบนี้ได้ผล?
แก้ปัญหา 2 ข้อหลักของเทรดเดอร์:
1. **เข้าเร็วเกินไป** - เข้าก่อน Pullback เสร็จ
2. **เข้าช้าเกินไป** - พลาดโมเมนตัมหลังกลับตัว
**วิธีแก้**: ใช้กระบวนการยืนยัน 3 ขั้นตอน
- **ขั้น 1**: ระบุเทรนด์ → **ขั้น 2**: ตรวจจับ Pullback → **ขั้น 3**: ยืนยันการกลับตัว
---
## 🔧 ส่วนประกอบหลัก
### 1. ระบบ EMA 3 เส้น
ต่างจาก EMA ทั่วไป ระบบนี้ใช้ 3 เส้นที่มีหน้าที่แยกกัน:
- **EMA Trend (50)** - กำหนดทิศทางเทรนด์หลัก
- **EMA High (20)** - แนวต้านไดนามิก (สำหรับ Buy)
- **EMA Low (20)** - แนวรับไดนามิก (สำหรับ Sell)
**ทำไมต้อง 3 เส้น?**
- 1 เส้น = แยกเทรนด์กับ Pullback ไม่ได้
- 2 เส้น = ไม่มีจุด Entry/Exit ชัดเจน
- 3 เส้น = สร้าง Channel ที่บอกทั้งเทรนด์และโซนเข้าออเดอร์
### 2. ตรวจจับ Pattern
ระบบตรวจจับ 2 Pattern หลัก:
**Engulfing (แท่งกลืน)**
- Bullish: แท่งเขียวกลืนแท่งแดงทั้งหมด
- Bearish: แท่งแดงกลืนแท่งเขียวทั้งหมด
**Pin Bar (แท่งหาง)**
- Bullish: หางล่างยาว 60%+ ของช่วงทั้งหมด
- Bearish: หางบนยาว 60%+ ของช่วงทั้งหมด
### 3. เงื่อนไขยืนยันสัญญาณ (5 ข้อ)
**สัญญาณ Buy:**
1. ✅ ราคาปิด > EMA Trend (เทรนด์ขาขึ้น)
2. ✅ EMA High และ Low เหนือ EMA Trend (โครงสร้างดี)
3. ✅ เกิด Bullish Engulfing หรือ Pin Bar
4. ✅ ราคาปิด > EMA High (ยืนยัน Breakout)
5. ✅ ตัวเลือก: มี Pullback มาแตะ EMA High
**สัญญาณ Sell:**
1. ✅ ราคาปิด < EMA Trend (เทรนด์ขาลง)
2. ✅ EMA High และ Low ใต้ EMA Trend (โครงสร้างดี)
3. ✅ เกิด Bearish Engulfing หรือ Pin Bar
4. ✅ ราคาปิด < EMA Low (ยืนยัน Breakdown)
5. ✅ ตัวเลือก: มี Pullback มาแตะ EMA Low
**ตัวกรองเพิ่มเติม:**
- ต้องมีแท่งติดกัน 1-5 แท่ง (กำหนดได้)
- ห่างสัญญาณก่อนหน้าอย่างน้อย 4 แท่ง
- สัญญาณปรากฏหลังแท่งปิดเท่านั้น (ไม่ Repaint)
---
## 💰 คำนวณ Risk-Reward อัตโนมัติ
เมื่อสัญญาณเกิด ระบบคำนวณให้อัตโนมัติ:
**Long Position:**
- Entry = High ของแท่งสัญญาณ
- Stop Loss = Low ที่ต่ำกว่าของ 2 แท่งล่าสุด
- Target = 1R, 2R, 3R
**Short Position:**
- Entry = Low ของแท่งสัญญาณ
- Stop Loss = High ที่สูงกว่าของ 2 แท่งล่าสุด
- Target = 1R, 2R, 3R
**ลบอัตโนมัติ:** เส้นหายเมื่อราคาชน SL หรือถึง 3R
---
## 📈 กล่องเทรนด์หลาย Timeframe
แสดงเทรนด์พร้อมกัน 7 Timeframe:
- M1, M5, M15, M30, H1, H4, D1
**สีแสดงผล:**
- 🟢 เขียว = Uptrend
- 🔴 แดง = Downtrend
- ⚪ เทา = ไม่มีเทรนด์
**ประโยชน์:** เทรดตาม Timeframe ใหญ่เพื่อเพิ่ม Win Rate
---
## 📋 วิธีใช้งาน (5 ขั้นตอน)
1. **ระบุเทรนด์** - เช็คราคาเทียบกับ EMA Trend และกล่อง MTF
2. **รอ Pullback** - เฝ้าราคา Pullback มาที่ EMA High/Low
3. **เช็ค Pattern** - มองหาลูกศรสามเหลี่ยม (Engulfing) หรือเพชร (Pin Bar)
4. **เข้าออเดอร์** - เข้าเมื่อสัญญาณปรากฏ ใช้ SL/TP ที่แสดง
5. **จัดการเทรด** - เส้นจะหายเองเมื่อชน SL หรือถึง 3R
---
## ⚙️ การตั้งค่าแนะนำ
**Scalping (M1-M5)**
- EMA Trend: 20-30
- EMA High/Low: 10-15
- Require Pullback: ปิด
**Day Trading (M15-H1)**
- EMA Trend: 50 (ค่าเริ่มต้น)
- EMA High/Low: 20 (ค่าเริ่มต้น)
- Require Pullback: เปิด
**Swing Trading (H4-D1)**
- EMA Trend: 100-200
- EMA High/Low: 50
- Require Pullback: เปิด
---
## ✅ จุดเด่นที่แตกต่าง
1. **เป็นระบบสมบูรณ์** - ไม่ใช่แค่รวม Indicator
2. **EMA 3 เส้นสร้าง Channel** - บอกทั้งเทรนด์และโซนเข้า
3. **ตรวจสอบคุณภาพ Pattern** - ไม่ใช่ทุก Pattern ที่ให้สัญญาณ
4. **คำนวณ RR อัตโนมัติ** - วาง SL/TP ให้เลย
5. **ไม่ Repaint** - สัญญาณปรากฏหลังแท่งปิดเท่านั้น
---
## 📊 ควรทำ / ไม่ควรทำ
### ✅ ควรทำ:
- เทรดตามเทรนด์ Timeframe ใหญ่
- รอยืนยันครบ 5 เงื่อนไข
- เสี่ยง 1-2% ต่อเทรด
- ปล่อยกำไรไปอย่างน้อย 2R
### ❌ ไม่ควรทำ:
- เทรดทวนเทรนด์ในกล่อง MTF
- เข้าก่อนแท่งปิด
- ละเลย Stop Loss
- เทรดบ่อยเกินไป
---
## 🔍 ข้อจำกัด
- ไม่มี Indicator ไหนชนะ 100%
- สัญญาณผิดพลาดเกิดในตลาด Sideways
- ผลดีสุดในตลาดที่มีเทรนด์ชัด
- ต้องใช้ Money Management
- ควรดูปัจจัยพื้นฐานประกอบ
---
## 🎓 คำเตือน
**Disclaimer**: อินดิเคเตอร์นี้สำหรับการศึกษา ผลในอดีตไม่รับประกันอนาคต ใช้ Risk Management ที่เหมาะสมเสมอ
---
**เวอร์ชั่น**: 1.0
**Pine Script**: v5
**ประเภท**: Indicator (Overlay)
*Happy Trading! 🚀*
## Screenshots
**Bearish Signals with Risk-Reward:**
! (drive.google.com)
**Bullish Signal with Risk-Reward:**
! (drive.google.com)
**Multi-Timeframe Trend Box:**
! (drive.google.com)
**Settings Panel:**
! (drive.google.com)
ATAI Volume analysis with price action V 1.00ATAI Volume Analysis with Price Action
1. Introduction
1.1 Overview
ATAI Volume Analysis with Price Action is a composite indicator designed for TradingView. It combines per‑side volume data —that is, how much buying and selling occurs during each bar—with standard price‑structure elements such as swings, trend lines and support/resistance. By blending these elements the script aims to help a trader understand which side is in control, whether a breakout is genuine, when markets are potentially exhausted and where liquidity providers might be active.
The indicator is built around TradingView’s up/down volume feed accessed via the TradingView/ta/10 library. The following excerpt from the script illustrates how this feed is configured:
import TradingView/ta/10 as tvta
// Determine lower timeframe string based on user choice and chart resolution
string lower_tf_breakout = use_custom_tf_input ? custom_tf_input :
timeframe.isseconds ? "1S" :
timeframe.isintraday ? "1" :
timeframe.isdaily ? "5" : "60"
// Request up/down volume (both positive)
= tvta.requestUpAndDownVolume(lower_tf_breakout)
Lower‑timeframe selection. If you do not specify a custom lower timeframe, the script chooses a default based on your chart resolution: 1 second for second charts, 1 minute for intraday charts, 5 minutes for daily charts and 60 minutes for anything longer. Smaller intervals provide a more precise view of buyer and seller flow but cover fewer bars. Larger intervals cover more history at the cost of granularity.
Tick vs. time bars. Many trading platforms offer a tick / intrabar calculation mode that updates an indicator on every trade rather than only on bar close. Turning on one‑tick calculation will give the most accurate split between buy and sell volume on the current bar, but it typically reduces the amount of historical data available. For the highest fidelity in live trading you can enable this mode; for studying longer histories you might prefer to disable it. When volume data is completely unavailable (some instruments and crypto pairs), all modules that rely on it will remain silent and only the price‑structure backbone will operate.
Figure caption, Each panel shows the indicator’s info table for a different volume sampling interval. In the left chart, the parentheses “(5)” beside the buy‑volume figure denote that the script is aggregating volume over five‑minute bars; the center chart uses “(1)” for one‑minute bars; and the right chart uses “(1T)” for a one‑tick interval. These notations tell you which lower timeframe is driving the volume calculations. Shorter intervals such as 1 minute or 1 tick provide finer detail on buyer and seller flow, but they cover fewer bars; longer intervals like five‑minute bars smooth the data and give more history.
Figure caption, The values in parentheses inside the info table come directly from the Breakout — Settings. The first row shows the custom lower-timeframe used for volume calculations (e.g., “(1)”, “(5)”, or “(1T)”)
2. Price‑Structure Backbone
Even without volume, the indicator draws structural features that underpin all other modules. These features are always on and serve as the reference levels for subsequent calculations.
2.1 What it draws
• Pivots: Swing highs and lows are detected using the pivot_left_input and pivot_right_input settings. A pivot high is identified when the high recorded pivot_right_input bars ago exceeds the highs of the preceding pivot_left_input bars and is also higher than (or equal to) the highs of the subsequent pivot_right_input bars; pivot lows follow the inverse logic. The indicator retains only a fixed number of such pivot points per side, as defined by point_count_input, discarding the oldest ones when the limit is exceeded.
• Trend lines: For each side, the indicator connects the earliest stored pivot and the most recent pivot (oldest high to newest high, and oldest low to newest low). When a new pivot is added or an old one drops out of the lookback window, the line’s endpoints—and therefore its slope—are recalculated accordingly.
• Horizontal support/resistance: The highest high and lowest low within the lookback window defined by length_input are plotted as horizontal dashed lines. These serve as short‑term support and resistance levels.
• Ranked labels: If showPivotLabels is enabled the indicator prints labels such as “HH1”, “HH2”, “LL1” and “LL2” near each pivot. The ranking is determined by comparing the price of each stored pivot: HH1 is the highest high, HH2 is the second highest, and so on; LL1 is the lowest low, LL2 is the second lowest. In the case of equal prices the newer pivot gets the better rank. Labels are offset from price using ½ × ATR × label_atr_multiplier, with the ATR length defined by label_atr_len_input. A dotted connector links each label to the candle’s wick.
2.2 Key settings
• length_input: Window length for finding the highest and lowest values and for determining trend line endpoints. A larger value considers more history and will generate longer trend lines and S/R levels.
• pivot_left_input, pivot_right_input: Strictness of swing confirmation. Higher values require more bars on either side to form a pivot; lower values create more pivots but may include minor swings.
• point_count_input: How many pivots are kept in memory on each side. When new pivots exceed this number the oldest ones are discarded.
• label_atr_len_input and label_atr_multiplier: Determine how far pivot labels are offset from the bar using ATR. Increasing the multiplier moves labels further away from price.
• Styling inputs for trend lines, horizontal lines and labels (color, width and line style).
Figure caption, The chart illustrates how the indicator’s price‑structure backbone operates. In this daily example, the script scans for bars where the high (or low) pivot_right_input bars back is higher (or lower) than the preceding pivot_left_input bars and higher or lower than the subsequent pivot_right_input bars; only those bars are marked as pivots.
These pivot points are stored and ranked: the highest high is labelled “HH1”, the second‑highest “HH2”, and so on, while lows are marked “LL1”, “LL2”, etc. Each label is offset from the price by half of an ATR‑based distance to keep the chart clear, and a dotted connector links the label to the actual candle.
The red diagonal line connects the earliest and latest stored high pivots, and the green line does the same for low pivots; when a new pivot is added or an old one drops out of the lookback window, the end‑points and slopes adjust accordingly. Dashed horizontal lines mark the highest high and lowest low within the current lookback window, providing visual support and resistance levels. Together, these elements form the structural backbone that other modules reference, even when volume data is unavailable.
3. Breakout Module
3.1 Concept
This module confirms that a price break beyond a recent high or low is supported by a genuine shift in buying or selling pressure. It requires price to clear the highest high (“HH1”) or lowest low (“LL1”) and, simultaneously, that the winning side shows a significant volume spike, dominance and ranking. Only when all volume and price conditions pass is a breakout labelled.
3.2 Inputs
• lookback_break_input : This controls the number of bars used to compute moving averages and percentiles for volume. A larger value smooths the averages and percentiles but makes the indicator respond more slowly.
• vol_mult_input : The “spike” multiplier; the current buy or sell volume must be at least this multiple of its moving average over the lookback window to qualify as a breakout.
• rank_threshold_input (0–100) : Defines a volume percentile cutoff: the current buyer/seller volume must be in the top (100−threshold)%(100−threshold)% of all volumes within the lookback window. For example, if set to 80, the current volume must be in the top 20 % of the lookback distribution.
• ratio_threshold_input (0–1) : Specifies the minimum share of total volume that the buyer (for a bullish breakout) or seller (for bearish) must hold on the current bar; the code also requires that the cumulative buyer volume over the lookback window exceeds the seller volume (and vice versa for bearish cases).
• use_custom_tf_input / custom_tf_input : When enabled, these inputs override the automatic choice of lower timeframe for up/down volume; otherwise the script selects a sensible default based on the chart’s timeframe.
• Label appearance settings : Separate options control the ATR-based offset length, offset multiplier, label size and colors for bullish and bearish breakout labels, as well as the connector style and width.
3.3 Detection logic
1. Data preparation : Retrieve per‑side volume from the lower timeframe and take absolute values. Build rolling arrays of the last lookback_break_input values to compute simple moving averages (SMAs), cumulative sums and percentile ranks for buy and sell volume.
2. Volume spike: A spike is flagged when the current buy (or, in the bearish case, sell) volume is at least vol_mult_input times its SMA over the lookback window.
3. Dominance test: The buyer’s (or seller’s) share of total volume on the current bar must meet or exceed ratio_threshold_input. In addition, the cumulative sum of buyer volume over the window must exceed the cumulative sum of seller volume for a bullish breakout (and vice versa for bearish). A separate requirement checks the sign of delta: for bullish breakouts delta_breakout must be non‑negative; for bearish breakouts it must be non‑positive.
4. Percentile rank: The current volume must fall within the top (100 – rank_threshold_input) percent of the lookback distribution—ensuring that the spike is unusually large relative to recent history.
5. Price test: For a bullish signal, the closing price must close above the highest pivot (HH1); for a bearish signal, the close must be below the lowest pivot (LL1).
6. Labeling: When all conditions above are satisfied, the indicator prints “Breakout ↑” above the bar (bullish) or “Breakout ↓” below the bar (bearish). Labels are offset using half of an ATR‑based distance and linked to the candle with a dotted connector.
Figure caption, (Breakout ↑ example) , On this daily chart, price pushes above the red trendline and the highest prior pivot (HH1). The indicator recognizes this as a valid breakout because the buyer‑side volume on the lower timeframe spikes above its recent moving average and buyers dominate the volume statistics over the lookback period; when combined with a close above HH1, this satisfies the breakout conditions. The “Breakout ↑” label appears above the candle, and the info table highlights that up‑volume is elevated relative to its 11‑bar average, buyer share exceeds the dominance threshold and money‑flow metrics support the move.
Figure caption, In this daily example, price breaks below the lowest pivot (LL1) and the lower green trendline. The indicator identifies this as a bearish breakout because sell‑side volume is sharply elevated—about twice its 11‑bar average—and sellers dominate both the bar and the lookback window. With the close falling below LL1, the script triggers a Breakout ↓ label and marks the corresponding row in the info table, which shows strong down volume, negative delta and a seller share comfortably above the dominance threshold.
4. Market Phase Module (Volume Only)
4.1 Concept
Not all markets trend; many cycle between periods of accumulation (buying pressure building up), distribution (selling pressure dominating) and neutral behavior. This module classifies the current bar into one of these phases without using ATR , relying solely on buyer and seller volume statistics. It looks at net flows, ratio changes and an OBV‑like cumulative line with dual‑reference (1‑ and 2‑bar) trends. The result is displayed both as on‑chart labels and in a dedicated row of the info table.
4.2 Inputs
• phase_period_len: Number of bars over which to compute sums and ratios for phase detection.
• phase_ratio_thresh : Minimum buyer share (for accumulation) or minimum seller share (for distribution, derived as 1 − phase_ratio_thresh) of the total volume.
• strict_mode: When enabled, both the 1‑bar and 2‑bar changes in each statistic must agree on the direction (strict confirmation); when disabled, only one of the two references needs to agree (looser confirmation).
• Color customisation for info table cells and label styling for accumulation and distribution phases, including ATR length, multiplier, label size, colors and connector styles.
• show_phase_module: Toggles the entire phase detection subsystem.
• show_phase_labels: Controls whether on‑chart labels are drawn when accumulation or distribution is detected.
4.3 Detection logic
The module computes three families of statistics over the volume window defined by phase_period_len:
1. Net sum (buyers minus sellers): net_sum_phase = Σ(buy) − Σ(sell). A positive value indicates a predominance of buyers. The code also computes the differences between the current value and the values 1 and 2 bars ago (d_net_1, d_net_2) to derive up/down trends.
2. Buyer ratio: The instantaneous ratio TF_buy_breakout / TF_tot_breakout and the window ratio Σ(buy) / Σ(total). The current ratio must exceed phase_ratio_thresh for accumulation or fall below 1 − phase_ratio_thresh for distribution. The first and second differences of the window ratio (d_ratio_1, d_ratio_2) determine trend direction.
3. OBV‑like cumulative net flow: An on‑balance volume analogue obv_net_phase increments by TF_buy_breakout − TF_sell_breakout each bar. Its differences over the last 1 and 2 bars (d_obv_1, d_obv_2) provide trend clues.
The algorithm then combines these signals:
• For strict mode , accumulation requires: (a) current ratio ≥ threshold, (b) cumulative ratio ≥ threshold, (c) both ratio differences ≥ 0, (d) net sum differences ≥ 0, and (e) OBV differences ≥ 0. Distribution is the mirror case.
• For loose mode , it relaxes the directional tests: either the 1‑ or the 2‑bar difference needs to agree in each category.
If all conditions for accumulation are satisfied, the phase is labelled “Accumulation” ; if all conditions for distribution are satisfied, it’s labelled “Distribution” ; otherwise the phase is “Neutral” .
4.4 Outputs
• Info table row : Row 8 displays “Market Phase (Vol)” on the left and the detected phase (Accumulation, Distribution or Neutral) on the right. The text colour of both cells matches a user‑selectable palette (typically green for accumulation, red for distribution and grey for neutral).
• On‑chart labels : When show_phase_labels is enabled and a phase persists for at least one bar, the module prints a label above the bar ( “Accum” ) or below the bar ( “Dist” ) with a dashed or dotted connector. The label is offset using ATR based on phase_label_atr_len_input and phase_label_multiplier and is styled according to user preferences.
Figure caption, The chart displays a red “Dist” label above a particular bar, indicating that the accumulation/distribution module identified a distribution phase at that point. The detection is based on seller dominance: during that bar, the net buyer-minus-seller flow and the OBV‑style cumulative flow were trending down, and the buyer ratio had dropped below the preset threshold. These conditions satisfy the distribution criteria in strict mode. The label is placed above the bar using an ATR‑based offset and a dashed connector. By the time of the current bar in the screenshot, the phase indicator shows “Neutral” in the info table—signaling that neither accumulation nor distribution conditions are currently met—yet the historical “Dist” label remains to mark where the prior distribution phase began.
Figure caption, In this example the market phase module has signaled an Accumulation phase. Three bars before the current candle, the algorithm detected a shift toward buyers: up‑volume exceeded its moving average, down‑volume was below average, and the buyer share of total volume climbed above the threshold while the on‑balance net flow and cumulative ratios were trending upwards. The blue “Accum” label anchored below that bar marks the start of the phase; it remains on the chart because successive bars continue to satisfy the accumulation conditions. The info table confirms this: the “Market Phase (Vol)” row still reads Accumulation, and the ratio and sum rows show buyers dominating both on the current bar and across the lookback window.
5. OB/OS Spike Module
5.1 What overbought/oversold means here
In many markets, a rapid extension up or down is often followed by a period of consolidation or reversal. The indicator interprets overbought (OB) conditions as abnormally strong selling risk at or after a price rally and oversold (OS) conditions as unusually strong buying risk after a decline. Importantly, these are not direct trade signals; rather they flag areas where caution or contrarian setups may be appropriate.
5.2 Inputs
• minHits_obos (1–7): Minimum number of oscillators that must agree on an overbought or oversold condition for a label to print.
• syncWin_obos: Length of a small sliding window over which oscillator votes are smoothed by taking the maximum count observed. This helps filter out choppy signals.
• Volume spike criteria: kVolRatio_obos (ratio of current volume to its SMA) and zVolThr_obos (Z‑score threshold) across volLen_obos. Either threshold can trigger a spike.
• Oscillator toggles and periods: Each of RSI, Stochastic (K and D), Williams %R, CCI, MFI, DeMarker and Stochastic RSI can be independently enabled; their periods are adjustable.
• Label appearance: ATR‑based offset, size, colors for OB and OS labels, plus connector style and width.
5.3 Detection logic
1. Directional volume spikes: Volume spikes are computed separately for buyer and seller volumes. A sell volume spike (sellVolSpike) flags a potential OverBought bar, while a buy volume spike (buyVolSpike) flags a potential OverSold bar. A spike occurs when the respective volume exceeds kVolRatio_obos times its simple moving average over the window or when its Z‑score exceeds zVolThr_obos.
2. Oscillator votes: For each enabled oscillator, calculate its overbought and oversold state using standard thresholds (e.g., RSI ≥ 70 for OB and ≤ 30 for OS; Stochastic %K/%D ≥ 80 for OB and ≤ 20 for OS; etc.). Count how many oscillators vote for OB and how many vote for OS.
3. Minimum hits: Apply the smoothing window syncWin_obos to the vote counts using a maximum‑of‑last‑N approach. A candidate bar is only considered if the smoothed OB hit count ≥ minHits_obos (for OverBought) or the smoothed OS hit count ≥ minHits_obos (for OverSold).
4. Tie‑breaking: If both OverBought and OverSold spike conditions are present on the same bar, compare the smoothed hit counts: the side with the higher count is selected; ties default to OverBought.
5. Label printing: When conditions are met, the bar is labelled as “OverBought X/7” above the candle or “OverSold X/7” below it. “X” is the number of oscillators confirming, and the bracket lists the abbreviations of contributing oscillators. Labels are offset from price using half of an ATR‑scaled distance and can optionally include a dotted or dashed connector line.
Figure caption, In this chart the overbought/oversold module has flagged an OverSold signal. A sell‑off from the prior highs brought price down to the lower trend‑line, where the bar marked “OverSold 3/7 DeM” appears. This label indicates that on that bar the module detected a buy‑side volume spike and that at least three of the seven enabled oscillators—in this case including the DeMarker—were in oversold territory. The label is printed below the candle with a dotted connector, signaling that the market may be temporarily exhausted on the downside. After this oversold print, price begins to rebound towards the upper red trend‑line and higher pivot levels.
Figure caption, This example shows the overbought/oversold module in action. In the left‑hand panel you can see the OB/OS settings where each oscillator (RSI, Stochastic, Williams %R, CCI, MFI, DeMarker and Stochastic RSI) can be enabled or disabled, and the ATR length and label offset multiplier adjusted. On the chart itself, price has pushed up to the descending red trendline and triggered an “OverBought 3/7” label. That means the sell‑side volume spiked relative to its average and three out of the seven enabled oscillators were in overbought territory. The label is offset above the candle by half of an ATR and connected with a dashed line, signaling that upside momentum may be overextended and a pause or pullback could follow.
6. Buyer/Seller Trap Module
6.1 Concept
A bull trap occurs when price appears to break above resistance, attracting buyers, but fails to sustain the move and quickly reverses, leaving a long upper wick and trapping late entrants. A bear trap is the opposite: price breaks below support, lures in sellers, then snaps back, leaving a long lower wick and trapping shorts. This module detects such traps by looking for price structure sweeps, order‑flow mismatches and dominance reversals. It uses a scoring system to differentiate risk from confirmed traps.
6.2 Inputs
• trap_lookback_len: Window length used to rank extremes and detect sweeps.
• trap_wick_threshold: Minimum proportion of a bar’s range that must be wick (upper for bull traps, lower for bear traps) to qualify as a sweep.
• trap_score_risk: Minimum aggregated score required to flag a trap risk. (The code defines a trap_score_confirm input, but confirmation is actually based on price reversal rather than a separate score threshold.)
• trap_confirm_bars: Maximum number of bars allowed for price to reverse and confirm the trap. If price does not reverse in this window, the risk label will expire or remain unconfirmed.
• Label settings: ATR length and multiplier for offsetting, size, colours for risk and confirmed labels, and connector style and width. Separate settings exist for bull and bear traps.
• Toggle inputs: show_trap_module and show_trap_labels enable the module and control whether labels are drawn on the chart.
6.3 Scoring logic
The module assigns points to several conditions and sums them to determine whether a trap risk is present. For bull traps, the score is built from the following (bear traps mirror the logic with highs and lows swapped):
1. Sweep (2 points): Price trades above the high pivot (HH1) but fails to close above it and leaves a long upper wick at least trap_wick_threshold × range. For bear traps, price dips below the low pivot (LL1), fails to close below and leaves a long lower wick.
2. Close break (1 point): Price closes beyond HH1 or LL1 without leaving a long wick.
3. Candle/delta mismatch (2 points): The candle closes bullish yet the order flow delta is negative or the seller ratio exceeds 50%, indicating hidden supply. Conversely, a bearish close with positive delta or buyer dominance suggests hidden demand.
4. Dominance inversion (2 points): The current bar’s buyer volume has the highest rank in the lookback window while cumulative sums favor sellers, or vice versa.
5. Low‑volume break (1 point): Price crosses the pivot but total volume is below its moving average.
The total score for each side is compared to trap_score_risk. If the score is high enough, a “Bull Trap Risk” or “Bear Trap Risk” label is drawn, offset from the candle by half of an ATR‑scaled distance using a dashed outline. If, within trap_confirm_bars, price reverses beyond the opposite level—drops back below the high pivot for bull traps or rises above the low pivot for bear traps—the label is upgraded to a solid “Bull Trap” or “Bear Trap” . In this version of the code, there is no separate score threshold for confirmation: the variable trap_score_confirm is unused; confirmation depends solely on a successful price reversal within the specified number of bars.
Figure caption, In this example the trap module has flagged a Bear Trap Risk. Price initially breaks below the most recent low pivot (LL1), but the bar closes back above that level and leaves a long lower wick, suggesting a failed push lower. Combined with a mismatch between the candle direction and the order flow (buyers regain control) and a reversal in volume dominance, the aggregate score exceeds the risk threshold, so a dashed “Bear Trap Risk” label prints beneath the bar. The green and red trend lines mark the current low and high pivot trajectories, while the horizontal dashed lines show the highest and lowest values in the lookback window. If, within the next few bars, price closes decisively above the support, the risk label would upgrade to a solid “Bear Trap” label.
Figure caption, In this example the trap module has identified both ends of a price range. Near the highs, price briefly pushes above the descending red trendline and the recent pivot high, but fails to close there and leaves a noticeable upper wick. That combination of a sweep above resistance and order‑flow mismatch generates a Bull Trap Risk label with a dashed outline, warning that the upside break may not hold. At the opposite extreme, price later dips below the green trendline and the labelled low pivot, then quickly snaps back and closes higher. The long lower wick and subsequent price reversal upgrade the previous bear‑trap risk into a confirmed Bear Trap (solid label), indicating that sellers were caught on a false breakdown. Horizontal dashed lines mark the highest high and lowest low of the lookback window, while the red and green diagonals connect the earliest and latest pivot highs and lows to visualize the range.
7. Sharp Move Module
7.1 Concept
Markets sometimes display absorption or climax behavior—periods when one side steadily gains the upper hand before price breaks out with a sharp move. This module evaluates several order‑flow and volume conditions to anticipate such moves. Users can choose how many conditions must be met to flag a risk and how many (plus a price break) are required for confirmation.
7.2 Inputs
• sharp Lookback: Number of bars in the window used to compute moving averages, sums, percentile ranks and reference levels.
• sharpPercentile: Minimum percentile rank for the current side’s volume; the current buy (or sell) volume must be greater than or equal to this percentile of historical volumes over the lookback window.
• sharpVolMult: Multiplier used in the volume climax check. The current side’s volume must exceed this multiple of its average to count as a climax.
• sharpRatioThr: Minimum dominance ratio (current side’s volume relative to the opposite side) used in both the instant and cumulative dominance checks.
• sharpChurnThr: Maximum ratio of a bar’s range to its ATR for absorption/churn detection; lower values indicate more absorption (large volume in a small range).
• sharpScoreRisk: Minimum number of conditions that must be true to print a risk label.
• sharpScoreConfirm: Minimum number of conditions plus a price break required for confirmation.
• sharpCvdThr: Threshold for cumulative delta divergence versus price change (positive for bullish accumulation, negative for bearish distribution).
• Label settings: ATR length (sharpATRlen) and multiplier (sharpLabelMult) for positioning labels, label size, colors and connector styles for bullish and bearish sharp moves.
• Toggles: enableSharp activates the module; show_sharp_labels controls whether labels are drawn.
7.3 Conditions (six per side)
For each side, the indicator computes six boolean conditions and sums them to form a score:
1. Dominance (instant and cumulative):
– Instant dominance: current buy volume ≥ sharpRatioThr × current sell volume.
– Cumulative dominance: sum of buy volumes over the window ≥ sharpRatioThr × sum of sell volumes (and vice versa for bearish checks).
2. Accumulation/Distribution divergence: Over the lookback window, cumulative delta rises by at least sharpCvdThr while price fails to rise (bullish), or cumulative delta falls by at least sharpCvdThr while price fails to fall (bearish).
3. Volume climax: The current side’s volume is ≥ sharpVolMult × its average and the product of volume and bar range is the highest in the lookback window.
4. Absorption/Churn: The current side’s volume divided by the bar’s range equals the highest value in the window and the bar’s range divided by ATR ≤ sharpChurnThr (indicating large volume within a small range).
5. Percentile rank: The current side’s volume percentile rank is ≥ sharp Percentile.
6. Mirror logic for sellers: The above checks are repeated with buyer and seller roles swapped and the price break levels reversed.
Each condition that passes contributes one point to the corresponding side’s score (0 or 1). Risk and confirmation thresholds are then applied to these scores.
7.4 Scoring and labels
• Risk: If scoreBull ≥ sharpScoreRisk, a “Sharp ↑ Risk” label is drawn above the bar. If scoreBear ≥ sharpScoreRisk, a “Sharp ↓ Risk” label is drawn below the bar.
• Confirmation: A risk label is upgraded to “Sharp ↑” when scoreBull ≥ sharpScoreConfirm and the bar closes above the highest recent pivot (HH1); for bearish cases, confirmation requires scoreBear ≥ sharpScoreConfirm and a close below the lowest pivot (LL1).
• Label positioning: Labels are offset from the candle by ATR × sharpLabelMult (full ATR times multiplier), not half, and may include a dashed or dotted connector line if enabled.
Figure caption, In this chart both bullish and bearish sharp‑move setups have been flagged. Earlier in the range, a “Sharp ↓ Risk” label appears beneath a candle: the sell‑side score met the risk threshold, signaling that the combination of strong sell volume, dominance and absorption within a narrow range suggested a potential sharp decline. The price did not close below the lower pivot, so this label remains a “risk” and no confirmation occurred. Later, as the market recovered and volume shifted back to the buy side, a “Sharp ↑ Risk” label prints above a candle near the top of the channel. Here, buy‑side dominance, cumulative delta divergence and a volume climax aligned, but price has not yet closed above the upper pivot (HH1), so the alert is still a risk rather than a confirmed sharp‑up move.
Figure caption, In this chart a Sharp ↑ label is displayed above a candle, indicating that the sharp move module has confirmed a bullish breakout. Prior bars satisfied the risk threshold — showing buy‑side dominance, positive cumulative delta divergence, a volume climax and strong absorption in a narrow range — and this candle closes above the highest recent pivot, upgrading the earlier “Sharp ↑ Risk” alert to a full Sharp ↑ signal. The green label is offset from the candle with a dashed connector, while the red and green trend lines trace the high and low pivot trajectories and the dashed horizontals mark the highest and lowest values of the lookback window.
8. Market‑Maker / Spread‑Capture Module
8.1 Concept
Liquidity providers often “capture the spread” by buying and selling in almost equal amounts within a very narrow price range. These bars can signal temporary congestion before a move or reflect algorithmic activity. This module flags bars where both buyer and seller volumes are high, the price range is only a few ticks and the buy/sell split remains close to 50%. It helps traders spot potential liquidity pockets.
8.2 Inputs
• scalpLookback: Window length used to compute volume averages.
• scalpVolMult: Multiplier applied to each side’s average volume; both buy and sell volumes must exceed this multiple.
• scalpTickCount: Maximum allowed number of ticks in a bar’s range (calculated as (high − low) / minTick). A value of 1 or 2 captures ultra‑small bars; increasing it relaxes the range requirement.
• scalpDeltaRatio: Maximum deviation from a perfect 50/50 split. For example, 0.05 means the buyer share must be between 45% and 55%.
• Label settings: ATR length, multiplier, size, colors, connector style and width.
• Toggles : show_scalp_module and show_scalp_labels to enable the module and its labels.
8.3 Signal
When, on the current bar, both TF_buy_breakout and TF_sell_breakout exceed scalpVolMult times their respective averages and (high − low)/minTick ≤ scalpTickCount and the buyer share is within scalpDeltaRatio of 50%, the module prints a “Spread ↔” label above the bar. The label uses the same ATR offset logic as other modules and draws a connector if enabled.
Figure caption, In this chart the spread‑capture module has identified a potential liquidity pocket. Buyer and seller volumes both spiked above their recent averages, yet the candle’s range measured only a couple of ticks and the buy/sell split stayed close to 50 %. This combination met the module’s criteria, so it printed a grey “Spread ↔” label above the bar. The red and green trend lines link the earliest and latest high and low pivots, and the dashed horizontals mark the highest high and lowest low within the current lookback window.
9. Money Flow Module
9.1 Concept
To translate volume into a monetary measure, this module multiplies each side’s volume by the closing price. It tracks buying and selling system money default currency on a per-bar basis and sums them over a chosen period. The difference between buy and sell currencies (Δ$) shows net inflow or outflow.
9.2 Inputs
• mf_period_len_mf: Number of bars used for summing buy and sell dollars.
• Label appearance settings: ATR length, multiplier, size, colors for up/down labels, and connector style and width.
• Toggles: Use enableMoneyFlowLabel_mf and showMFLabels to control whether the module and its labels are displayed.
9.3 Calculations
• Per-bar money: Buy $ = TF_buy_breakout × close; Sell $ = TF_sell_breakout × close. Their difference is Δ$ = Buy $ − Sell $.
• Summations: Over mf_period_len_mf bars, compute Σ Buy $, Σ Sell $ and ΣΔ$ using math.sum().
• Info table entries: Rows 9–13 display these values as texts like “↑ USD 1234 (1M)” or “ΣΔ USD −5678 (14)”, with colors reflecting whether buyers or sellers dominate.
• Money flow status: If Δ$ is positive the bar is marked “Money flow in” ; if negative, “Money flow out” ; if zero, “Neutral”. The cumulative status is similarly derived from ΣΔ.Labels print at the bar that changes the sign of ΣΔ, offset using ATR × label multiplier and styled per user preferences.
Figure caption, The chart illustrates a steady rise toward the highest recent pivot (HH1) with price riding between a rising green trend‑line and a red trend‑line drawn through earlier pivot highs. A green Money flow in label appears above the bar near the top of the channel, signaling that net dollar flow turned positive on this bar: buy‑side dollar volume exceeded sell‑side dollar volume, pushing the cumulative sum ΣΔ$ above zero. In the info table, the “Money flow (bar)” and “Money flow Σ” rows both read In, confirming that the indicator’s money‑flow module has detected an inflow at both bar and aggregate levels, while other modules (pivots, trend lines and support/resistance) remain active to provide structural context.
In this example the Money Flow module signals a net outflow. Price has been trending downward: successive high pivots form a falling red trend‑line and the low pivots form a descending green support line. When the latest bar broke below the previous low pivot (LL1), both the bar‑level and cumulative net dollar flow turned negative—selling volume at the close exceeded buying volume and pushed the cumulative Δ$ below zero. The module reacts by printing a red “Money flow out” label beneath the candle; the info table confirms that the “Money flow (bar)” and “Money flow Σ” rows both show Out, indicating sustained dominance of sellers in this period.
10. Info Table
10.1 Purpose
When enabled, the Info Table appears in the lower right of your chart. It summarises key values computed by the indicator—such as buy and sell volume, delta, total volume, breakout status, market phase, and money flow—so you can see at a glance which side is dominant and which signals are active.
10.2 Symbols
• ↑ / ↓ — Up (↑) denotes buy volume or money; down (↓) denotes sell volume or money.
• MA — Moving average. In the table it shows the average value of a series over the lookback period.
• Σ (Sigma) — Cumulative sum over the chosen lookback period.
• Δ (Delta) — Difference between buy and sell values.
• B / S — Buyer and seller share of total volume, expressed as percentages.
• Ref. Price — Reference price for breakout calculations, based on the latest pivot.
• Status — Indicates whether a breakout condition is currently active (True) or has failed.
10.3 Row definitions
1. Up volume / MA up volume – Displays current buy volume on the lower timeframe and its moving average over the lookback period.
2. Down volume / MA down volume – Shows current sell volume and its moving average; sell values are formatted in red for clarity.
3. Δ / ΣΔ – Lists the difference between buy and sell volume for the current bar and the cumulative delta volume over the lookback period.
4. Σ / MA Σ (Vol/MA) – Total volume (buy + sell) for the bar, with the ratio of this volume to its moving average; the right cell shows the average total volume.
5. B/S ratio – Buy and sell share of the total volume: current bar percentages and the average percentages across the lookback period.
6. Buyer Rank / Seller Rank – Ranks the bar’s buy and sell volumes among the last (n) bars; lower rank numbers indicate higher relative volume.
7. Σ Buy / Σ Sell – Sum of buy and sell volumes over the lookback window, indicating which side has traded more.
8. Breakout UP / DOWN – Shows the breakout thresholds (Ref. Price) and whether the breakout condition is active (True) or has failed.
9. Market Phase (Vol) – Reports the current volume‑only phase: Accumulation, Distribution or Neutral.
10. Money Flow – The final rows display dollar amounts and status:
– ↑ USD / Σ↑ USD – Buy dollars for the current bar and the cumulative sum over the money‑flow period.
– ↓ USD / Σ↓ USD – Sell dollars and their cumulative sum.
– Δ USD / ΣΔ USD – Net dollar difference (buy minus sell) for the bar and cumulatively.
– Money flow (bar) – Indicates whether the bar’s net dollar flow is positive (In), negative (Out) or neutral.
– Money flow Σ – Shows whether the cumulative net dollar flow across the chosen period is positive, negative or neutral.
The chart above shows a sequence of different signals from the indicator. A Bull Trap Risk appears after price briefly pushes above resistance but fails to hold, then a green Accum label identifies an accumulation phase. An upward breakout follows, confirmed by a Money flow in print. Later, a Sharp ↓ Risk warns of a possible sharp downturn; after price dips below support but quickly recovers, a Bear Trap label marks a false breakdown. The highlighted info table in the center summarizes key metrics at that moment, including current and average buy/sell volumes, net delta, total volume versus its moving average, breakout status (up and down), market phase (volume), and bar‑level and cumulative money flow (In/Out).
11. Conclusion & Final Remarks
This indicator was developed as a holistic study of market structure and order flow. It brings together several well‑known concepts from technical analysis—breakouts, accumulation and distribution phases, overbought and oversold extremes, bull and bear traps, sharp directional moves, market‑maker spread bars and money flow—into a single Pine Script tool. Each module is based on widely recognized trading ideas and was implemented after consulting reference materials and example strategies, so you can see in real time how these concepts interact on your chart.
A distinctive feature of this indicator is its reliance on per‑side volume: instead of tallying only total volume, it separately measures buy and sell transactions on a lower time frame. This approach gives a clearer view of who is in control—buyers or sellers—and helps filter breakouts, detect phases of accumulation or distribution, recognize potential traps, anticipate sharp moves and gauge whether liquidity providers are active. The money‑flow module extends this analysis by converting volume into currency values and tracking net inflow or outflow across a chosen window.
Although comprehensive, this indicator is intended solely as a guide. It highlights conditions and statistics that many traders find useful, but it does not generate trading signals or guarantee results. Ultimately, you remain responsible for your positions. Use the information presented here to inform your analysis, combine it with other tools and risk‑management techniques, and always make your own decisions when trading.
Fundur - Market Sentiment A Fundur - Market Sentiment A: Complete Trading Indicator Guide
Indicator Overview
The Fundur - Market Sentiment A is a revolutionary multi-timeframe sentiment analysis indicator that combines advanced ZigZag pivot detection, wave-based structure analysis, and comprehensive market sentiment evaluation into one powerful trading tool. This indicator is designed to identify high-probability reversal points and trend continuations by analyzing market sentiment across 11 different timeframes simultaneously.
What Makes Market Sentiment A Unique?
Market Sentiment A is a sophisticated ZigZag system that utilizes the Market Sentiment B oscillator to perform advanced on-chart analysis against price action. By introducing Histogram-Correlated ZigZag Analysis - a breakthrough methodology that correlates sentiment histogram waves with actual price pivots to identify validated market extremes. Unlike static pivot indicators, Market Sentiment A provides dynamic analysis that adapts to changing market conditions while maintaining precise accuracy in pivot identification.
Core Methodology
The indicator operates on the principle that market sentiment oscillates in measurable waves that precede price movements. By analyzing sentiment patterns across multiple timeframes and correlating them with histogram wave behavior, traders can identify precise entry and exit points with quantifiable strength ratings and comprehensive wave event analysis.
Key Features
🎯 Revolutionary ZigZag System
Histogram-Correlated Detection : Unique correlation between sentiment waves and price pivots
Dynamic Speed Control : High, Medium, Low sensitivity settings for different market conditions
Validated Extremes : Only confirmed pivots are marked with comprehensive validation system
Real-Time Correlation : Live correlation between histogram turns and price extremes
📊 Multi-Timeframe Sentiment Engine
11 Timeframe Analysis : Simultaneous analysis across periods from 8 to 987 bars
Advanced Sentiment Calculation : Proprietary algorithm combining multiple sentiment factors
Momentum Wave Integration : 34-period momentum waves for trend context
Dynamic Smoothing : Optional smoothing for cleaner signals
🧠 Intelligent Wave Event Tracking
Green Wave Events : Bullish histogram wave analysis with comprehensive event detection
Red Wave Events : Bearish histogram wave analysis with detailed event tracking
Event Deduplication : Advanced system prevents duplicate event detection
10+ Event Types : MPIV, HTURN, TRI, SW, VOL, MDIV, HDIV, PDIV and more
⚖️ Advanced Strength Rating System
0-100 Strength Score : Comprehensive strength calculation for every pivot
Multi-Factor Analysis : Based on wave events, trend context, structure, and sentiment
Real-Time Calculation : Dynamic strength scoring as conditions change
Strength Breakdown : Detailed tooltip showing strength components
🎨 Sophisticated Visual System
Validated Pivot Labels : Clear ✓ markers for confirmed extremes
Structure Analysis : HH/HL/LH/LL structure identification with trend context
Dynamic ZigZag Lines : Connecting validated extremes with trend-based coloring
Bar Coloring Options : Momentum swings and market sentiment bar coloring
Comprehensive Tooltips : Detailed information on hover for every pivot
Setup Guide
Step 1: Adding the Indicator
Open TradingView and navigate to your desired chart
Click the "Indicators" button or press "/" key
Search for "Fundur - Market Sentiment A"
Add the indicator to your chart
Step 2: Core System Configuration
ZigZag System Settings
✅ Enable ZigZag System: ON (Core functionality)
ZigZag Speed : Choose based on your trading style:
High Speed : Most sensitive, fastest detection (2-bar lookback) - Best for scalping
Medium Speed : Balanced approach (3-bar lookback) - Recommended for most traders
Low Speed : Most reliable, slower detection (4-bar lookback) - Best for swing trading
✅ Show ZigZag Lines: ON (Visual connection of validated pivots)
Bar Coloring Settings
⚠️ Momentum Swings: OFF (Avoid visual clutter initially)
✅ Market Sentiment: ON (Primary sentiment-based bar coloring)
Step 3: Label Display Configuration
Essential Labels (Recommended Settings)
✅ Show Validated Pivots (✓): ON (Core validated extremes)
⚠️ Show Potential Turns (●): OFF (Reduces noise - enable once familiar)
⚠️ Show Structure Labels: OFF (Start clean, enable for advanced analysis)
⚠️ Include Trend in Structure Labels: OFF (Advanced feature)
✅ Show Strength Rating (💪): ON (Critical for trade quality assessment)
⚠️ Show Market Sentiment Wave Events: OFF (Advanced feature for later)
Label Visual Customization
Label Coloring : Standard (Highs=Red, Lows=Green)
Label Size : Normal
Label Transparency : 0%
Text Transparency : 0%
Step 4: Alert System Setup
✅ Enable Alerts: ON
⚠️ Alert Potential Bullish Turns: OFF (Disabled by design to prevent noise)
⚠️ Alert Potential Bearish Turns: OFF (Disabled by design to prevent noise)
✅ Alert ONLY on Confirmed Extremes: ON (High-quality signals only)
✅ Include Wave Events in Confirmed Alerts: ON (Comprehensive context)
Basic Trading Guide
Understanding the Dynamic ZigZag System
Market Sentiment A is fundamentally a Dynamic ZigZag System that displays validated highs and lows on your price chart. The indicator uses Market Sentiment B wave calculations internally to determine when sentiment waves finish, but these histograms and oscillators are NOT displayed on your chart .
What You See on Your Chart:
✓ Validated Highs : Red checkmarks marking confirmed resistance levels
✓ Validated Lows : Green checkmarks marking confirmed support levels
ZigZag Lines : Connecting validated extremes to show market structure
💪 Strength Ratings : 0-100 scores indicating signal quality
Structure Labels : HH/HL/LH/LL showing trend context
How Validation Works (Behind the Scenes):
High Validation : Uses Market Sentiment B wave analysis to confirm when a price high represents a true resistance level
Low Validation : Uses Market Sentiment B wave analysis to confirm when a price low represents a true support level
Dynamic Detection : Continuously monitors sentiment waves to validate extremes in real-time
Quality Filtering : Only displays the most significant highs and lows based on wave completion
Key Trading Concept:
Focus entirely on the validated highs and lows displayed on your chart. These represent dynamic support and resistance levels that have been confirmed by underlying sentiment analysis. The histogram and oscillator calculations happen internally - your trading decisions should be based on price action around these validated levels.
Entry Strategies
Primary Strategy: Dynamic Support/Resistance Reversals
Setup : Wait for validated pivot with ✓ marker and strength rating displayed on chart
Entry Timing : Enter on the bar when validation occurs or on pullback to the validated level
Direction : Counter-trend to the validated extreme (buy at validated lows/support, sell at validated highs/resistance)
Confirmation : Look for strength rating above 60 for higher probability setups
Structure Context : Consider overall trend using HH/HL/LH/LL structure labels
Secondary Strategy: ZigZag Trend Continuation
Setup : Identify trend direction using consecutive validated highs and lows
Entry : Enter in trend direction when price pulls back to previous validated level
Confirmation : Look for structure labels confirming trend (HH/HL for uptrend, LH/LL for downtrend)
Strength Filter : Use strength ratings above 70 for trend continuation entries
Stop Loss Methodology
For Long Positions (Validated Lows) : Place stop below the validated low price level
For Short Positions (Validated Highs) : Place stop above the validated high price level
Alternative Method : Use previous validated extreme in opposite direction as stop level
Structure-Based Method : Use significant validated levels that would invalidate the trade setup
Buffer Consideration : Add small buffer beyond validated level to account for wicks and spread
Profit Taking Strategy
For Long Positions (Validated Low Entries):
Target 1 : Previous validated high shown on chart (75% of position)
Target 2 : Next significant validated high or key resistance level (50% of remaining 25% = 12.5% of original position)
Target 3 : Extended targets using ZigZag structure analysis and trend context (remaining 12.5% of original position)
Management : Move stop loss to breakeven once first target (TP1) is executed
For Short Positions (Validated High Entries):
Target 1 : Previous validated low shown on chart (75% of position)
Target 2 : Next significant validated low or key support level (50% of remaining 25% = 12.5% of original position)
Target 3 : Extended targets using ZigZag structure analysis and trend context (remaining 12.5% of original position)
Management : Move stop loss to breakeven once first target (TP1) is executed
ZigZag Structure Trading Approach
Sideways Markets : Trade between validated highs and lows - buy at support, sell at resistance
Trending Markets : Use validated levels as pullback entry points in trend direction
Structure Breaks : Watch for breaks of significant validated levels to signal trend changes
Range Identification : Use consecutive validated highs and lows to identify trading ranges
Breakout Trading : Enter when price breaks beyond validated levels with strong momentum
Strength Rating Interpretation
Understanding the 0-100 Strength Score
The strength rating combines multiple factors:
Base Strength (25 points) : Fundamental pivot validation
Wave Events (12 points each) : Number and quality of wave events detected
Trend Context (5-10 points) : Alignment with overall trend direction
Structure Quality (3-8 points) : HH/HL/LH/LL structure strength
Sentiment Position (5-10 points) : Extreme sentiment readings
Momentum Context (5 points) : Momentum divergence confirmation
Strength Categories
90-100 : Exceptional strength - Highest probability setups
75-89 : Strong signal - High confidence trades
60-74 : Good signal - Solid trading opportunities
45-59 : Moderate signal - Use additional confirmation
30-44 : Weak signal - Proceed with caution
Below 30 : Very weak - Generally avoid
Wave Event Reference (Calculation Background)
Understanding Wave Events in Strength Calculations
Wave events are used internally by Market Sentiment A to calculate strength ratings and validate pivots. While these events may appear in alert messages or tooltips, they are not meant for direct trading decisions - they are calculation components that contribute to the overall strength score.
Key Wave Events (For Reference Only)
MPIV↑/MPIV↓ : Momentum pivot detection used in validation process
HTURN : Histogram turn identification used for wave completion
TRI↑/TRI↓ : Triangle pattern detection contributing to strength calculation
SW : Small wave indication affecting pivot quality assessment
VOL : Volume spike detection adding to strength scoring
MDIV↑/MDIV↓ : Momentum divergence contributing to validation strength
HDIV↑/HDIV↓ : Histogram divergence used in pivot confirmation
PDIV↑/PDIV↓ : Price divergence analysis for strength enhancement
How Wave Events Affect Your Trading
Strength Score Impact : More events generally result in higher strength ratings for validated pivots
Alert Context : Events may be mentioned in alerts to provide background on signal quality
Focus on Results : Instead of analyzing individual events, focus on the final strength rating and validated pivot levels
Trust the System : The indicator processes these events automatically - your job is to trade the validated highs and lows
Analysis Setups
Setup 1: Scalping Configuration (1-5 minute charts)
Core Settings:
ZigZag Speed: High (fastest detection for quick scalps)
Show Validated Pivots: ON
Show Strength Rating: ON
Bar Coloring: Market Sentiment
Visual Settings:
Label Size: Small (reduce visual clutter)
ZigZag Lines: ON
Potential Turns: ON (for immediate signals)
Trading Approach:
Focus on strength ratings above 70 for scalp entries
Quick entries at validated highs/lows with immediate execution
Tight stops just beyond validated levels
Target previous validated pivots shown on chart for quick profits
Use ZigZag structure to identify rapid reversal opportunities
Setup 2: Day Trading Configuration (5-15 minute charts)
Core Settings:
ZigZag Speed: Medium (balanced approach)
Show Validated Pivots: ON
Show Strength Rating: ON
Include Wave Events: ON (for context)
Visual Settings:
Label Size: Normal
Show Structure Labels: ON (for trend context)
ZigZag Lines: ON with trend coloring
Trading Approach:
Wait for strength ratings above 60 for quality setups
Use HH/HL/LH/LL structure labels for trend bias
Combine reversal trades at extremes with trend continuation at pullbacks
Hold positions targeting next validated pivot levels
Use ZigZag structure analysis for entry timing and market context
Setup 3: Swing Trading Configuration (1-4 hour charts)
Core Settings:
ZigZag Speed: Low (most reliable signals)
Show Validated Pivots: ON
Show Structure Labels: ON
Include Trend Analysis: ON
Visual Settings:
Label Size: Normal
Show all wave events for comprehensive analysis
Enable all alert types
Trading Approach:
Focus on strength ratings above 75 for swing positions
Emphasize trend continuation using ZigZag structure
Use validated level breaks for major position adjustments
Hold positions across multiple sessions targeting distant validated levels
Use comprehensive structure analysis (HH/HL/LH/LL) for entries/exits
Setup 4: Position Trading Configuration (4H-Daily charts)
Core Settings:
ZigZag Speed: Low (maximum reliability)
Show Validated Pivots: ON
Show Structure Labels: ON
Show all analysis features
Visual Settings:
Clean, comprehensive labeling
Full wave event display
Trend-based coloring for major bias
Trading Approach:
Only trade strength ratings above 80 for position entries
Focus on major ZigZag structure changes and validated level breaks
Use long-term structure analysis (HH/HL/LH/LL) for bias
Hold positions for weeks to months targeting major validated levels
Align with fundamental analysis and major market structure
Setup 5: Multi-Asset Analysis Configuration
For Forex Pairs:
Use Medium to Low speed settings
Focus on major session changes
Pay attention to news event correlation
Use strength ratings above 70
For Crypto Assets:
Medium speed for 24/7 market adaptation
Higher volatility requires strength above 75
Monitor weekend behavior patterns
Consider market sentiment cycles
For Stock Markets:
Align with market hours
Consider earnings and economic events
Use sector-specific analysis
Respect market close/open dynamics
Visual Components
Core Visual Elements
✓ Validated Pivots : Green checkmarks for confirmed lows, red for confirmed highs
● Potential Turns : Small dots showing histogram turn correlations (optional)
ZigZag Lines : Connecting validated extremes with trend-based coloring
💪 Strength Ratings : Numerical strength scores from 0-100
Structure Labels : HH/HL/LH/LL with trend context (optional)
Bar Coloring System
Market Sentiment Coloring : Based on sentiment oscillator position and momentum
Extreme Conditions : Special coloring for extreme overbought/oversold conditions
Momentum Swing Coloring : Alternative coloring based on momentum analysis
Advanced Visual Features
Wave Event Labels : Comprehensive event display within pivot labels
Trend Context : Dynamic trend identification and display
Strength Breakdown : Detailed tooltips showing strength components
Custom Coloring Modes : Standard vs trend-based coloring options
Alert System
Core Alert Types
Validated High Confirmed : When red wave validates ultimate high with full context
Validated Low Confirmed : When green wave validates ultimate low with full context
Trend Change Detected : When structure analysis detects trend shifts
Alert Message Structure
Each alert includes:
Timeframe identification
Signal type (BULLISH/BEARISH)
Structure context (HH/HL/LH/LL)
Strength score with 💪 rating
Exact price level
Wave events context (if enabled)
Setting Up Alerts
Enable desired alert types in indicator settings
Focus on "Confirmed Extremes" alerts for quality
Enable wave events for comprehensive context
Test alerts on historical data first
Set up multiple notification methods
Risk Management Framework
Strength-Based Position Sizing
Strength 90-100 : Maximum position size (3-5% risk)
Strength 75-89 : Large position size (2-3% risk)
Strength 60-74 : Standard position size (1-2% risk)
Strength 45-59 : Small position size (0.5-1% risk)
Below 45 : Avoid or minimal size (0.25% risk maximum)
Stop Loss Guidelines
Primary Method : Always use validated pivot levels for stops
Buffer Method : Add small buffer beyond validation level
Multiple Timeframe : Consider higher timeframe validated levels
Wave Event Context : Adjust stops based on event confluence
Risk-Reward Optimization
Minimum R:R : 1.5:1 for all trades
Preferred R:R : 2:1 or better for strength above 70
Exceptional Setups : 3:1+ for strength above 85
Position Management : Take 75% at TP1, 50% of remaining at TP2, close remaining at TP3
Stop Management : Move stop to breakeven after TP1 execution
Best Practices
Signal Quality Assessment
Always wait for validated pivots with ✓ checkmarks displayed on chart
Prioritize strength ratings above 60 for trade quality
Focus on the validated high/low levels rather than underlying calculations
Consider HH/HL/LH/LL structure labels for directional bias
Use ZigZag line connections to understand market structure flow
Entry Timing Optimization
Enter on validation bar or immediate pullback to validated level
Use lower timeframes for precise entry refinement around validated levels
Wait for strength score calculation completion before entry
Monitor price action around validated highs and lows
Consider multiple timeframe validated level alignment
Exit Strategy Management
Use opposite validated pivots displayed on chart as primary targets
Execute Fundur 3-stage exit: 75% at TP1, 12.5% at TP2, 12.5% at TP3
Move stop loss to breakeven immediately after TP1 execution
Monitor strength ratings of new validated levels that could reverse remaining position
Watch for structure changes (trend breaks) via HH/HL/LH/LL labels for early exit consideration
Common Mistakes to Avoid
Signal Interpretation Errors
Don't trade potential turns without ✓ validation markers
Never ignore strength ratings below 45 - they indicate weak signals
Don't chase signals after significant movement away from validated levels
Avoid overriding clear ZigZag structure and trend context
Don't ignore the relationship between consecutive validated highs and lows
Risk Management Failures
Never risk more than the strength score suggests for position sizing
Don't move stops against validated levels - they represent key structure
Avoid oversizing on "sure thing" setups - even high-strength signals can fail
Don't ignore multiple timeframe validated level context
Never trade without clear invalidation levels (validated highs/lows for stops)
System Usage Mistakes
Don't enable all features immediately - start simple
Avoid changing speed settings mid-session
Don't ignore alert system capabilities
Never disable core validation features
Don't overlook customization for your chart setup
Advanced Techniques
Multi-Timeframe ZigZag Analysis
Use higher timeframe validated levels for major bias and targets
Align lower timeframe entries with higher timeframe validated structure
Look for validated level confluence across timeframes
Monitor strength rating consistency of validated levels across periods
Advanced Structure Pattern Recognition
Identify recurring validated level patterns and their outcomes
Recognize high-probability ZigZag structure sequences
Use historical validated level patterns for target projection
Combine ZigZag analysis with other Fundur technical analysis tools
Advanced Alert Utilization
Create custom alert combinations based on strength thresholds
Use validated level break alerts for position management
Combine strength rating filters with validated pivot alerts
Develop systematic responses to different validated level types
Conclusion
The Fundur - Market Sentiment A indicator represents a breakthrough in technical analysis, providing a dynamic ZigZag system that displays validated highs and lows with unprecedented accuracy. By following the methodologies outlined in this guide and adapting the settings to your trading style, you can harness the full power of this sophisticated system for more precise and profitable trading decisions.
The key to success with Market Sentiment A lies in understanding that it is fundamentally a dynamic support and resistance system. Focus on the validated highs and lows displayed on your chart, use the strength ratings to assess signal quality, and leverage the structure analysis for trend context. Start with conservative settings, focus on high-strength signals, and gradually incorporate advanced features as you become familiar with the system's behavior across different market conditions.
Remember that this indicator provides the tools for identification and analysis - successful trading still requires proper risk management, psychological discipline, and continuous learning. Use the strength rating system as your primary guide, respect the validated pivot methodology, and always prioritize capital preservation over profit maximization.
SMC Structures and FVGสวัสดีครับ! ผมจะอธิบายอินดิเคเตอร์ "SMC Structures and FVG + MACD" ที่คุณให้มาอย่างละเอียดในแต่ละส่วน เพื่อให้คุณเข้าใจการทำงานของมันอย่างถ่องแท้ครับ
อินดิเคเตอร์นี้เป็นการผสมผสานแนวคิดของ Smart Money Concept (SMC) ซึ่งเน้นการวิเคราะห์โครงสร้างตลาด (Market Structure) และ Fair Value Gap (FVG) เข้ากับอินดิเคเตอร์ MACD เพื่อใช้เป็นตัวกรองหรือตัวยืนยันสัญญาณ Choch/BoS (Change of Character / Break of Structure)
1. ภาพรวมอินดิเคเตอร์ (Overall Purpose)
อินดิเคเตอร์นี้มีจุดประสงค์หลักคือ:
ระบุโครงสร้างตลาด: ตีเส้นและป้ายกำกับ Choch (Change of Character) และ BoS (Break of Structure) บนกราฟโดยอัตโนมัติ
ผสานการยืนยันด้วย MACD: สัญญาณ Choch/BoS จะถูกพิจารณาก็ต่อเมื่อ MACD Histogram เกิดการตัดขึ้นหรือลง (Zero Cross) ในทิศทางที่สอดคล้องกัน
แสดง Fair Value Gap (FVG): หากเปิดใช้งาน จะมีการตีกล่อง FVG บนกราฟ
แสดงระดับ Fibonacci: คำนวณและแสดงระดับ Fibonacci ที่สำคัญตามโครงสร้างตลาดปัจจุบัน
ปรับตาม Timeframe: การคำนวณและการแสดงผลทั้งหมดจะปรับตาม Timeframe ที่คุณกำลังใช้งานอยู่โดยอัตโนมัติ
2. ส่วนประกอบหลักของโค้ด (Code Breakdown)
โค้ดนี้สามารถแบ่งออกเป็นส่วนหลัก ๆ ได้ดังนี้:
2.1 Inputs (การตั้งค่า)
ส่วนนี้คือตัวแปรที่คุณสามารถปรับแต่งได้ในหน้าต่างการตั้งค่าของอินดิเคเตอร์ (คลิกที่รูปฟันเฟืองข้างชื่ออินดิเคเตอร์บนกราฟ)
MACD Settings (ตั้งค่า MACD):
fast_len: ความยาวของ Fast EMA สำหรับ MACD (ค่าเริ่มต้น 12)
slow_len: ความยาวของ Slow EMA สำหรับ MACD (ค่าเริ่มต้น 26)
signal_len: ความยาวของ Signal Line สำหรับ MACD (ค่าเริ่มต้น 9)
= ta.macd(close, fast_len, slow_len, signal_len): คำนวณค่า MACD Line, Signal Line และ Histogram โดยใช้ราคาปิด (close) และค่าความยาวที่กำหนด
is_bullish_macd_cross: ตรวจสอบว่า MACD Histogram ตัดขึ้นเหนือเส้น 0 (จากค่าลบเป็นบวก)
is_bearish_macd_cross: ตรวจสอบว่า MACD Histogram ตัดลงใต้เส้น 0 (จากค่าบวกเป็นลบ)
Fear Value Gap (FVG) Settings:
isFvgToShow: (Boolean) เปิด/ปิดการแสดง FVG บนกราฟ
bullishFvgColor: สีสำหรับ Bullish FVG
bearishFvgColor: สีสำหรับ Bearish FVG
mitigatedFvgColor: สีสำหรับ FVG ที่ถูก Mitigate (ลดทอน) แล้ว
fvgHistoryNbr: จำนวน FVG ย้อนหลังที่จะแสดง
isMitigatedFvgToReduce: (Boolean) เปิด/ปิดการลดขนาด FVG เมื่อถูก Mitigate
Structures (โครงสร้างตลาด) Settings:
isStructBodyCandleBreak: (Boolean) หากเป็น true การ Break จะต้องเกิดขึ้นด้วย เนื้อเทียน ที่ปิดเหนือ/ใต้ Swing High/Low หากเป็น false แค่ไส้เทียนทะลุก็ถือว่า Break
isCurrentStructToShow: (Boolean) เปิด/ปิดการแสดงเส้นโครงสร้างตลาดปัจจุบัน (เส้นสีน้ำเงินในภาพตัวอย่าง)
pivot_len: ความยาวของแท่งเทียนที่ใช้ในการมองหาจุด Pivot (Swing High/Low) ยิ่งค่าน้อยยิ่งจับ Swing เล็กๆ ได้, ยิ่งค่ามากยิ่งจับ Swing ใหญ่ๆ ได้
bullishBosColor, bearishBosColor: สีสำหรับเส้นและป้าย BOS ขาขึ้น/ขาลง
bosLineStyleOption, bosLineWidth: สไตล์ (Solid, Dotted, Dashed) และความหนาของเส้น BOS
bullishChochColor, bearishChochColor: สีสำหรับเส้นและป้าย CHoCH ขาขึ้น/ขาลง
chochLineStyleOption, chochLineWidth: สไตล์ (Solid, Dotted, Dashed) และความหนาของเส้น CHoCH
currentStructColor, currentStructLineStyleOption, currentStructLineWidth: สี, สไตล์ และความหนาของเส้นโครงสร้างตลาดปัจจุบัน
structHistoryNbr: จำนวนการ Break (Choch/BoS) ย้อนหลังที่จะแสดง
Structure Fibonacci (จากโค้ดต้นฉบับ):
เป็นชุด Input สำหรับเปิด/ปิด, กำหนดค่า, สี, สไตล์ และความหนาของเส้น Fibonacci Levels ต่างๆ (0.786, 0.705, 0.618, 0.5, 0.382) ที่จะถูกคำนวณจากโครงสร้างตลาดปัจจุบัน
2.2 Helper Functions (ฟังก์ชันช่วยทำงาน)
getLineStyle(lineOption): ฟังก์ชันนี้ใช้แปลงค่า String ที่เลือกจาก Input (เช่น "─", "┈", "╌") ให้เป็นรูปแบบ line.style_ ที่ Pine Script เข้าใจ
get_structure_highest_bar(lookback): ฟังก์ชันนี้พยายามหา Bar Index ของแท่งเทียนที่ทำ Swing High ภายในช่วง lookback ที่กำหนด
get_structure_lowest_bar(lookback): ฟังก์ชันนี้พยายามหา Bar Index ของแท่งเทียนที่ทำ Swing Low ภายในช่วง lookback ที่กำหนด
is_structure_high_broken(...): ฟังก์ชันนี้ตรวจสอบว่าราคาปัจจุบันได้ Break เหนือ _structureHigh (Swing High) หรือไม่ โดยพิจารณาจาก _highStructBreakPrice (ราคาปิดหรือราคา High ขึ้นอยู่กับการตั้งค่า isStructBodyCandleBreak)
FVGDraw(...): ฟังก์ชันนี้รับ Arrays ของ FVG Boxes, Types, Mitigation Status และ Labels มาประมวลผล เพื่ออัปเดตสถานะของ FVG (เช่น ถูก Mitigate หรือไม่) และปรับขนาด/ตำแหน่งของ FVG Box และ Label บนกราฟ
2.3 Global Variables (ตัวแปรทั่วทั้งอินดิเคเตอร์)
เป็นตัวแปรที่ประกาศด้วย var ซึ่งหมายความว่าค่าของมันจะถูกเก็บไว้และอัปเดตในแต่ละแท่งเทียน (persists across bars)
structureLines, structureLabels: Arrays สำหรับเก็บอ็อบเจกต์ line และ label ของเส้น Choch/BoS ที่วาดบนกราฟ
fvgBoxes, fvgTypes, fvgLabels, isFvgMitigated: Arrays สำหรับเก็บข้อมูลของ FVG Boxes และสถานะต่างๆ
structureHigh, structureLow: เก็บราคาของ Swing High/Low ที่สำคัญของโครงสร้างตลาดปัจจุบัน
structureHighStartIndex, structureLowStartIndex: เก็บ Bar Index ของจุดเริ่มต้นของ Swing High/Low ที่สำคัญ
structureDirection: เก็บสถานะของทิศทางโครงสร้างตลาด (1 = Bullish, 2 = Bearish, 0 = Undefined)
fiboXPrice, fiboXStartIndex, fiboXLine, fiboXLabel: ตัวแปรสำหรับเก็บข้อมูลและอ็อบเจกต์ของเส้น Fibonacci Levels
isBOSAlert, isCHOCHAlert: (Boolean) ใช้สำหรับส่งสัญญาณ Alert (หากมีการตั้งค่า Alert ไว้)
2.4 FVG Processing (การประมวลผล FVG)
ส่วนนี้จะตรวจสอบเงื่อนไขการเกิด FVG (Bullish FVG: high < low , Bearish FVG: low > high )
หากเกิด FVG และ isFvgToShow เป็น true จะมีการสร้าง box และ label ใหม่เพื่อแสดง FVG บนกราฟ
มีการจัดการ fvgBoxes และ fvgLabels เพื่อจำกัดจำนวน FVG ที่แสดงตาม fvgHistoryNbr และลบ FVG เก่าออก
ฟังก์ชัน FVGDraw จะถูกเรียกเพื่ออัปเดตสถานะของ FVG (เช่น การถูก Mitigate) และปรับการแสดงผล
2.5 Structures Processing (การประมวลผลโครงสร้างตลาด)
Initialization: ที่ bar_index == 0 (แท่งเทียนแรกของกราฟ) จะมีการกำหนดค่าเริ่มต้นให้กับ structureHigh, structureLow, structureHighStartIndex, structureLowStartIndex
Finding Current High/Low: highest, highestBar, lowest, lowestBar ถูกใช้เพื่อหา High/Low ที่สุดและ Bar Index ของมันใน 10 แท่งล่าสุด (หรือทั้งหมดหากกราฟสั้นกว่า 10 แท่ง)
Calculating Structure Max/Min Bar: structureMaxBar และ structureMinBar ใช้ฟังก์ชัน get_structure_highest_bar และ get_structure_lowest_bar เพื่อหา Bar Index ของ Swing High/Low ที่แท้จริง (ไม่ใช่แค่ High/Low ที่สุดใน lookback แต่เป็นจุด Pivot ที่สมบูรณ์)
Break Price: lowStructBreakPrice และ highStructBreakPrice จะเป็นราคาปิด (close) หรือราคา Low/High ขึ้นอยู่กับ isStructBodyCandleBreak
isStuctureLowBroken / isStructureHighBroken: เงื่อนไขเหล่านี้ตรวจสอบว่าราคาได้ทำลาย structureLow หรือ structureHigh หรือไม่ โดยพิจารณาจากราคา Break, ราคาแท่งก่อนหน้า และ Bar Index ของจุดเริ่มต้นโครงสร้าง
Choch/BoS Logic (ส่วนสำคัญที่ถูกผสานกับ MACD):
if(isStuctureLowBroken and is_bearish_macd_cross): นี่คือจุดที่ MACD เข้ามามีบทบาท หากราคาทำลาย structureLow (สัญญาณขาลง) และ MACD Histogram เกิด Bearish Zero Cross (is_bearish_macd_cross เป็น true) อินดิเคเตอร์จะพิจารณาว่าเป็น Choch หรือ BoS
หาก structureDirection == 1 (เดิมเป็นขาขึ้น) หรือ 0 (ยังไม่กำหนด) จะตีเป็น "CHoCH" (เปลี่ยนทิศทางโครงสร้างเป็นขาลง)
หาก structureDirection == 2 (เดิมเป็นขาลง) จะตีเป็น "BOS" (ยืนยันโครงสร้างขาลง)
มีการสร้าง line.new และ label.new เพื่อวาดเส้นและป้ายกำกับ
structureDirection จะถูกอัปเดตเป็น 1 (Bullish)
structureHighStartIndex, structureLowStartIndex, structureHigh, structureLow จะถูกอัปเดตเพื่อกำหนดโครงสร้างใหม่
else if(isStructureHighBroken and is_bullish_macd_cross): เช่นกันสำหรับขาขึ้น หากราคาทำลาย structureHigh (สัญญาณขาขึ้น) และ MACD Histogram เกิด Bullish Zero Cross (is_bullish_macd_cross เป็น true) อินดิเคเตอร์จะพิจารณาว่าเป็น Choch หรือ BoS
หาก structureDirection == 2 (เดิมเป็นขาลง) หรือ 0 (ยังไม่กำหนด) จะตีเป็น "CHoCH" (เปลี่ยนทิศทางโครงสร้างเป็นขาขึ้น)
หาก structureDirection == 1 (เดิมเป็นขาขึ้น) จะตีเป็น "BOS" (ยืนยันโครงสร้างขาขึ้น)
มีการสร้าง line.new และ label.new เพื่อวาดเส้นและป้ายกำกับ
structureDirection จะถูกอัปเดตเป็น 2 (Bearish)
structureHighStartIndex, structureLowStartIndex, structureHigh, structureLow จะถูกอัปเดตเพื่อกำหนดโครงสร้างใหม่
การลบเส้นเก่า: d.delete_line (หากไลบรารีทำงาน) จะถูกเรียกเพื่อลบเส้นและป้ายกำกับเก่าออกเมื่อจำนวนเกิน structHistoryNbr
Updating Structure High/Low (else block): หากไม่มีการ Break เกิดขึ้น แต่ราคาปัจจุบันสูงกว่า structureHigh หรือต่ำกว่า structureLow ในทิศทางที่สอดคล้องกัน (เช่น ยังคงเป็นขาขึ้นและทำ High ใหม่) structureHigh หรือ structureLow จะถูกอัปเดตเพื่อติดตาม High/Low ที่สุดของโครงสร้างปัจจุบัน
Current Structure Display:
หาก isCurrentStructToShow เป็น true อินดิเคเตอร์จะวาดเส้น structureHighLine และ structureLowLine เพื่อแสดงขอบเขตของโครงสร้างตลาดปัจจุบัน
Fibonacci Display:
หาก isFiboXToShow เป็น true อินดิเคเตอร์จะคำนวณและวาดเส้น Fibonacci Levels ต่างๆ (0.786, 0.705, 0.618, 0.5, 0.382) โดยอิงจาก structureHigh และ structureLow ของโครงสร้างตลาดปัจจุบัน
Alerts:
alertcondition: ใช้สำหรับตั้งค่า Alert ใน TradingView เมื่อเกิดสัญญาณ BOS หรือ CHOCH
plot(na):
plot(na) เป็นคำสั่งที่สำคัญในอินดิเคเตอร์ที่ไม่ได้ต้องการพล็อต Series ของข้อมูลบนกราฟ (เช่น ไม่ได้พล็อตเส้น EMA หรือ RSI) แต่ใช้วาดอ็อบเจกต์ (Line, Label, Box) โดยตรง
การมี plot(na) ช่วยให้ Pine Script รู้ว่าอินดิเคเตอร์นี้มีเอาต์พุตที่แสดงผลบนกราฟ แม้ว่าจะไม่ได้เป็น Series ที่พล็อตตามปกติก็ตาม
3. วิธีใช้งาน
คัดลอกโค้ดทั้งหมด ที่อยู่ในบล็อก immersive ด้านบน
ไปที่ TradingView และเปิดกราฟที่คุณต้องการ
คลิกที่เมนู "Pine Editor" ที่อยู่ด้านล่างของหน้าจอ
ลบโค้ดเดิมที่มีอยู่ และ วางโค้ดที่คัดลอกมา ลงไปแทน
คลิกที่ปุ่ม "Add to Chart"
อินดิเคเตอร์จะถูกเพิ่มลงในกราฟของคุณโดยอัตโนมัติ คุณสามารถคลิกที่รูปฟันเฟืองข้างชื่ออินดิเคเตอร์บนกราฟเพื่อเข้าถึงหน้าต่างการตั้งค่าและปรับแต่งตามความต้องการของคุณได้
Hello! I will explain the "SMC Structures and FVG + MACD" indicator you provided in detail, section by section, so you can fully understand how it works.This indicator combines the concepts of Smart Money Concept (SMC), which focuses on analyzing Market Structure and Fair Value Gaps (FVG), with the MACD indicator to serve as a filter or confirmation for Choch (Change of Character) and BoS (Break of Structure) signals.1. Overall PurposeThe main purposes of this indicator are:Identify Market Structure: Automatically draw lines and label Choch (Change of Character) and BoS (Break of Structure) on the chart.Integrate MACD Confirmation: Choch/BoS signals will only be considered when the MACD Histogram performs a cross (Zero Cross) in the corresponding direction.Display Fair Value Gap (FVG): If enabled, FVG boxes will be drawn on the chart.Display Fibonacci Levels: Calculate and display important Fibonacci levels based on the current market structure.Adapt to Timeframe: All calculations and displays will automatically adjust to the timeframe you are currently using.2. Code BreakdownThis code can be divided into the following main sections:2.1 Inputs (Settings)This section contains variables that you can adjust in the indicator's settings window (click the gear icon next to the indicator's name on the chart).MACD Settings:fast_len: Length of the Fast EMA for MACD (default 12)slow_len: Length of the Slow EMA for MACD (default 26)signal_len: Length of the Signal Line for MACD (default 9) = ta.macd(close, fast_len, slow_len, signal_len): Calculates the MACD Line, Signal Line, and Histogram using the closing price (close) and the specified lengths.is_bullish_macd_cross: Checks if the MACD Histogram crosses above the 0 line (from negative to positive).is_bearish_macd_cross: Checks if the MACD Histogram crosses below the 0 line (from positive to negative).Fear Value Gap (FVG) Settings:isFvgToShow: (Boolean) Enables/disables the display of FVG on the chart.bullishFvgColor: Color for Bullish FVG.bearishFvgColor: Color for Bearish FVG.mitigatedFvgColor: Color for FVG that has been mitigated.fvgHistoryNbr: Number of historical FVG to display.isMitigatedFvgToReduce: (Boolean) Enables/disables reducing the size of FVG when mitigated.Structures (โครงสร้างตลาด) Settings:isStructBodyCandleBreak: (Boolean) If true, the break must occur with the candle body closing above/below the Swing High/Low. If false, a wick break is sufficient.isCurrentStructToShow: (Boolean) Enables/disables the display of the current market structure lines (blue lines in the example image).pivot_len: Lookback length for identifying Pivot points (Swing High/Low). A smaller value captures smaller, more frequent swings; a larger value captures larger, more significant swings.bullishBosColor, bearishBosColor: Colors for bullish/bearish BOS lines and labels.bosLineStyleOption, bosLineWidth: Style (Solid, Dotted, Dashed) and width of BOS lines.bullishChochColor, bearishChochColor: Colors for bullish/bearish CHoCH lines and labels.chochLineStyleOption, chochLineWidth: Style (Solid, Dotted, Dashed) and width of CHoCH lines.currentStructColor, currentStructLineStyleOption, currentStructLineWidth: Color, style, and width of the current market structure lines.structHistoryNbr: Number of historical breaks (Choch/BoS) to display.Structure Fibonacci (from original code):A set of inputs to enable/disable, define values, colors, styles, and widths for various Fibonacci Levels (0.786, 0.705, 0.618, 0.5, 0.382) that will be calculated from the current market structure.2.2 Helper FunctionsgetLineStyle(lineOption): This function converts the selected string input (e.g., "─", "┈", "╌") into a line.style_ format understood by Pine Script.get_structure_highest_bar(lookback): This function attempts to find the Bar Index of the Swing High within the specified lookback period.get_structure_lowest_bar(lookback): This function attempts to find the Bar Index of the Swing Low within the specified lookback period.is_structure_high_broken(...): This function checks if the current price has broken above _structureHigh (Swing High), considering _highStructBreakPrice (closing price or high price depending on isStructBodyCandleBreak setting).FVGDraw(...): This function takes arrays of FVG Boxes, Types, Mitigation Status, and Labels to process and update the status of FVG (e.g., whether it's mitigated) and adjust the size/position of FVG Boxes and Labels on the chart.2.3 Global VariablesThese are variables declared with var, meaning their values are stored and updated on each bar (persists across bars).structureLines, structureLabels: Arrays to store line and label objects for Choch/BoS lines drawn on the chart.fvgBoxes, fvgTypes, fvgLabels, isFvgMitigated: Arrays to store FVG box data and their respective statuses.structureHigh, structureLow: Stores the price of the significant Swing High/Low of the current market structure.structureHighStartIndex, structureLowStartIndex: Stores the Bar Index of the start point of the significant Swing High/Low.structureDirection: Stores the status of the market structure direction (1 = Bullish, 2 = Bearish, 0 = Undefined).fiboXPrice, fiboXStartIndex, fiboXLine, fiboXLabel: Variables to store data and objects for Fibonacci Levels.isBOSAlert, isCHOCHAlert: (Boolean) Used to trigger alerts in TradingView (if alerts are configured).2.4 FVG ProcessingThis section checks the conditions for FVG formation (Bullish FVG: high < low , Bearish FVG: low > high ).If FVG occurs and isFvgToShow is true, a new box and label are created to display the FVG on the chart.fvgBoxes and fvgLabels are managed to limit the number of FVG displayed according to fvgHistoryNbr and remove older FVG.The FVGDraw function is called to update the FVG status (e.g., whether it's mitigated) and adjust its display.2.5 Structures ProcessingInitialization: At bar_index == 0 (the first bar of the chart), structureHigh, structureLow, structureHighStartIndex, and structureLowStartIndex are initialized.Finding Current High/Low: highest, highestBar, lowest, lowestBar are used to find the highest/lowest price and its Bar Index of it in the last 10 bars (or all bars if the chart is shorter than 10 bars).Calculating Structure Max/Min Bar: structureMaxBar and structureMinBar use get_structure_highest_bar and get_structure_lowest_bar functions to find the Bar Index of the true Swing High/Low (not just the highest/lowest in the lookback but a complete Pivot point).Break Price: lowStructBreakPrice and highStructBreakPrice will be the closing price (close) or the Low/High price, depending on the isStructBodyCandleBreak setting.isStuctureLowBroken / isStructureHighBroken: These conditions check if the price has broken structureLow or structureHigh, considering the break price, previous bar prices, and the Bar Index of the structure's starting point.Choch/BoS Logic (Key Integration with MACD):if(isStuctureLowBroken and is_bearish_macd_cross): This is where MACD plays a role. If the price breaks structureLow (bearish signal) AND the MACD Histogram performs a Bearish Zero Cross (is_bearish_macd_cross is true), the indicator will consider it a Choch or BoS.If structureDirection == 1 (previously bullish) or 0 (undefined), it will be labeled "CHoCH" (changing structure direction to bearish).If structureDirection == 2 (already bearish), it will be labeled "BOS" (confirming bearish structure).line.new and label.new are used to draw the line and label.structureDirection will be updated to 1 (Bullish).structureHighStartIndex, structureLowStartIndex, structureHigh, structureLow will be updated to define the new structure.else if(isStructureHighBroken and is_bullish_macd_cross): Similarly for bullish breaks. If the price breaks structureHigh (bullish signal) AND the MACD Histogram performs a Bullish Zero Cross (is_bullish_macd_cross is true), the indicator will consider it a Choch or BoS.If structureDirection == 2 (previously bearish) or 0 (undefined), it will be labeled "CHoCH" (changing structure direction to bullish).If structureDirection == 1 (already bullish), it will be labeled "BOS" (confirming bullish structure).line.new and label.new are used to draw the line and label.structureDirection will be updated to 2 (Bearish).structureHighStartIndex, structureLowStartIndex, structureHigh, structureLow will be updated to define the new structure.Deleting Old Lines: d.delete_line (if the library works) will be called to delete old lines and labels when their number exceeds structHistoryNbr.Updating Structure High/Low (else block): If no break occurs, but the current price is higher than structureHigh or lower than structureLow in the corresponding direction (e.g., still bullish and making a new high), structureHigh or structureLow will be updated to track the highest/lowest point of the current structure.Current Structure Display:If isCurrentStructToShow is true, the indicator draws structureHighLine and structureLowLine to show the boundaries of the current market structure.Fibonacci Display:If isFiboXToShow is true, the indicator calculates and draws various Fibonacci Levels (0.786, 0.705, 0.618, 0.5, 0.382) based on the structureHigh and structureLow of the current market structure.Alerts:alertcondition: Used to set up alerts in TradingView when BOS or CHOCH signals occur.plot(na):plot(na) is an important statement in indicators that do not plot data series directly on the chart (e.g., not plotting EMA or RSI lines) but instead draw objects (Line, Label, Box).Having plot(na) helps Pine Script recognize that this indicator has an output displayed on the chart, even if it's not a regularly plotted series.3. How to UseCopy all the code in the immersive block above.Go to TradingView and open your desired chart.Click on the "Pine Editor" menu at the bottom of the screen.Delete any existing code and paste the copied code in its place.Click the "Add to Chart" button.The indicator will be added to your chart automatically. You can click the gear icon next to the indicator's name on the chart to access the settings window and customize it to your needs.I hope this explanation helps you understand this indicator in detail. If anything is unclear, or you need further adjustments, please let me know.