Автоматическое определение рыночной структуры (BOS и CHoCH) в Pine Script v5

Автоматическое определение рыночной структуры (BOS и CHoCH) в Pine Script v5 Pine Script
Подробное руководство по созданию скрипта Pine Script v5 для автоматического определения Break of Structure (BOS) и Change of Character (CHoCH) на основе зигзага, с визуализацией на графике.
Суть: Скрипт Pine Script v5 использует неперерисовывающийся метод определения зигзага для идентификации значимых максимумов и минимумов, на основе которых автоматически определяет Break of Structure (BOS) и Change of Character (CHoCH), визуализируя их на графике для анализа рыночной структуры.

Исходный код

Представленный ниже скрипт для 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, выполните следующие шаги:

  1. Откройте TradingView и перейдите в раздел Pine Editor (обычно находится в нижней части экрана).

  2. Удалите любой существующий код в редакторе и вставьте предоставленный выше скрипт.

  3. Нажмите кнопку 'Добавить на график' (Add to Chart) в правом верхнем углу Pine Editor.

  4. Индикатор появится на вашем графике. Вы можете настроить его параметры, такие как pivotLookback, цвета и видимость BOS/CHoCH, через меню настроек индикатора на графике.

Этот скрипт является мощным инструментом для автоматизации анализа рыночной структуры, что особенно полезно для трейдеров, использующих концепции Smart Money (SMC) или Price Action. Он может служить основой для более сложных торговых стратегий, например, для генерации сигналов, которые затем можно интегрировать с внешними платформами. Для более сложных торговых систем, которые могут использовать эти сигналы, рассмотрите статью Интеграция Pine Script v5 с 3Commas: Кастомные JSON Сигналы для DCA Бота.

Если вы планируете использовать эти сигналы для управления позициями, вам может быть полезна статья Динамический Размер Позиции в Pine Script v5: Расчет % от Капитала, которая поможет вам эффективно управлять рисками.

Для анализа рыночной структуры на разных таймфреймах, что может дополнить данный скрипт, изучите Мульти-таймфреймный FVG в Pine Script v5: руководство без перерисовки. Комбинируя эти подходы, вы сможете создать более комплексную и надежную торговую систему.


Оцените статью
FinFluct