Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Source Code


//@version=6
indicator("PSAR Trend Filter", shorttitle="PSAR Trend Filter", overlay=true, max_labels_count=500)

//---------------------------------------------------------
// INPUTS
//---------------------------------------------------------
const string calcGroup   = "Calculation"
const string filterGroup = "Signal Filters"
const string visualGroup = "Visuals"

start     = input.float(0.02, step=0.001, title="PSAR Start", group=calcGroup)
increment = input.float(0.02, step=0.001, title="PSAR Increment", group=calcGroup)
maximum   = input.float(0.20, step=0.01,  title="PSAR Maximum", group=calcGroup)

confirmOnClose  = input.bool(true,  title="Confirm Signals On Bar Close", group=filterGroup)
useEMAFilter    = input.bool(true,  title="Use EMA Trend Filter", group=filterGroup)
emaLength       = input.int(50, minval=1, title="EMA Length", group=filterGroup)
useADXFilter    = input.bool(true,  title="Use ADX Strength Filter", group=filterGroup)
adxLength       = input.int(14, minval=1, title="ADX Length", group=filterGroup)
adxMin          = input.float(15.0, step=0.5, title="Minimum ADX", group=filterGroup)
useCandleFilter = input.bool(false, title="Use Candle Confirmation", group=filterGroup)
useCooldown     = input.bool(true,  title="Use Cooldown Between Signals", group=filterGroup)
cooldownBars    = input.int(1, minval=0, title="Cooldown Bars", group=filterGroup)

psarWidth            = input.int(2, minval=1, maxval=4, title="PSAR Point Width", group=visualGroup)
highlightStartPoints = input.bool(false, title="Highlight Start Points", group=visualGroup)
highlightState       = input.bool(true,  title="Highlight Trend State", group=visualGroup)
showEMA              = input.bool(true,  title="Show EMA Filter", group=visualGroup)

//---------------------------------------------------------
// CORE CALCULATION
//---------------------------------------------------------
psar = ta.sar(start, increment, maximum)
dir  = close > psar ? 1 : -1

rawBuySignal  = ta.crossover(close, psar)
rawSellSignal = ta.crossunder(close, psar)

emaValue = ta.ema(close, emaLength)

// Правильное получение ADX
[_, _, adxValue] = ta.dmi(adxLength, adxLength)

//---------------------------------------------------------
// FILTERS
//---------------------------------------------------------
trendLongOk  = not useEMAFilter or close > emaValue
trendShortOk = not useEMAFilter or close < emaValue

// Проверка на na(), чтобы индикатор работал корректно с самого начала истории
strengthOk = not useADXFilter or (not na(adxValue) and adxValue >= adxMin)

candleLongOk  = not useCandleFilter or close > open
candleShortOk = not useCandleFilter or close < open
barConfirmed = not confirmOnClose or barstate.isconfirmed

var int lastSignalBar = 0
cooldownOk = not useCooldown or (bar_index - lastSignalBar > cooldownBars)

buySignal  = rawBuySignal and trendLongOk and strengthOk and candleLongOk and cooldownOk and barConfirmed
sellSignal = rawSellSignal and trendShortOk and strengthOk and candleShortOk and cooldownOk and barConfirmed

if buySignal or sellSignal
    lastSignalBar := bar_index

//---------------------------------------------------------
// COLORS
//---------------------------------------------------------
bullColor      = color.rgb(0, 184, 148)
bearColor      = color.rgb(214, 48, 49)
emaColor       = color.rgb(120, 120, 120)
bullFillColor  = color.new(bullColor, 88)
bearFillColor  = color.new(bearColor, 88)
startBullColor = color.new(bullColor, 0)
startBearColor = color.new(bearColor, 0)

psarColor = dir == 1 ? bullColor : bearColor

//---------------------------------------------------------
// PLOTS
//---------------------------------------------------------
psarPlot = plot(psar, title="PSAR", style=plot.style_circles, linewidth=psarWidth, color=psarColor)
emaPlot  = plot(showEMA and useEMAFilter ? emaValue : na, title="EMA Filter", color=emaColor, linewidth=2)

// Исправленный блок заливки фона
midPricePlot = plot(ohlc4, title="Mid Price", display=display.none, editable=false)
c_fill = highlightState ? (dir == 1 ? bullFillColor : bearFillColor) : color(na)
fill(midPricePlot, psarPlot, title="Trend State Fill", color=c_fill)

plotshape(rawBuySignal and highlightStartPoints ? psar : na, title="Raw Long Start", location=location.absolute, style=shape.circle, size=size.small, color=startBullColor)
plotshape(rawSellSignal and highlightStartPoints ? psar : na, title="Raw Short Start", location=location.absolute, style=shape.circle, size=size.small, color=startBearColor)

//---------------------------------------------------------
// ALERTS
//---------------------------------------------------------
alertcondition(rawBuySignal or rawSellSignal, title="PSAR Raw Direction Change", message="PSAR raw direction changed on {{exchange}}:{{ticker}}")
alertcondition(buySignal, title="PSAR Filtered Long", message="MarketStructureLab PSAR Trend Filter FREE LONG on {{exchange}}:{{ticker}}")
alertcondition(sellSignal, title="PSAR Filtered Short", message="MarketStructureLab PSAR Trend Filter FREE SHORT on {{exchange}}:{{ticker}}")