Исходный код
Представленный ниже скрипт для Pine Script v5 позволяет автоматически определять ключевые элементы рыночной структуры: Break of Structure (BOS) и Change of Character (CHoCH). Он использует метод определения пивотов (поворотных точек) для построения неперерисовывающегося зигзага, что является основой для идентификации тренда и его изменений. Скрипт визуализирует эти события на графике с помощью линий и текстовых меток, а также отображает линии, соединяющие подтвержденные свинг-точки.
//@version=5
indicator("Market Structure (BOS & CHoCH) with Zigzag", overlay=true, max_labels_count=500, max_lines_count=500)
// --- Inputs ---
pivotLookback = input.int(10, "Pivot Lookback (Bars)", minval=5, maxval=50)
showBOS = input.bool(true, "Show Break of Structure (BOS)")
bosColor = input.color(color.new(color.green, 0), "BOS Color")
showCHoCH = input.bool(true, "Show Change of Character (CHoCH)")
chochColor = input.color(color.new(color.red, 0), "CHoCH Color")
showSwingLines = input.bool(true, "Show Swing Lines")
swingLineColor = input.color(color.new(color.gray, 70), "Swing Line Color")
labelOffset = input.float(0.005, "Label Offset (Price %)", minval=0.001, maxval=0.05) // Unified offset
// --- Global Variables for Market Structure ---
// Store confirmed swing points and their bar indices
var float lastConfirmedHigh = na
var int lastConfirmedHighBarIndex = na
var float lastConfirmedLow = na
var int lastConfirmedLowBarIndex = na
var float previousConfirmedHigh = na
var int previousConfirmedHighBarIndex = na
var float previousConfirmedLow = na
var int previousConfirmedLowBarIndex = na
// --- Helper Functions ---
// Function to identify a pivot high
f_isPivotHigh(src, lookback) =>
src[lookback] == ta.highest(src, lookback + 1) and src[lookback] == ta.highest(src[lookback], lookback)
// Function to identify a pivot low
f_isPivotLow(src, lookback) =>
src[lookback] == ta.lowest(src, lookback + 1) and src[lookback] == ta.lowest(src[lookback], lookback)
// --- Main Logic ---
isHighPivot = f_isPivotHigh(high, pivotLookback)
isLowPivot = f_isPivotLow(low, pivotLookback)
// Update confirmed swing points
if isHighPivot
previousConfirmedHigh := lastConfirmedHigh
previousConfirmedHighBarIndex := lastConfirmedHighBarIndex
lastConfirmedHigh := high[pivotLookback]
lastConfirmedHighBarIndex := bar_index[pivotLookback]
if isLowPivot
previousConfirmedLow := lastConfirmedLow
previousConfirmedLowBarIndex := lastConfirmedLowBarIndex
lastConfirmedLow := low[pivotLookback]
lastConfirmedLowBarIndex := bar_index[pivotLookback]
// Determine current market trend based on confirmed swings
var string currentMarketTrend = "neutral" // "bullish", "bearish", "ranging"
// Only determine trend if we have at least two confirmed highs and lows
if not na(lastConfirmedHigh) and not na(lastConfirmedLow) and not na(previousConfirmedHigh) and not na(previousConfirmedLow)
bool isHigherHigh = lastConfirmedHigh > previousConfirmedHigh
bool isLowerHigh = lastConfirmedHigh < previousConfirmedHigh
bool isHigherLow = lastConfirmedLow > previousConfirmedLow
bool isLowerLow = lastConfirmedLow < previousConfirmedLow
if isHigherHigh and isHigherLow
currentMarketTrend := "bullish"
else if isLowerHigh and isLowerLow
currentMarketTrend := "bearish"
else
currentMarketTrend := "ranging" // Price is consolidating or unclear trend
// --- BOS and CHoCH Detection ---
// Use arrays to store lines and labels for persistence
var line[] bosLines = array.new_line()
var label[] bosLabels = array.new_label()
var line[] chochLines = array.new_line()
var label[] chochLabels = array.new_label()
// Clear old lines/labels to manage memory and avoid clutter
// For simplicity, we'll keep a limited number.
maxObjects = 100 // Max lines/labels to keep on chart
if array.size(bosLines) > maxObjects
line.delete(array.shift(bosLines))
if array.size(bosLabels) > maxObjects
label.delete(array.shift(bosLabels))
if array.size(chochLines) > maxObjects
line.delete(array.shift(chochLines))
if array.size(chochLabels) > maxObjects
label.delete(array.shift(chochLabels))
// Ensure we have enough confirmed swings to determine structure
if not na(lastConfirmedHigh) and not na(lastConfirmedLow) and not na(previousConfirmedHigh) and not na(previousConfirmedLow)
// Break of Structure (BOS)
if showBOS
// Bullish BOS: Price breaks above lastConfirmedHigh in a bullish trend
if currentMarketTrend == "bullish" and close > lastConfirmedHigh and bar_index > lastConfirmedHighBarIndex
array.push(bosLines, line.new(lastConfirmedHighBarIndex, lastConfirmedHigh, bar_index, lastConfirmedHigh, xloc=xloc.bar_index, extend=extend.right, color=bosColor, style=line.style_dashed, width=1))
array.push(bosLabels, label.new(bar_index, lastConfirmedHigh * (1 + labelOffset), "BOS", xloc=xloc.bar_index, yloc=yloc.abovebar, color=bosColor, textcolor=color.white, style=label.style_label_down))
// Bearish BOS: Price breaks below lastConfirmedLow in a bearish trend
else if currentMarketTrend == "bearish" and close < lastConfirmedLow and bar_index > lastConfirmedLowBarIndex
array.push(bosLines, line.new(lastConfirmedLowBarIndex, lastConfirmedLow, bar_index, lastConfirmedLow, xloc=xloc.bar_index, extend=extend.right, color=bosColor, style=line.style_dashed, width=1))
array.push(bosLabels, label.new(bar_index, lastConfirmedLow * (1 - labelOffset), "BOS", xloc=xloc.bar_index, yloc=yloc.belowbar, color=bosColor, textcolor=color.white, style=label.style_label_up))
// Change of Character (CHoCH)
if showCHoCH
// Bullish CHoCH: Price breaks above lastConfirmedHigh in a bearish trend (potential reversal)
if currentMarketTrend == "bearish" and close > lastConfirmedHigh and bar_index > lastConfirmedHighBarIndex
array.push(chochLines, line.new(lastConfirmedHighBarIndex, lastConfirmedHigh, bar_index, lastConfirmedHigh, xloc=xloc.bar_index, extend=extend.right, color=chochColor, style=line.style_dashed, width=1))
array.push(chochLabels, label.new(bar_index, lastConfirmedHigh * (1 + labelOffset), "CHoCH", xloc=xloc.bar_index, yloc=yloc.abovebar, color=chochColor, textcolor=color.white, style=label.style_label_down))
// Bearish CHoCH: Price breaks below lastConfirmedLow in a bullish trend (potential reversal)
else if currentMarketTrend == "bullish" and close < lastConfirmedLow and bar_index > lastConfirmedLowBarIndex
array.push(chochLines, line.new(lastConfirmedLowBarIndex, lastConfirmedLow, bar_index, lastConfirmedLow, xloc=xloc.bar_index, extend=extend.right, color=chochColor, style=line.style_dashed, width=1))
array.push(chochLabels, label.new(bar_index, lastConfirmedLow * (1 - labelOffset), "CHoCH", xloc=xloc.bar_index, yloc=yloc.belowbar, color=chochColor, textcolor=color.white, style=label.style_label_up))
// --- Plotting Swing Lines ---
// Use arrays for swing lines to persist them
var line[] swingLines = array.new_line()
if array.size(swingLines) > maxObjects
line.delete(array.shift(swingLines))
if showSwingLines and not na(lastConfirmedHigh) and not na(lastConfirmedLow) and not na(previousConfirmedHigh) and not na(previousConfirmedLow)
// Plot lines connecting previous confirmed high to last confirmed high
if not na(previousConfirmedHighBarIndex) and not na(lastConfirmedHighBarIndex) and previousConfirmedHighBarIndex < lastConfirmedHighBarIndex
array.push(swingLines, line.new(previousConfirmedHighBarIndex, previousConfirmedHigh, lastConfirmedHighBarIndex, lastConfirmedHigh, xloc=xloc.bar_index, color=swingLineColor, width=1))
// Plot lines connecting previous confirmed low to last confirmed low
if not na(previousConfirmedLowBarIndex) and not na(lastConfirmedLowBarIndex) and previousConfirmedLowBarIndex < lastConfirmedLowBarIndex
array.push(swingLines, line.new(previousConfirmedLowBarIndex, previousConfirmedLow, lastConfirmedLowBarIndex, lastConfirmedLow, xloc=xloc.bar_index, color=swingLineColor, width=1))
// Plot current swing points for debugging/visualization
plot(lastConfirmedHigh, "Last Confirmed High", color.blue, style=plot.style_circles, linewidth=2)
plot(lastConfirmedLow, "Last Confirmed Low", color.fuchsia, style=plot.style_circles, linewidth=2)
// Optional: Plot current trend for visualization
plotshape(currentMarketTrend == "bullish" ? low : na, "Bullish Trend", shape.triangleup, location.belowbar, color.green, size=size.tiny)
plotshape(currentMarketTrend == "bearish" ? high : na, "Bearish Trend", shape.triangledown, location.abovebar, color.red, size=size.tiny)
Разбор параметров
pivotLookback: Определяет количество баров, используемых для подтверждения пивота (поворотной точки). Большее значение делает зигзаг более сглаженным, игнорируя мелкие колебания, но увеличивает задержку в определении пивота.showBOS: Логический переключатель для отображения меток и линий Break of Structure (BOS) на графике.bosColor: Цвет, используемый для линий и меток BOS.showCHoCH: Логический переключатель для отображения меток и линий Change of Character (CHoCH) на графике.chochColor: Цвет, используемый для линий и меток CHoCH.showSwingLines: Логический переключатель для отображения линий, соединяющих подтвержденные свинг-максимумы и свинг-минимумы, формируя визуальный зигзаг.swingLineColor: Цвет для линий, соединяющих свинг-точки.labelOffset: Процентное смещение для меток BOS и CHoCH относительно цены, чтобы они не перекрывали свечи.
Как запустить
Чтобы использовать этот скрипт в TradingView, выполните следующие шаги:
-
Откройте TradingView и перейдите в раздел Pine Editor (обычно находится в нижней части экрана).
-
Удалите любой существующий код в редакторе и вставьте предоставленный выше скрипт.
-
Нажмите кнопку 'Добавить на график' (Add to Chart) в правом верхнем углу Pine Editor.
-
Индикатор появится на вашем графике. Вы можете настроить его параметры, такие как
pivotLookback, цвета и видимость BOS/CHoCH, через меню настроек индикатора на графике.
Этот скрипт является мощным инструментом для автоматизации анализа рыночной структуры, что особенно полезно для трейдеров, использующих концепции Smart Money (SMC) или Price Action. Он может служить основой для более сложных торговых стратегий, например, для генерации сигналов, которые затем можно интегрировать с внешними платформами. Для более сложных торговых систем, которые могут использовать эти сигналы, рассмотрите статью Интеграция Pine Script v5 с 3Commas: Кастомные JSON Сигналы для DCA Бота.
Если вы планируете использовать эти сигналы для управления позициями, вам может быть полезна статья Динамический Размер Позиции в Pine Script v5: Расчет % от Капитала, которая поможет вам эффективно управлять рисками.
Для анализа рыночной структуры на разных таймфреймах, что может дополнить данный скрипт, изучите Мульти-таймфреймный FVG в Pine Script v5: руководство без перерисовки. Комбинируя эти подходы, вы сможете создать более комплексную и надежную торговую систему.




