QARAR Unified EGX Market Map
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «indicator qarar unified egx market map for tradingview.pine» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Индикатор «QARAR Unified EGX Market Map» — это многоуровневый инструмент технического анализа для TradingView, написанный на Pine Script v6. Он отображает на графике три основных слоя: относительную волну акции, качающийся тренд и зоны поддержки/сопротивления.
Слой «Относительная волна» сравнивает динамику выбранной акции с индексами EGX30, EGX70EWI и EGX100EWI, рассчитывая процентное отклонение за заданный период и сглаживая его скользящей средней. Результаты отображаются в виде линий, заливок и горизонтальных уровней, а также в виде таблицы-дашборда с указанием состояния (лидер, отстающий, сильный или слабый относительно рынка).
Слой «Качающийся тренд» строит адаптивную линию тренда на основе ATR с настраиваемыми длинами быстрой и медленной склонности, определяя развороты при достижении заданных порогов. Слой «Зоны S/R» выявляет зоны поддержки и сопротивления по пивотам, оценивает их силу с учётом объёма и свечей, отрисовывает графические зоны с метками и поддерживает визуальную карту исторических зон.
Индикатор предоставляет настраиваемые параметры отображения каждого слоя, дашборды с информацией о состоянии зон и условия оповещений для обнаружения пробоев спроса и предложения. Продукт работает в режиме индикатора (не является торговым советником).
Настройки программы
| Настройка | Описание |
|---|---|
| showRelativeWave | Включает или отключает отображение слоя относительной волны |
| showRollingTrend | Включает или отключает отображение качающегося тренда |
| showSRZones | Включает или отключает отображение зон поддержки и сопротивления |
| showWaveDash | Включает или отключает дашборд относительной волны |
| showSRDash | Включает или отключает дашборд зон поддержки и сопротивления |
| baseLen | Период lookback для расчёта базовой цены при определении относительной волны |
| smoothLen | Период сглаживания для расчёта волны производительности |
| lineWidth | Толщина линий отображения относительной волны |
| fastLengthInput | Длина периода для быстрой склонности в качающемся тренде |
| slowLengthInput | Длина периода для медленной склонности в качающемся тренде |
| atrLengthInput | Длина периода для расчёта ATR, используемого в качающемся тренде |
| fastThresholdInput | Порог ATR для перехода в режим быстрой склонности качающегося тренда |
| reverseThresholdInput | Порог ATR для определения разворота тренда в качающемся тренде |
| useSRZoneEngine | Включает или отключает движок зон поддержки и сопротивления |
| pivotLen | Параметр устойчивости пивотов для определения зон поддержки и сопротивления |
| srAtrLen | Длина периода ATR для расчёта зон поддержки и сопротивления |
| srZoneDepthMult | Множитель ATR для определения глубины зоны поддержки или сопротивления |
| srBreakBufferMult | Множитель ATR для буфера пробоя/принятия при формировании зон S/R |
| srRetestToleranceATR | Множитель ATR для допуска при повторном тестировании/возврате к зоне S/R |
| showSRVisualMap | Включает или отключает визуальную карту исторических зон поддержки и сопротивления |
| srVisualMaxZones | Максимальное количество исторических зон на карте |
| srVisualExtendRight | Продлевать зоны поддержки и сопротивления вправо от текущего бара |
| srVisualFadeOld | Плавно затухать старые зоны на карте |
| srVisualShowLabels | Отображать текстовые метки на основных зонах |
| srVisualMinGapATR | Минимальный зазор между зонами в единицах ATR |
| srVisualMinStrength | Минимальная сила зоны для отображения на карте |
| srVisualMajorStrength | Порог силы для определения основной зоны поддержки или сопротивления |
| srVisualShowBroken | Отображать пробитые зоны поддержки и сопротивления |
| srVisualMaxBroken | Максимальное количество видимых пробитых зон |
| srVisualAgeLimit | Количество баров после которого слабые зоны скрываются |
| srVisualMinEntriesMajor | Минимальное количество касаний для признания зоны основной |
| srVisualSweepBoost | Бонус к силе зоны при обнаружении пробоя/отклонения |
| srVisualVolumeBoost | Бонус к силе зоны при реакции на высокий объём |
| useResistanceHeatMap | Включает цветовую заливку зон в зависимости от их силы |
| visibilityMode | Режим видимости зон: Clean, Genesis или Full |
| showOnlyMajorLabels | Отображать метки только для основных зон поддержки и сопротивления |
| volLen | Период скользящей средней объёма для реакции на объём |
| volReactionMult | Множитель для определения высокого объёма при реакции на зону |
| dashPosInput | Позиция дашборда зон поддержки и сопротивления на графике |
Поиск по коду файла
indicator("QARAR Unified EGX Market Map", "QARAR Market Map", overlay=false, max_bars_back=5000, max_boxes_count=500, max_labels_count=500, max_lines_count=500, dynamic_requests=true)
masterGroup = "0) Layer Controls"
showRelativeWave = input.bool(true, "Show Relative Wave", group=masterGroup)
showRollingTrend = input.bool(true, "Show Rolling Trend", group=masterGroup)
showSRZones = input.bool(true, "Show S/R Zones", group=masterGroup)
showWaveDash = input.bool(true, "Show Relative Wave Dashboard", group=masterGroup)
showSRDash = input.bool(false, "Show S/R Dashboard", group=masterGroup)
waveGroup = "1) QARAR Relative Wave"
baseLen = input.int(120, "Wave Base Lookback", minval=20, maxval=500, group=waveGroup)
smoothLen = input.int(5, "Wave Smoothing", minval=1, maxval=50, group=waveGroup)
lineWidth = input.int(2, "Line Width", minval=1, maxval=4, group=waveGroup)
egx30 = request.security("EGX:EGX30", timeframe.period, close, ignore_invalid_symbol=true)
egx70 = request.security("EGX:EGX70EWI", timeframe.period, close, ignore_invalid_symbol=true)
egx100 = request.security("EGX:EGX100EWI", timeframe.period, close, ignore_invalid_symbol=true)
baseStock = close[baseLen]
base30 = egx30[baseLen]
base70 = egx70[baseLen]
base100 = egx100[baseLen]
ready30 = not na(baseStock) and not na(base30) and baseStock != 0 and base30 != 0
ready70 = not na(baseStock) and not na(base70) and baseStock != 0 and base70 != 0
ready100 = not na(baseStock) and not na(base100) and baseStock != 0 and base100 != 0
stockPerf = not na(baseStock) and baseStock != 0 ? (close / baseStock - 1.0) * 100.0 : na
egx30Perf = ready30 ? (egx30 / base30 - 1.0) * 100.0 : na
egx70Perf = ready70 ? (egx70 / base70 - 1.0) * 100.0 : na
egx100Perf = ready100 ? (egx100 / base100 - 1.0) * 100.0 : na
stockWave = ta.ema(stockPerf, smoothLen)
egx30Wave = ta.ema(egx30Perf, smoothLen)
egx70Wave = ta.ema(egx70Perf, smoothLen)
egx100Wave = ta.ema(egx100Perf, smoothLen)
rs30 = stockWave - egx30Wave
rs70 = stockWave - egx70Wave
rs100 = stockWave - egx100Wave
avgRS = (nz(rs30) + nz(rs70) + nz(rs100)) / 3.0
leaderAll = rs30 > 0 and rs70 > 0 and rs100 > 0
weakAll = rs30 < 0 and rs70 < 0 and rs100 < 0
waveState = leaderAll ? "MARKET LEADER" : weakAll ? "MARKET LAGGARD" : avgRS > 0 ? "RELATIVE STRONG" : "RELATIVE WEAK"
waveStateColor = waveState == "MARKET LEADER" ? color.green : waveState == "RELATIVE STRONG" ? color.teal : waveState == "MARKET LAGGARD" ? color.red : color.orange
hline(0, "Zero", color=showRelativeWave ? color.gray : color.new(color.gray, 100))
hline(10, "Plus 10%", color=showRelativeWave ? color.new(color.green, 70) : color.new(color.green, 100), linestyle=hline.style_dotted)
hline(-10, "Minus 10%", color=showRelativeWave ? color.new(color.red, 70) : color.new(color.red, 100), linestyle=hline.style_dotted)
stockPlot = plot(showRelativeWave ? stockWave : na, "Stock Performance", color=color.aqua, linewidth=3)
egx30Plot = plot(showRelativeWave ? egx30Wave : na, "EGX30 Performance", color=color.yellow, linewidth=2)
egx70Plot = plot(showRelativeWave ? egx70Wave : na, "EGX70 Performance", color=color.new(color.orange, 75), linewidth=1)
egx100Plot = plot(showRelativeWave ? egx100Wave : na, "EGX100 Performance", color=color.new(color.purple, 80), linewidth=1)
plot(showRelativeWave ? rs30 : na, "Stock vs EGX30", style=plot.style_area, color=rs30 >= 0 ? color.new(color.green, 82) : color.new(color.red, 82))
plot(showRelativeWave ? rs70 : na, "Stock vs EGX70", style=plot.style_columns, color=rs70 >= 0 ? color.new(color.teal, 35) : color.new(color.red, 35))
plot(showRelativeWave ? rs100 : na, "Stock vs EGX100", style=plot.style_area, color=rs100 >= 0 ? color.new(color.blue, 88) : color.new(color.orange, 88))
fill(stockPlot, egx30Plot, color=showRelativeWave ? (stockWave >= egx30Wave ? color.new(color.teal, 82) : color.new(color.red, 85)) : na)
fill(stockPlot, egx70Plot, color=showRelativeWave ? (stockWave >= egx70Wave ? color.new(color.green, 96) : color.new(color.orange, 96)) : na)
fill(stockPlot, egx100Plot, color=showRelativeWave ? (stockWave >= egx100Wave ? color.new(color.blue, 97) : color.new(color.purple, 97)) : na)
rollGroup = "2) QARAR Rolling Trend"
color BULL_COLOR = #089981
color BEAR_COLOR = #f23645
fastLengthInput = input.int(5, "Fast Slope Length", minval=1, group=rollGroup)
slowLengthInput = input.int(10, "Slow Slope Length", minval=1, group=rollGroup)
atrLengthInput = input.int(200, "ATR Length", minval=1, group=rollGroup)
fastThresholdInput = input.float(1.0, "Fast Slope Threshold ATR", minval=0, step=0.1, group=rollGroup)
reverseThresholdInput = input.float(2.0, "Reverse Threshold ATR", minval=0, step=0.1, group=rollGroup)
rollAtr = ta.atr(atrLengthInput)
var float rollSeg = close
var int rollTrend = 1
var float activeSlope = 0.0
var bool isFastMode = false
bool bullReversal = false
bool bearReversal = false
if not na(rollAtr)
float distFromSeg = close - rollSeg
bullReversal := rollTrend == -1 and distFromSeg > reverseThresholdInput * rollAtr
bearReversal := rollTrend == 1 and -distFromSeg > reverseThresholdInput * rollAtr
if bullReversal
rollTrend := 1
else if bearReversal
rollTrend := -1
bool newIsFastMode = math.abs(distFromSeg) > fastThresholdInput * rollAtr
bool speedChanged = newIsFastMode != isFastMode
if bullReversal or bearReversal or speedChanged or activeSlope == 0.0
isFastMode := newIsFastMode
activeSlope := isFastMode ? rollAtr / fastLengthInput : rollAtr / slowLengthInput
rollSeg := rollSeg + (rollTrend * activeSlope)
else
rollSeg := close
rollColor = rollTrend == 1 ? BULL_COLOR : BEAR_COLOR
rollPlot = plot(showRollingTrend ? rollSeg : na, "QARAR Rolling Trend", color=rollColor, linewidth=2, force_overlay=true)
pricePlot = plot(showRollingTrend ? close : na, "Price Reference", display=display.none, force_overlay=true)
fill(pricePlot, rollPlot, top_value=rollTrend == 1 ? close : rollSeg, bottom_value=rollTrend == 1 ? rollSeg : close, top_color=rollTrend == 1 ? color.new(BULL_COLOR, 50) : color.new(BEAR_COLOR, 90), bottom_color=rollTrend == 1 ? color.new(BULL_COLOR, 90) : color.new(BEAR_COLOR, 50), title="Rolling Trend Fill")
qDemand = color.rgb(20, 184, 166)
qSupply = color.rgb(220, 95, 121)
qReclaimed = color.rgb(16, 185, 129)
qBroken = color.rgb(100, 116, 139)
qLiquidity = color.rgb(245, 158, 11)
qBlue = color.rgb(37, 99, 235)
qGold = color.rgb(214, 167, 86)
qPanelHead = color.rgb(17, 24, 39)
qPanelSoft = color.rgb(31, 41, 55)
qTextMuted = color.rgb(190, 190, 190)
srMainGroup = "3) QARAR S/R Engine"
useSRZoneEngine = input.bool(true, "Enable S/R Engine", group=srMainGroup)
pivotLen = input.int(5, "Pivot Strength", minval=2, maxval=30, group=srMainGroup)
srAtrLen = input.int(200, "S/R ATR Length", minval=20, maxval=500, group=srMainGroup)
srZoneDepthMult = input.float(0.55, "Zone Depth ATR", minval=0.10, maxval=2.00, step=0.05, group=srMainGroup)
srBreakBufferMult = input.float(0.15, "Break / Acceptance Buffer ATR", minval=0.00, maxval=1.00, step=0.05, group=srMainGroup)
srRetestToleranceATR = input.float(0.45, "Retest / Reclaim Tolerance ATR", minval=0.05, maxval=2.00, step=0.05, group=srMainGroup)
srVisGroup = "4) QARAR S/R Visual Map"
showSRVisualMap = input.bool(true, "Show Full Historical S/R Visual Map", group=srVisGroup)
srVisualMaxZones = input.int(55, "Max Historical Zones", minval=5, maxval=120, group=srVisGroup)
srVisualExtendRight = input.bool(true, "Extend Zones Right", group=srVisGroup)
srVisualFadeOld = input.bool(true, "Fade Old Zones", group=srVisGroup)
srVisualShowLabels = input.bool(true, "Show Major Zone Labels", group=srVisGroup)
srVisualMinGapATR = input.float(0.55, "Minimum Gap Between Zones ATR", minval=0.10, maxval=5.00, step=0.05, group=srVisGroup)
srVisualMinStrength = input.float(42.0, "Minimum Zone Strength", minval=20.0, maxval=90.0, step=1.0, group=srVisGroup)
srVisualMajorStrength = input.float(62.0, "Major Zone Strength", minval=30.0, maxval=95.0, step=1.0, group=srVisGroup)
srVisualShowBroken = input.bool(true, "Show Broken Zones", group=srVisGroup)
srVisualMaxBroken = input.int(14, "Max Visible Broken Zones", minval=0, maxval=50, group=srVisGroup)
srVisualAgeLimit = input.int(650, "Fade / Hide Weak Zones After Bars", minval=50, maxval=2500, group=srVisGroup)
srVisualMinEntriesMajor = input.int(2, "Major Zone Min Touches", minval=1, maxval=8, group=srVisGroup)
srVisualSweepBoost = input.float(10.0, "Sweep / Rejection Strength Boost", minval=0.0, maxval=30.0, step=0.5, group=srVisGroup)
srVisualVolumeBoost = input.float(8.0, "Volume Reaction Strength Boost", minval=0.0, maxval=25.0, step=0.5, group=srVisGroup)
useResistanceHeatMap = input.bool(false, "Heatmap Strength Coloring", group=srVisGroup)
srFilterGroup = "5) QARAR S/R Smart Visibility"
visibilityMode = input.string("Genesis", "Visibility Mode", options=["Clean", "Genesis", "Full"], group=srFilterGroup)
showOnlyMajorLabels = input.bool(true, "Labels Only For Major Zones", group=srFilterGroup)
srVolGroup = "6) QARAR S/R Volume / Reaction"
volLen = input.int(20, "Volume MA", minval=5, group=srVolGroup)
volReactionMult = input.float(1.15, "High Volume Reaction Mult", minval=0.5, maxval=5.0, step=0.05, group=srVolGroup)
srDashGroup = "7) QARAR S/R Dashboard"
dashPosInput = input.string("Top Right", "Dashboard Position", options=["Top Right", "Bottom Right", "Bottom Left", "Top Left"], group=srDashGroup)
atr = ta.atr(14)
srAtr = ta.atr(srAtrLen)
volMA = ta.sma(volume, volLen)
body = math.abs(close - open)
barRange = math.max(high - low, syminfo.mintick)
upperWick = high - math.max(open, close)
lowerWick = math.min(open, close) - low
pivotHigh = ta.pivothigh(high, pivotLen, pivotLen)
pivotLow = ta.pivotlow(low, pivotLen, pivotLen)
profileZoneMajorStrength = visibilityMode == "Clean" ? srVisualMajorStrength + 8 : visibilityMode == "Full" ? srVisualMajorStrength - 8 : srVisualMajorStrength
profileMinStrength = visibilityMode == "Clean" ? srVisualMinStrength + 10 : visibilityMode == "Full" ? srVisualMinStrength - 8 : srVisualMinStrength
profileMaxZones = visibilityMode == "Clean" ? math.min(srVisualMaxZones, 18) : visibilityMode == "Full" ? srVisualMaxZones : math.min(srVisualMaxZones, 55)
profileMaxBroken = visibilityMode == "Clean" ? math.min(srVisualMaxBroken, 5) : srVisualMaxBroken
profileZoneDepthMult = srZoneDepthMult
profileBreakBufferMult = srBreakBufferMult
var box[] qZoneBoxes = array.new_box()
var label[] qZoneLabels = array.new_label()
var float[] qZoneTops = array.new_float()
var float[] qZoneBottoms = array.new_float()
var float[] qZoneStrengths = array.new_float()
var bool[] qZoneSupports = array.new_bool()
var bool[] qZoneBroken = array.new_bool()
var int[] qZoneBirth = array.new_int()
var int[] qZoneEntries = array.new_int()
var int[] qZoneSweeps = array.new_int()
var float[] qZoneVolumes = array.new_float()
f_zone_mid(float _top, float _bottom) =>
(_top + _bottom) / 2.0
f_zone_overlaps(float _top, float _bottom, bool _isSupport) =>
int _idx = na
if array.size(qZoneBoxes) > 0
float _mid = f_zone_mid(_top, _bottom)
for zi = 0 to array.size(qZoneBoxes) - 1
bool sameType = array.get(qZoneSupports, zi) == _isSupport
float zTop = array.get(qZoneTops, zi)
float zBot = array.get(qZoneBottoms, zi)
float zMid = f_zone_mid(zTop, zBot)
bool priceOverlap = math.max(_bottom, zBot) <= math.min(_top, zTop)
bool nearGap = math.abs(_mid - zMid) <= srAtr * srVisualMinGapATR
if sameType and (priceOverlap or nearGap)
_idx := zi
break
_idx
f_zone_bg(bool _isSupport, bool _broken, int _age, float _strength, bool _isMajor) =>
int ageFade = srVisualFadeOld ? int(math.floor(_age / 60)) : 0
int tr = 90
if useResistanceHeatMap
tr := _strength >= 88 ? 30 : _strength >= 78 ? 42 : _strength >= 68 ? 54 : _strength >= 58 ? 66 : _strength >= 48 ? 78 : 90
else
int baseTransp = _isMajor ? 76 : 88
int strengthAdj = _strength >= 82 ? -16 : _strength >= 70 ? -10 : _strength >= 58 ? -5 : 2
tr := baseTransp + strengthAdj
tr := math.max(_isMajor ? 28 : 64, math.min(96, tr + ageFade))
_broken ? color.new(qBroken, math.min(96, tr + 8)) : _isSupport ? color.new(qDemand, tr) : color.new(qSupply, tr)
f_zone_border(bool _isSupport, bool _broken, float _strength, bool _isMajor) =>
int tr = useResistanceHeatMap ? (_strength >= 88 ? 0 : _strength >= 78 ? 8 : _strength >= 68 ? 18 : _strength >= 58 ? 34 : 62) : (_isMajor ? (_strength >= 82 ? 8 : _strength >= 70 ? 18 : 28) : 66)
_broken ? color.new(qBroken, 58) : _isSupport ? color.new(qDemand, tr) : color.new(qSupply, tr)
f_restyle_zone(int _idx, bool _reclaimed=false) =>
box bx = array.get(qZoneBoxes, _idx)
bool zSup = array.get(qZoneSupports, _idx)
bool zBroken = array.get(qZoneBroken, _idx)
int zAge = bar_index - array.get(qZoneBirth, _idx)
float zStrength = array.get(qZoneStrengths, _idx)
int zEntries = array.get(qZoneEntries, _idx)
int zSweeps = array.get(qZoneSweeps, _idx)
bool zMajor = zStrength >= profileZoneMajorStrength or zEntries >= srVisualMinEntriesMajor
color bg = _reclaimed ? color.new(qReclaimed, 76) : f_zone_bg(zSup, zBroken, zAge, zStrength, zMajor)
color br = _reclaimed ? color.new(qReclaimed, 24) : f_zone_border(zSup, zBroken, zStrength, zMajor)
box.set_bgcolor(bx, bg)
box.set_border_color(bx, br)
box.set_border_width(bx, zMajor and not zBroken ? 2 : 1)
if not srVisualExtendRight
box.set_right(bx, bar_index + 25)
label lb = array.get(qZoneLabels, _idx)
if not na(lb)
float zTop = array.get(qZoneTops, _idx)
float zBot = array.get(qZoneBПоказано первые 50% кода (символов: 22618)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.