← К каталогу
Исходный код · ID 4473

Dynamic Profile Key Levels

dynamic profile key levels.pine
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Этот индикатор для TradingView (Pine Script v6) отображает на графике ключевые уровни на основе профиля объёмов. Он рассчитывает профиль объёмов по заданному диапазону баров, определяет точку контроля (POC), границы зоны стоимости (VAH/VAL), локальные пики и впадины объёма, а также наиболее объёмные ряды. Все уровни отрисовываются графическими элементами прямо на ценовом графике.

Индикатор поддерживает два режима расчёта профиля — фиксированный по заданному откату и динамический, привязанный к подтверждённым пивотам. Предусмотрены параметры разрешения профиля, периода пивотов, частоты пересчёта и процента зоны стоимости. Уровни могут продлеваться автоматически, останавливаться при пробое и иметь ограничение по количеству хранимых.

Система событий фиксирует пробои, откаты и повторные подходы к уровням с возможностью настройки охлаждения сигналов и временного окна повторных подходов. Настроены условные оповещения TradingView для каждого типа событий. Таблица метрик отображает позицию цены относительно зоны стоимости, расстояние до POC, относительный объём и количество активных уровней.

Настройки программы

НастройкаОписание
showProfile Включает отображение профиля объёмов на графике.
enablePoc Включает отображение точки контроля (POC) и связанных с ней уровней и сигналов. При отключении также отключаются фиксированные уровни POC и их сигналы.
enableValueArea Включает отображение границ зоны стоимости (VAH и VAL). При отключении фиксированные уровни зоны стоимости и их сигналы также деактивируются.
showBackground Включает фоновое затенение. Зона стоимости отображает VAH-VAL, а фоновое затенение — отдельный тип. Выбираются тип текущего, исторического или развивающегося уровня и тип фона.
showPeaks Включает отображение пиков объёма. Каждый пик имеет вариант линий или зон. При отключении также деактивируются сигналы пиков.
showTroughs Включает отображение впадин объёма. Каждая впадина имеет вариант линий или зон. При отключении также деактивируются сигналы впадин.
showRanked Включает отображение ранжированных строк объёма. Дублирующиеся и перекрывающиеся строки могут пропускаться.
keepHistory Сохраняет остановленные узловые отрисовки. При отключении исторические узлы удаляются. POC и зона стоимости используют собственные настройки истории.
showLevelLabels Отображает метки с информацией на видимых уровнях.
showMetrics Отображает таблицу метрик с данными профиля.
showAccents Включает визуальные акценты: контуры профиля и выделение уровней. При отключении отображаются простые графические элементы.
showCenterLine Добавляет пунктирные линии внутри включённых зон. Активен при наличии пиков, впадин или ранжированных рядов.
focusNearby При включении усиливает визуальное выделение уровней, расположенных близко к текущей цене.
showPrices Добавляет точную цену к каждой видимой метке. Активен только при включённых метках уровней.
showSignals Отображает маркеры событий для включённых типов фиксированных уровней. Этот переключатель скрывает только маркеры; оповещения продолжают работать.
keepOldActive Сохраняет старые узлы активными до их пробоя, истечения срока или удаления из хранилища. Ограничение видимых узлов скрывает только дополнительные отрисовки, уровни продолжают отслеживаться.
stopOnBreak При включении уровень останавливается (деактивируется) после закрытия свечи, пробившей его. При отключении возможны повторные подходы к пробитым уровням.
preventOverlap Блокирует создание новых узлов, перекрывающих активные узлы или POC. Линии зоны стоимости от этой проверки освобождены. При отключении возможны повторные подходы к пробитым уровням.
showBreaks Отображает маркеры пробоя уровней. Активен при включённых маркерах сигналов.
showRejections Отображает маркеры откатов уровней. Активен при включённых маркерах сигналов.
showRetests Отображает маркеры повторных подходов к уровням. Требует отключённой остановки на пробой. Эти переключатели не отключают оповещения.
expiryBars Количество баров после которого неактивный уровень автоматически останавливается.
maxLevels Общее количество активных и остановленных уровней, хранимых в памяти. Удаляется самый старый остановленный уровень, или самый старый активный если все активны.
profileMode Режим расчёта профиля. «Fixed» использует выбранный откат. «Dynamic» начинает от последнего подтверждённого пивота в пределах ограничения отката.
lookback Максимальное количество баров, используемых для расчёта профиля в фиксированном режиме.
pivotLength Количество баров с каждой стороны пивота, необходимых для подтверждения нового якоря. Активен только в динамическом режиме профиля.
resolution Количество рядов (интервалов), на которые делится диапазон цен профиля.
refreshBars Профиль пересчитывается на каждом N-м закрытом баре. Сигналы используют закрытие каждого бара. Значение 1 обеспечивает обновление профиля на каждом баре.
valueAreaPercent Процент объёма профиля, включаемый в зону стоимости (VAH и VAL).
pocMode Вариант отображения точки контроля. «Current» сохраняет активную линию POC. «Historical» также сохраняет остановленные линии. «Developing» показывает путь POC без создания фиксированных уровней и сигналов.
valueAreaMode Вариант отображения зоны стоимости. «Current» сохраняет активные линии VAH/VAL. «Historical» также сохраняет остановленные линии. «Developing» показывает путь без фиксированных уровней и сигналов.
peakMode Вариант отображения пиков объёма: линии или зоны.
peakCount Максимальное количество локальных пиков объёма, выбираемых на профиль.
troughMode Вариант отображения впадин объёма: линии или зоны.
troughCount Максимальное количество локальных впадин объёма, выбираемых на профиль. Внешние ряды профиля исключаются.
rankedMode Вариант отображения ранжированных строк объёма. Добавляет ранжированные строки даже если они не являются локальными пиками или впадинами.
highestRows Количество наиболее объёмных рядов, добавляемых из ранжированных строк профиля.
lowestRows Количество наименее объёмных рядов, добавляемых из ранжированных строк профиля. Ноль исключает эту сторону.
zoneRadius Количество рядов, включаемых с каждой стороны узла. Радиус 1 создаёт трёхрядную зону. В режиме линий используется один ряд по центру.
profilePlacement Размещение профиля на графике: справа или слева.
profileColorMode Определяет цветовую схему строк профиля. «Directional» раскрашивает по балансу объёма вверх/вниз. «Up / Down» разделяет строки на две части. «Relative Volume» использует один цвет, зависящий от темы.
profileWidth Ширина профиля в барах графика.
profileOffset Смещение профиля вправо в барах графика. Активен при правом размещении.
backgroundMode Определяет тип фонового затенения для последнего профиля. Варианты: зона стоимости, диапазон профиля или оба одновременно.
signalDisplay Вариант отображения маркеров сигналов: только символы или символы с текстом.
signalScope Определяет уровни, на которых генерируются сигналы. «Nodes» использует пики, впадины и ранжированные ряды. «All Levels» также использует включённые фиксированные уровни POC и зоны стоимости.
signalCooldown Минимальное расстояние в барах между принятыми сигналами на одном уровне. Также применяется к оповещениям.
retestWindow Максимальное количество баров после пробоя для первого успешного повторного подхода. Активен только при отключённой остановке на пробое.
volumeLength Период скользящего среднего для расчёта среднего объёма, используемого в фильтре относительного объёма.
minimumRelativeVolume Минимальный относительный объём (RVOL) для принятия сигнала. Объём свечи делится на предшествующее среднее. Ноль отключает фильтр.
maxSignalLabels Максимальное количество хранимых маркеров сигналов. Не более одной метки на направление на бар. Приоритет: пробои, затем повторные подходы, затем откаты.
visualStyle Вариант визуального стиля акцентов. «Signature» добавляет затенение ядра, скобки и свечение. «Volume Balance» заменяет затенение на полоску баланса объёма вверх/вниз.
contrastMode Управляет контрастностью отображения. Режим «Signature» добавляет затенение ядра узла, скобки и свечение линий. «Volume Balance» заменяет затенение на полоску объёма вверх/вниз. «Custom» позволяет задать прозрачность вручную.
maxVisibleNodes Ограничивает количество видимых активных узловых отрисовок. Не влияет на хранимые уровни или оповещения. Включает один ближайший узел из каждой семьи, затем заполняет оставшиеся слоты по расстоянию до цены.
levelExtension Длина продления уровней вправо от текущего бара в барах.
green Цвет для бычьих (положительных) элементов отображения.
red Цвет для медвежьих (отрицательных) элементов отображения.
neut Цвет для нейтральных элементов отображения. POC использует цвет переднего плана графика.
labelMetric Определяет содержимое меток уровней. «Volume Share» показывает долю объёма, «Row Strength» — силу ряда относительно POC, «Up Volume» — объём вверх по свече, «Name» — только имя уровня.
labelSizeInput Размер текста меток уровней.
maxLevelLabels Максимальное количество меток на видимых активных уровнях. Метки используют одну правую колонку. Слишком близкие по цене метки пропускаются.
tableMode Вариант таблицы метрик. «Compact» показывает позицию зоны стоимости, расстояние до POC, ближайшие видимые уровни и относительный объём. «Detailed» добавляет данные профиля, баланс объёма, количество уровней и последний сигнал.
tableSizeInput Размер текста в таблице метрик.
tablePosition Позиция таблицы метрик на графике.
peakDetection Соседние ряды проверяются по обе стороны как процент от разрешения профиля. Большие значения выбирают более широкие пики.
troughDetection Соседние ряды проверяются по обе стороны как процент от разрешения профиля. Большие значения выбирают более широкие впадины.
minimumNodeVolume Минимальный объём узлового ряда относительно ряда POC в процентах. Пустые ряды исключаются.
smoothing Радиус сглаживания объёма рядов для обнаружения локальных пиков и впадин. Ноль отключает сглаживание.
matchTolerance Допуск в рядах для сопоставления нового узла с существующим. Существующий узел сохраняется при создании нового узла того же типа на таком же расстоянии.
calculationHistory Количество последних баров графика, используемых для обновления исторических профилей и сигналов. Более ранние бары могут использоваться для данных отката.
useLowerTimeframe Использует свечи нижнего таймфрейма при наличии. Объём распределяется равномерно по диапазону каждой свечи. Это оценочный объём по цене, а не данные биржевого стакана.
intragran Гранулярность баров при использовании нижнего таймфрейма. Определяет, на какое количество секунд делится таймфрейм графика.
allowSeconds Разрешает запрос данных в секундах при использовании нижнего таймфрейма. Данные в секундах запрашиваются приблизительно путём деления таймфрейма графика на гранулярность баров.
zoneFillTransparency Прозрачность заливки зон при ручном режиме контраста. Меньшие значения делают зоны более заметными.
zoneBorderTransparency Прозрачность границ зон при ручном режиме контраста. Меньшие значения делают зоны более заметными.
inactiveTransparency Прозрачность исторических (остановленных) уровней при ручном режиме контраста.
profileTransparency Базовая прозрачность строк профиля при ручном режиме контраста. Строки с меньшим объёмом используют более мягкую настройку.
Получить полный код

Поиск по коду файла

indicator("Dynamic Profile Key Levels", "Dynamic Profile", overlay = true, max_boxes_count = 500, max_lines_count = 500, max_labels_count = 500, max_polylines_count = 4, max_bars_back = 5000)

componentsGR = "Components"
showProfile = input.bool(true, "Volume Profile", inline = "mainComponents", group = componentsGR)
enablePoc = input.bool(false, "Point of Control", inline = "mainComponents", group = componentsGR, tooltip = "Shows the profile and POC. Select their variants below. Turning POC off also disables fixed POC levels and their signals.")
enableValueArea = input.bool(true, "Value Area Levels", inline = "areaComponents", group = componentsGR)
showBackground = input.bool(false, "Background", inline = "areaComponents", group = componentsGR, tooltip = "Value Area Levels enables VAH and VAL. Background shading is separate. Select Current, Historical, or Developing levels and the background type below.")
showPeaks = input.bool(true, "Volume Peaks", inline = "nodeComponents", group = componentsGR)
showTroughs = input.bool(false, "Volume Troughs", inline = "nodeComponents", group = componentsGR, tooltip = "Enables peak and trough levels. Each has a Lines or Zones variant below. Turning a level type off also disables its level signals.")
showRanked = input.bool(true, "Ranked Volume Rows", inline = "extraComponents", group = componentsGR)
keepHistory = input.bool(false, "Historical Nodes", inline = "extraComponents", group = componentsGR, tooltip = "Ranked rows add high- or low-volume rows that pass the filters. Historical Nodes keeps stopped node drawings. POC and value-area history use their own variants. History is off by default.")
showLevelLabels = input.bool(true, "Level Labels", inline = "infoComponents", group = componentsGR)
showMetrics = input.bool(true, "Metrics Table", inline = "infoComponents", group = componentsGR, tooltip = "Shows spaced labels and a metrics table. Label content, text size, and table layout are set below.")
showAccents = input.bool(true, "Visual Accents", inline = "styleComponents", group = componentsGR)
showCenterLine = input.bool(false, "Zone Center Lines", inline = "styleComponents", group = componentsGR, active = showPeaks or showTroughs or showRanked, tooltip = "Visual Accents adds profile outlines and level highlights. Zone Center Lines adds dotted lines inside enabled zones.")
focusNearby = input.bool(true, "Emphasize Nearby Levels", inline = "detailComponents", group = componentsGR)
showPrices = input.bool(false, "Label Prices", inline = "detailComponents", group = componentsGR, active = showLevelLabels, tooltip = "Near-price emphasis changes drawing contrast only. Label Prices adds the exact price to each visible label.")
showSignals = input.bool(true, "Signal Markers", group = componentsGR, tooltip = "Shows closed-bar signals for enabled fixed level types. This switch hides markers only; alerts still operate. Select the marker style below.")

historyGR = "Level Management"
keepOldActive = input.bool(true, "Extend Previous Nodes", group = historyGR, tooltip = "Keeps old nodes active until break, expiry, or storage removal. The visible-node limit only hides extra drawings; those levels remain tracked. POC and value-area lines always follow the latest profile.")
stopOnBreak = input.bool(true, "Stop Extending On Break", inline = "management", group = historyGR)
preventOverlap = input.bool(true, "Avoid Overlap", inline = "management", group = historyGR, tooltip = "Stop Extending ends a level after a close breaks through it. Disable it for later retests. Avoid Overlap blocks new nodes that overlap active nodes or POC. Value-area lines are exempt.")
showBreaks = input.bool(true, "Breaks", inline = "signalComponents", group = componentsGR, active = showSignals)
showRejections = input.bool(true, "Rejections", inline = "signalComponents", group = componentsGR, active = showSignals)
showRetests = input.bool(true, "Retests", inline = "signalComponents", group = componentsGR, active = showSignals and not stopOnBreak, tooltip = "Select which events receive markers. These switches do not disable alerts. Retests require Stop Extending On Break to be disabled.")
expiryBars = input.int(500, "Level Expiry Bars", minval = 1, maxval = 5000, group = historyGR, display = display.none)
maxLevels = input.int(150, "Maximum Stored Levels", minval = 40, maxval = 250, group = historyGR, display = display.none, tooltip = "Total active and stopped levels retained. Removes the oldest stopped level first, or the oldest active level when all are active.")

calcGR = "Calculation"
profileMode = input.string("Fixed", "Lookback Mode", options = ["Fixed", "Dynamic"], group = calcGR, display = display.none, tooltip = "Fixed uses the selected lookback. Dynamic starts at the latest confirmed pivot, within the lookback limit.")
lookback = input.int(240, "Lookback Limit", minval = 30, maxval = 1500, group = calcGR, display = display.none)
pivotLength = input.int(35, "Pivot Period", minval = 2, maxval = 250, group = calcGR, display = display.none, active = profileMode == "Dynamic", tooltip = "Bars required on each side of a pivot. A new anchor is available only after the pivot is confirmed.")
resolution = input.int(64, "Profile Resolution", minval = 20, maxval = 100, group = calcGR, display = display.none)
refreshBars = input.int(5, "Refresh Every N Bars", minval = 1, maxval = 100, group = calcGR, display = display.none, tooltip = "Rebuilds the profile on every Nth closed chart bar. Signals still use each chart-bar close. Set to 1 for each-bar profile updates.")
valueAreaPercent = input.float(70.0, "Value Area (%)", minval = 1.0, maxval = 100.0, step = 1.0, group = calcGR, display = display.none)

nodeGR = "Key Level Variants"
pocMode = input.string("Current", "POC Variant", options = ["Current", "Historical", "Developing"], group = nodeGR, display = display.none, active = enablePoc, tooltip = "Current keeps the active POC line. Historical also keeps stopped POC lines. Developing shows the POC path without creating fixed POC levels or POC signals.")
valueAreaMode = input.string("Current", "Value Area Variant", options = ["Current", "Historical", "Developing"], group = nodeGR, display = display.none, active = enableValueArea, tooltip = "Controls VAH and VAL. Current keeps active lines. Historical also keeps stopped lines. Developing shows their paths without fixed value-area levels or their signals.")
peakMode = input.string("Zones", "Peak Variant", options = ["Lines", "Zones"], inline = "peaks", group = nodeGR, display = display.none, active = showPeaks)
peakCount = input.int(2, "Max", minval = 1, maxval = 8, inline = "peaks", group = nodeGR, display = display.none, active = showPeaks, tooltip = "Maximum local volume peaks selected per profile. Existing nodes can remain active when Extend Previous Nodes is enabled.")
troughMode = input.string("Lines", "Trough Variant", options = ["Lines", "Zones"], inline = "troughs", group = nodeGR, display = display.none, active = showTroughs)
troughCount = input.int(1, "Max", minval = 1, maxval = 8, inline = "troughs", group = nodeGR, display = display.none, active = showTroughs, tooltip = "Maximum local volume troughs selected per profile. Outer profile rows are excluded.")
rankedMode = input.string("Lines", "Ranked Row Variant", options = ["Lines", "Zones"], group = nodeGR, display = display.none, active = showRanked, tooltip = "Adds ranked volume rows even when they are not local peaks or troughs. Duplicate and overlapping rows can be skipped.")
highestRows = input.int(1, "Highest Rows", minval = 0, maxval = 5, inline = "ranked", group = nodeGR, display = display.none, active = showRanked)
lowestRows = input.int(0, "Lowest Rows", minval = 0, maxval = 5, inline = "ranked", group = nodeGR, display = display.none, active = showRanked, tooltip = "Number of extra high-volume and low-volume rows. Zero excludes that side. Rows must pass the volume and overlap filters.")
zoneRadius = input.int(1, "Zone Radius (Rows)", minval = 0, maxval = 5, group = nodeGR, display = display.none, active = (showPeaks and peakMode == "Zones") or (showTroughs and troughMode == "Zones") or (showRanked and rankedMode == "Zones"), tooltip = "Rows included on each side of a node. A radius of 1 creates a three-row zone. Lines mode uses one row center.")

profileGR = "Profile Display"
profilePlacement = input.string("Right", "Placement", options = ["Right", "Left"], group = profileGR, display = display.none, active = showProfile)
profileColorMode = input.string("Directional", "Color Variant", options = ["Directional", "Up / Down", "Relative Volume"], group = profileGR, display = display.none, active = showProfile, tooltip = "Directional colors each row by estimated up/down volume balance. Up / Down splits rows into two parts. Relative Volume uses one theme-aware color. Row width represents volume, not buying or selling pressure.")
profileWidth = input.int(60, "Width", minval = 5, maxval = 200, inline = "profileSize", group = profileGR, display = display.none, active = showProfile)
profileOffset = input.int(20, "Offset", minval = 0, maxval = 250, inline = "profileSize", group = profileGR, display = display.none, active = showProfile and profilePlacement == "Right", tooltip = "Profile width and right-side offset in chart bars. Left placement starts at the first bar of the latest profile window.")
backgroundMode = input.string("Value Area", "Background Variant", options = ["Value Area", "Profile Range", "Both"], group = profileGR, display = display.none, active = showBackground, tooltip = "Shading for the latest profile only. Value Area shades the range between VAH and VAL.")

signalGR = "Signal Settings"
signalDisplay = input.string("Markers", "Marker Variant", options = ["Markers", "Markers + Text"], group = signalGR, display = display.none, active = showSignals, tooltip = "Markers uses symbols only. Markers + Text also shows the event name. New levels cannot signal on their creation bar.")
signalScope = input.string("Nodes", "Signal Levels", options = ["Nodes", "All Levels"], group = signalGR, display = display.none, tooltip = "Nodes uses peaks, troughs, and ranked rows. All Levels also uses enabled fixed POC and value-area levels. Alerts can use tracked nodes hidden by the visible-node limit.")
signalCooldown = input.int(3, "Signal Cooldown", minval = 0, maxval = 100, group = signalGR, display = display.none, tooltip = "Minimum bar spacing between accepted signals on the same level. Also applies to alerts.")
retestWindow = input.int(30, "Retest Window", minval = 1, maxval = 500, group = signalGR, display = display.none, active = not stopOnBreak, tooltip = "Maximum bars after a break for its first successful retest.")
volumeLength = input.int(20, "Volume Average", minval = 1, maxval = 200, inline = "volumeFilter", group = signalGR, display = display.none)
minimumRelativeVolume = input.float(0.0, "Minimum RVOL", minval = 0.0, maxval = 10.0, step = 0.1, inline = "volumeFilter", group = signalGR, display = display.none, tooltip = "Signal volume divided by the preceding average volume. Zero disables the filter. Also applies to alerts.")
maxSignalLabels = input.int(80, "Signal Label Limit", minval = 10, maxval = 300, group = signalGR, display = display.none, active = showSignals, tooltip = "Maximum stored signal markers. At most one label per direction per bar. Breaks take priority over retests, then rejections.")

appearanceGR = "Appearance"
visualStyle = input.string("Signature", "Accent Variant", options = ["Signature", "Volume Balance"], inline = "design", group = appearanceGR, display = display.none, active = showAccents)
contrastMode = input.string("Bright", "Contrast", options = ["Soft", "Balanced", "Bright", "Custom"], inline = "design", group = appearanceGR, display = display.none, tooltip = "Signature adds node-core shading, edge brackets, and line glow. Volume Balance replaces core shading with an up/down volume strip. Uncheck Visual Accents for plain drawings. Contrast controls transparency.")
maxVisibleNodes = input.int(8, "Visible Active Nodes", minval = 3, maxval = 100, group = appearanceGR, display = display.none, active = showPeaks or showTroughs or showRanked, tooltip = "Limits active node drawings, not stored levels or alerts. Includes one nearest node from each available family, then fills remaining slots by distance to price. POC and value-area lines are separate. History has its own checkbox.")
levelExtension = input.int(5, "Level Extension", minval = 0, maxval = 100, group = appearanceGR, display = display.none)
green = input.color(#00ffbb, "Colors", inline = "colors", group = appearanceGR)
red = input.color(#ff1100, "", inline = "colors", group = appearanceGR)
neut = input.color(color.gray, "", inline = "colors", group = appearanceGR, tooltip = "Bullish, bearish, and neutral colors. POC uses the chart foreground color.")

labelGR = "Label Settings"
labelMetric = input.string("Volume Share", "Label Content", options = ["Name", "Volume Share", "Row Strength", "Up Volume"], group = labelGR, display = display.none, active = showLevelLabels, tooltip = "Volume Share compares the row or zone with total profile volume. Row Strength compares the node row with the POC row. Up Volume uses candle direction, not actual buying volume. Values are fixed at creation and are not win probabilities.")
labelSizeInput = input.string("Tiny", "Text Size", options = ["Tiny", "Small", "Normal", "Large"], inline = "labelSize", group = labelGR, display = display.none, active = showLevelLabels)
maxLevelLabels = input.int(8, "Max", minval = 1, maxval = 18, inline = "labelSize", group = labelGR, display = display.none, active = showLevelLabels, tooltip = "Maximum labels on visible active levels. Labels use one right-side column. Labels too close in price are skipped without moving level prices.")

tableGR = "Metrics Table"
tableMode = input.string("Compact", "Table Variant", options = ["Compact", "Detailed"], group = tableGR, display = display.none, active = showMetrics, tooltip = "Compact shows value-area position, POC distance, nearby visible levels, and relative volume. Detailed adds profile data, volume balance, level counts, and the last signal.")
tableSizeInput = input.string("Small", "Text Size", options = ["Tiny", "Small", "Normal", "Large"], inline = "table", group = tableGR, display = display.none, active = showMetrics)
tablePosition = input.string("Top Right", "Position", options = ["Top Left", "Top Center", "Top Right", "Middle Right", "Bottom Left", "Bottom Center", "Bottom Right"], inline = "table", group = tableGR, display = display.none, active = showMetrics)

advancedGR = "Advanced Calculation"
peakDetection = input.float(7.0, "Peak Detection (%)", minval = 1.0, maxval = 50.0, step = 1.0, group = advancedGR, display = display.none, active = showPeaks, tooltip = "Neighbor rows checked on each side as a percentage of profile resolution. Larger values select broader peaks.")
troughDetection = input.float(7.0, "Trough Detection (%)", minval = 1.0, maxval = 50.0, step = 1.0, group = advancedGR, display = display.none, active = showTroughs)
minimumNodeVolume = input.float(1.0, "Minimum Node Volume (%)", minval = 0.0, maxval = 100.0, step = 0.5, group = advancedGR, display = display.none, tooltip = "Minimum node-row volume relative to the POC row. Empty rows are excluded.")
smoothing = input.int(1, "Node Smoothing Radius", minval = 0, maxval = 5, group = advancedGR, display = display.none, tooltip = "Smooths row volume for local peak and trough detection only. Set to 0 to disable.")
matchTolerance = input.float(0.75, "Node Match Tolerance (Rows)", minval = 0.0, maxval = 5.0, step = 0.25, group = advancedGR, display = display.none, tooltip = "Keeps an existing node when a new node of the same type is this close. Its price, bounds, and creation statistics stay fixed.")
calculationHistory = input.int(2000, "Calculation History", minval = 100, maxval = 10000, group = advancedGR, display = display.none, tooltip = "Recent chart bars used for historical profile updates and signals. Earlier bars can supply lookback data. A moving start window can change initial level state after reload.")
useLowerTimeframe = input.bool(false, "Use Lower Timeframe", group = advancedGR, tooltip = "Uses lower-timeframe candles when available; otherwise chart candles. Volume is spread uniformly across each candle range. This is estimated volume at price, not exchange bid/ask data.")
intragran = input.int(5, "Bar Granularity", minval = 2, maxval = 20, inline = "lowerTf", group = advancedGR, display = display.none, active = useLowerTimeframe)
allowSeconds = input.bool(false, "Seconds", inline = "lowerTf", group = advancedGR, active = useLowerTimeframe, tooltip = "Requests approximately the chart timeframe divided by Bar Granularity. Seconds data is optional. The Detailed table reports lower-timeframe coverage.")

styleGR = "Custom Transparency"
zoneFillTransparency = input.int(72, "Zone Fill", minval = 0, maxval = 100, inline = "zoneAlpha", group = styleGR, display = display.none, active = contrastMode == "Custom")
zoneBorderTransparency = input.int(48, "Border", minval = 0, maxval = 100, inline = "zoneAlpha", group = styleGR, display = display.none, active = contrastMode == "Custom", tooltip = "Custom zone transparency. Lower values make zones more visible. Near-price emphasis can reduce these values further.")
inactiveTransparency = input.int(78, "History", minval = 0, maxval = 100, inline = "extraAlpha", group = styleGR, display = display.none, active = contrastMode == "Custom" and (keepHistory or (enablePoc and pocMode == "Historical") or (enableValueArea and valueAreaMode == "Historical")))
profileTransparency = input.int(15, "Profile", minval = 0, maxval = 100, inline = "extraAlpha", group = styleGR, display = display.none, active = contrastMode == "Custom" and showProfile, tooltip = "Custom history and profile base transparency. Profile rows with less volume use a softer setting.")

showPoc = enablePoc and pocMode != "Developing"
showValueArea = enableValueArea and valueAreaMode != "Developing"
showRange = showBackground and (backgroundMode == "Profile Range" or backgroundMode == "Both")
showValueAreaFill = showBackground and (backgroundMode == "Value Area" or backgroundMode == "Both")
showSignalText = signalDisplay == "Markers + Text"
zoneAlpha = contrastMode == "Custom" ? zoneFillTransparency : contrastMode == "Bright" ? 72 : contrastMode == "Balanced" ? 78 : 84
borderAlpha = contrastMode == "Custom" ? zoneBorderTransparency : contrastMode == "Bright" ? 48 : contrastMode == "Balanced" ? 58 : 68
historyAlpha = contrastMode == "Custom" ? inactiveTransparency : contrastMode == "Bright" ? 78 : contrastMode == "Balanced" ? 83 : 88
profileAlpha = contrastMode == "Custom" ? profileTransparency : contrastMode == "Bright" ? 15 : contrastMode == "Balanced" ? 28 : 42
lineAlpha = contrastMode == "Bright" or contrastMode == "Custom" ? 4 : contrastMode == "Balanced" ? 12 : 22

type BarData
    array<float> highs
    array<float> lows
    array<float> volumes
    array<float> upVolumes
    float highPrice
    float lowPrice
    bool lowerData
    bool missingVolume

type Profile
    array<float> volumes
    array<float> upVolumes
    array<float> smoothed
    float bottom
    float step
    float total
    float maximum
    float upTotal
    float poc
    float vah
    float val
    int pocRow
    int vahRow
    int valRow
    int bars
    int left
    int updated
    int lowerBars
    int missingBars
    bool valid = false

type Candidate
    int row
    int kind
    float price
    float top
    float bottom
    float share
    float strength
    float upShare
    bool matched = false

type KeyLevel
    box zone
    line ln
    int kind
    float price
    float top
    float bottom
    float share
    float strength
    float upShare
    int born
    int lastSeen
    int side
    int lastSignal = -100000
    int breakBar = -1
    int breakSide = 0
    int touchSide = 0
    int touches = 0
    bool active = true
    bool touching = false
    bool pendingTouch = false
    bool pendingRetest = false
    bool visible = true

var bars = array.new<BarData>()
var levels = array.new<KeyLevel>()
var profileBoxes = array.new_box()
var detailBoxes = array.new_box()
var detailLines = array.new_line()
var profileContours = array.new<polyline>()
var levelLabels = array.new_label()
var signalLabels = array.new_label()
var profile = Profile.new()
var pivotIndex = 0
var lastSignalText = "None"

sizeFromString(txt) =>
    switch txt
        "Tiny" => size.tiny
        "Small" => size.small
        "Normal" => size.normal
        => size.large

posFromString(txt) =>
    switch txt
        "Top Left" => position.top_left
        "Top Center" => position.top_center
        "Top Right" => position.top_right
        "Middle Right" => position.middle_right
        "Bottom Left" => position.bottom_left
        "Bottom Center" => position.bottom_center
        => position.bottom_right

formatPercent(value) =>
    str.tostring(value, "#.#") + "%"

isNode(kind) =>
    math.abs(kind) == 1 or math.abs(kind) == 3

usesZone(kind) =>
    switch kind
        1 => peakMode == "Zones"
        -1 => troughMode == "Zones"
        3 => rankedMode == "Zones"
        -3 => rankedMode == "Zones"
        => false

preserveHistory(kind) =>
    kind == 0 ? pocMode == "Historical" : math.abs(kind) == 2 ? valueAreaMode == "Historical" : keepHistory

nodeName(kind) =>
    switch kind
        0 => "POC"
        1 => "Peak"
        -1 => "Trough"
        2 => "VAH"
        -2 => "VAL"
        3 => "High Vol"
        => "Low Vol"

sideColor(side) =>
    side == 1 ? green : side == -1 ? red : color.from_gradient(0.3, 0, 1, neut, chart.fg_color)

clampAlpha(value) =>
    math.max(0.0, math.min(100.0, value))

themeTint(col, amount) =>
    color.from_gradient(amount, 0, 1, chart.bg_color, color.new(col, 0))

textInk(col) =>
    lightChart = color.r(chart.bg_color) * 0.299 + color.g(chart.bg_color) * 0.587 + color.b(chart.bg_color) * 0.114 > 150
    lightChart ? color.from_gradient(0.42, 0, 1, col, chart.fg_color) : color.new(col, 0)

levelColor(kind, side) =>
    kind == 0 ? chart.fg_color : sideColor(side)

levelFocus(top, bottom, price, unit) =>
    distance = math.max(bottom - price, math.max(price - top, 0.0))
    focusNearby ? 1.0 - math.min(1.0, distance / (unit * 4.0)) : 0.0

nodeSymbol(kind) =>
    kind == 0 ? "◆" : kind == 1 or kind == 3 ? "●" : kind == -1 or kind == -3 ? "○" : "─"

levelText(KeyLevel item) =>
    metric = switch labelMetric
        "Volume Share" => "  " + formatPercent(item.share) + " VOL"
        "Row Strength" => "  " + formatPercent(item.strength) + " ROW"
        "Up Volume" => "  " + formatPercent(item.upShare) + " UP"
        => ""
    nodeSymbol(item.kind) + " " + str.upper(nodeName(item.kind)) + metric + (showPrices ? "  ·  " + str.tostring(item.price, format.mintick) : "")

levelTooltip(KeyLevel item) =>
    nodeName(item.kind) + " | " + str.tostring(item.price, format.mintick) + "\nVolume share at creation: " + formatPercent(item.share) + "\nRow strength at creation: " + formatPercent(item.strength) + "\nEstimated up volume at creation: " + formatPercent(item.upShare) + "\nContact episodes: " + str.tostring(item.touches) + "\nAge: " + str.tostring(bar_index - item.born) + " bars\nPercentages are not win probabilities."

addRange(array<float> values, first, last, amount) =>
    values.set(first, values.get(first) + amount)
    values.set(last + 1, values.get(last + 1) - amount)

allocateVolume(array<float> totals, array<float> ups, candleLow, candleHigh, candleVolume, candleUp, base, step) =>
    if candleVolume > 0
        first = math.max(0, math.min(resolution - 1, int(math.floor((candleLow - base) / step))))
        last = math.max(first, math.min(resolution - 1, int(math.floor((candleHigh - base) / step))))
        upRatio = math.max(0.0, math.min(1.0, candleUp / candleVolume))
        if first == last or candleHigh <= candleLow
            addRange(totals, first, first, candleVolume)
            addRange(ups, first, first, candleVolume * upRatio)
        else
            span = candleHigh - candleLow
            firstVolume = candleVolume * math.max(0.0, math.min(1.0, (base + (first + 1) * step - candleLow) / span))
            lastVolume = candleVolume * math.max(0.0, math.min(1.0, (candleHigh - base - last * step) / span))
            addRange(totals, first, first, firstVolume)
            addRange(ups, first, first, firstVolume * upRatio)
            addRange(totals, last, last, lastVolume)
            addRange(ups, last, last, lastVolume * upRatio)
            if last > first + 1
                interior = candleVolume * step / span
                addRange(totals, first + 1, last - 1, interior)
                addRange(ups, first + 1, last - 1, interior * upRatio)

smoothRows(array<float> values) =>
    result = values.copy()
    if smoothing > 0
        prefix = array.new_float(resolution + 1, 0.0)
        for i = 0 to resolution - 1
            prefix.set(i + 1, prefix.get(i) + values.get(i))
        for i = 0 to resolution - 1
            first = math.max(0, i - smoothing)
            last = math.min(resolution - 1, i + smoothing)
            result.set(i, (prefix.get(last + 1) - prefix.get(first)) / (last - first + 1))
    result

nodeAt(array<float> values, index, radius, peak) =>
    value = values.get(index)
    valid = peak or (index > 0 and index < resolution - 1)
    contrast = false
    if valid
        for j = math.max(0, index - radius) to math.min(resolution - 1, index + radius)
            if j != index
                other = values.get(j)
                if (peak ? other > value : other < value) or (other == value and j < index)
                    valid := false
                    break
                contrast := contrast or (peak ? other < value : other > value)
    valid and contrast
var table wm = table.new(position.bottom_right, 1, 1)
if barstate.isfirst
    table.cell(wm, 0, 0, "Telegram @free_fx_pro", text_color = color.new(color.gray, 70), text_size = size.large)

buildProfile(window) =>
    result = Profile.new()
    rangeHigh = bars.last().highPrice
    rangeLow = bars.last().lowPrice
    for i = 0 to window - 1
        sample = bars.get(bars.size() - 1 - i)
        rangeHigh := math.max(rangeHigh, sample.highPrice)
        rangeLow := math.min(rangeLow, sample.lowPrice)
    step = math.max((rangeHigh - rangeLow) / resolution, syminfo.mintick)
    totals = array.new_float(resolution + 1, 0.0)
    ups = array.new_float(resolution + 1, 0.0)
    lowerBars = 0
    missingBars = 0
    for i = 0 to window - 1
        sample = bars.get(bars.size() - 1 - i)
        lowerBars += sample.lowerData ? 1 : 0
        missingBars += sample.missingVolume ? 1 : 0
        for j = 0 to sample.volumes.size() - 1
            allocateVolume(totals, ups, sample.lows.get(j), sample.highs.get(j), sample.volumes.get(j), sample.upVolumes.get(j), rangeLow, step)
    rowVolumes = array.new_float(resolution, 0.0)
    rowUps = array.new_float(resolution, 0.0)
    runningTotal = 0.0
    runningUp = 0.0
    for i = 0 to resolution - 1
        runningTotal += totals.get(i)
        runningUp += ups.get(i)
        rowVolumes.set(i, math.max(0.0, runningTotal))
        rowUps.set(i, math.max(0.0, math.min(runningTotal, runningUp)))
    total = rowVolumes.sum()
    maximum = rowVolumes.max()
    pocRow = rowVolumes.indexof(maximum)
    lower = pocRow
    upper = pocRow
    areaVolume = rowVolumes.get(pocRow)
    target = total * valueAreaPercent / 100.0
    while areaVolume < target and (lower > 0 or upper < resolution - 1)
        above = upper < resolution - 1 ? rowVolumes.get(upper + 1) : -1.0
        below = lower > 0 ? rowVolumes.get(lower - 1) : -1.0
        if above >= below and upper < resolution - 1
            upper += 1
            areaVolume += rowVolumes.get(upper)
        else
            lower -= 1
            areaVolume += rowVolumes.get(lower)
    result.volumes := rowVolumes
    result.upVolumes := rowUps
    result.smoothed := smoothRows(rowVolumes)
    result.bottom := rangeLow
    result.step := step
    result.total := total
    result.maximum := maximum
    result.upTotal := rowUps.sum()
    result.poc := rangeLow + (pocRow + 0.5) * step
    result.vah := rangeLow + (upper + 1) * step
    result.val := rangeLow + lower * step
    result.pocRow := pocRow
    result.vahRow := upper
    result.valRow := lower
    result.bars := window
    result.left := bar_index - window + 1
    result.updated := bar_index
    result.lowerBars := lowerBars
    result.missingBars := missingBars
    result.valid := total > 0 and maximum > 0
    result

makeCandidate(Profile data, row, kind) =>
    radius = usesZone(kind) ? zoneRadius : 0
    first = math.max(0, row - radius)
    last = math.min(resolution - 1, row + radius)
    price = kind == 2 ? data.vah : kind == -2 ? data.val : data.bottom + (row + 0.5) * data.step
    top = usesZone(kind) ? data.bottom

Показано первые 50% кода (символов: 45311)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
4 531,10₽ ≈ $55.39