OPEN-SOURCE SCRIPT
Trend River Pullback (Avramis-style) v1

//version=5
strategy("Trend River Pullback (Avramis-style) v1",
overlay=true, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.02,
pyramiding=0, calc_on_order_fills=true, calc_on_every_tick=true, margin_long=1, margin_short=1)
// ===== Inputs
// EMA "река"
emaFastLen = input.int(8, "EMA1 (быстрая)")
ema2Len = input.int(13, "EMA2")
emaMidLen = input.int(21, "EMA3 (средняя)")
ema4Len = input.int(34, "EMA4")
emaSlowLen = input.int(55, "EMA5 (медленная)")
// Откат и импульс
rsiLen = input.int(14, "RSI длина")
rsiOB = input.int(60, "RSI порог тренда (лонг)")
rsiOS = input.int(40, "RSI порог тренда (шорт)")
pullbackPct = input.float(40.0, "Глубина отката в % ширины реки", minval=0, maxval=100)
// Риск-менеджмент
riskPct = input.float(1.0, "Риск на сделку, % от капитала", step=0.1, minval=0.1)
atrLen = input.int(14, "ATR длина (стоп/трейлинг)")
atrMultSL = input.float(2.0, "ATR множитель для стопа", step=0.1)
tpRR = input.float(2.0, "Тейк-профит R-множитель", step=0.1)
// Трейлинг-стоп
useTrail = input.bool(true, "Включить трейлинг-стоп (Chandelier)")
trailMult = input.float(3.0, "ATR множитель трейлинга", step=0.1)
// Торговые часы (по времени биржи TradingView символа)
useSession = input.bool(false, "Ограничить торговые часы")
sessInput = input.session("0900-1800", "Сессия (локальная для биржи)")
// ===== Calculations
ema1 = ta.ema(close, emaFastLen)
ema2 = ta.ema(close, ema2Len)
ema3 = ta.ema(close, emaMidLen)
ema4 = ta.ema(close, ema4Len)
ema5 = ta.ema(close, emaSlowLen)
// "Река": верх/низ как конверт по средним
riverTop = math.max(math.max(ema1, ema2), math.max(ema3, math.max(ema4, ema5)))
riverBot = math.min(math.min(ema1, ema2), math.min(ema3, math.min(ema4, ema5)))
riverMid = (riverTop + riverBot) / 2.0
riverWidth = riverTop - riverBot
// Трендовые условия: выстроенность EMAs
bullAligned = ema1 > ema2 and ema2 > ema3 and ema3 > ema4 and ema4 > ema5
bearAligned = ema1 < ema2 and ema2 < ema3 and ema3 < ema4 and ema4 < ema5
// Импульс
rsi = ta.rsi(close, rsiLen)
// Откат внутрь "реки"
pullbackLevelBull = riverTop - riverWidth * (pullbackPct/100.0) // чем больше %, тем глубже внутрь
pullbackLevelBear = riverBot + riverWidth * (pullbackPct/100.0)
pullbackOkBull = bullAligned and rsi >= rsiOB and low <= pullbackLevelBull
pullbackOkBear = bearAligned and rsi <= rsiOS and high >= pullbackLevelBear
// Триггер входа: возврат в импульс (пересечение быстрой EMA)
longTrig = pullbackOkBull and ta.crossover(close, ema1)
shortTrig = pullbackOkBear and ta.crossunder(close, ema1)
// Сессия
inSession = useSession ? time(timeframe.period, sessInput) : true
// ATR для стопов
atr = ta.atr(atrLen)
// ===== Position sizing по риску
// Расчет размера позиции: риск% от капитала / (стоп в деньгах)
capital = strategy.equity
riskMoney = capital * (riskPct/100.0)
// Предварительные уровни стопов
longSL = close - atrMultSL * atr
shortSL = close + atrMultSL * atr
// Цена тика и размер — приблизительно через syminfo.pointvalue (может отличаться на разных рынках)
tickValue = syminfo.pointvalue
// Избежать деления на 0
slDistLong = math.max(close - longSL, syminfo.mintick)
slDistShort = math.max(shortSL - close, syminfo.mintick)
// Кол-во контрактов/лотов
qtyLong = riskMoney / (slDistLong * tickValue)
qtyShort = riskMoney / (slDistShort * tickValue)
// Ограничение: не меньше 0
qtyLong := math.max(qtyLong, 0)
qtyShort := math.max(qtyShort, 0)
// ===== Entries
if inSession and longTrig and strategy.position_size <= 0
strategy.entry("Long", strategy.long, qty=qtyLong)
if inSession and shortTrig and strategy.position_size >= 0
strategy.entry("Short", strategy.short, qty=qtyShort)
// ===== Exits: фиксированный TP по R и стоп
// Храним цену входа
var float entryPrice = na
if strategy.position_size != 0 and na(entryPrice)
entryPrice := strategy.position_avg_price
if strategy.position_size == 0
entryPrice := na
// Цели
longTP = na(entryPrice) ? na : entryPrice + tpRR * (entryPrice - longSL)
shortTP = na(entryPrice) ? na : entryPrice - tpRR * (shortSL - entryPrice)
// Трейлинг: Chandelier
trailLong = close - trailMult * atr
trailShort = close + trailMult * atr
// Итоговые уровни выхода
useTrailLong = useTrail and strategy.position_size > 0
useTrailShort = useTrail and strategy.position_size < 0
// Для лонга
if strategy.position_size > 0
stopL = math.max(longSL, na) // базовый стоп
tStop = useTrailLong ? trailLong : longSL
// Выход по стопу/трейлу и ТП
strategy.exit("L-Exit", from_entry="Long", stop=tStop, limit=longTP)
// Для шорта
if strategy.position_size < 0
stopS = math.min(shortSL, na)
tStopS = useTrailShort ? trailShort : shortSL
strategy.exit("S-Exit", from_entry="Short", stop=tStopS, limit=shortTP)
// ===== Visuals
plot(ema1, "EMA1", display=display.all, linewidth=1)
plot(ema2, "EMA2", display=display.all, linewidth=1)
plot(ema3, "EMA3", display=display.all, linewidth=2)
plot(ema4, "EMA4", display=display.all, linewidth=1)
plot(ema5, "EMA5", display=display.all, linewidth=1)
plot(riverTop, "River Top", style=plot.style_linebr, linewidth=1)
plot(riverBot, "River Bot", style=plot.style_linebr, linewidth=1)
fill(plot1=plot(riverTop, display=display.none), plot2=plot(riverBot, display=display.none), title="River Fill", transp=80)
plot(longTP, "Long TP", style=plot.style_linebr)
plot(shortTP, "Short TP", style=plot.style_linebr)
plot(useTrailLong ? trailLong : na, "Trail Long", style=plot.style_linebr)
plot(useTrailShort ? trailShort : na, "Trail Short", style=plot.style_linebr)
// Маркеры сигналов
plotshape(longTrig, title="Long Trigger", style=shape.triangleup, location=location.belowbar, size=size.tiny, text="L")
plotshape(shortTrig, title="Short Trigger", style=shape.triangledown, location=location.abovebar, size=size.tiny, text="S")
// ===== Alerts
alertcondition(longTrig, title="Long Signal", message="Long signal: trend aligned + pullback + momentum")
alertcondition(shortTrig, title="Short Signal", message="Short signal: trend aligned + pullback + momentum")
strategy("Trend River Pullback (Avramis-style) v1",
overlay=true, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.02,
pyramiding=0, calc_on_order_fills=true, calc_on_every_tick=true, margin_long=1, margin_short=1)
// ===== Inputs
// EMA "река"
emaFastLen = input.int(8, "EMA1 (быстрая)")
ema2Len = input.int(13, "EMA2")
emaMidLen = input.int(21, "EMA3 (средняя)")
ema4Len = input.int(34, "EMA4")
emaSlowLen = input.int(55, "EMA5 (медленная)")
// Откат и импульс
rsiLen = input.int(14, "RSI длина")
rsiOB = input.int(60, "RSI порог тренда (лонг)")
rsiOS = input.int(40, "RSI порог тренда (шорт)")
pullbackPct = input.float(40.0, "Глубина отката в % ширины реки", minval=0, maxval=100)
// Риск-менеджмент
riskPct = input.float(1.0, "Риск на сделку, % от капитала", step=0.1, minval=0.1)
atrLen = input.int(14, "ATR длина (стоп/трейлинг)")
atrMultSL = input.float(2.0, "ATR множитель для стопа", step=0.1)
tpRR = input.float(2.0, "Тейк-профит R-множитель", step=0.1)
// Трейлинг-стоп
useTrail = input.bool(true, "Включить трейлинг-стоп (Chandelier)")
trailMult = input.float(3.0, "ATR множитель трейлинга", step=0.1)
// Торговые часы (по времени биржи TradingView символа)
useSession = input.bool(false, "Ограничить торговые часы")
sessInput = input.session("0900-1800", "Сессия (локальная для биржи)")
// ===== Calculations
ema1 = ta.ema(close, emaFastLen)
ema2 = ta.ema(close, ema2Len)
ema3 = ta.ema(close, emaMidLen)
ema4 = ta.ema(close, ema4Len)
ema5 = ta.ema(close, emaSlowLen)
// "Река": верх/низ как конверт по средним
riverTop = math.max(math.max(ema1, ema2), math.max(ema3, math.max(ema4, ema5)))
riverBot = math.min(math.min(ema1, ema2), math.min(ema3, math.min(ema4, ema5)))
riverMid = (riverTop + riverBot) / 2.0
riverWidth = riverTop - riverBot
// Трендовые условия: выстроенность EMAs
bullAligned = ema1 > ema2 and ema2 > ema3 and ema3 > ema4 and ema4 > ema5
bearAligned = ema1 < ema2 and ema2 < ema3 and ema3 < ema4 and ema4 < ema5
// Импульс
rsi = ta.rsi(close, rsiLen)
// Откат внутрь "реки"
pullbackLevelBull = riverTop - riverWidth * (pullbackPct/100.0) // чем больше %, тем глубже внутрь
pullbackLevelBear = riverBot + riverWidth * (pullbackPct/100.0)
pullbackOkBull = bullAligned and rsi >= rsiOB and low <= pullbackLevelBull
pullbackOkBear = bearAligned and rsi <= rsiOS and high >= pullbackLevelBear
// Триггер входа: возврат в импульс (пересечение быстрой EMA)
longTrig = pullbackOkBull and ta.crossover(close, ema1)
shortTrig = pullbackOkBear and ta.crossunder(close, ema1)
// Сессия
inSession = useSession ? time(timeframe.period, sessInput) : true
// ATR для стопов
atr = ta.atr(atrLen)
// ===== Position sizing по риску
// Расчет размера позиции: риск% от капитала / (стоп в деньгах)
capital = strategy.equity
riskMoney = capital * (riskPct/100.0)
// Предварительные уровни стопов
longSL = close - atrMultSL * atr
shortSL = close + atrMultSL * atr
// Цена тика и размер — приблизительно через syminfo.pointvalue (может отличаться на разных рынках)
tickValue = syminfo.pointvalue
// Избежать деления на 0
slDistLong = math.max(close - longSL, syminfo.mintick)
slDistShort = math.max(shortSL - close, syminfo.mintick)
// Кол-во контрактов/лотов
qtyLong = riskMoney / (slDistLong * tickValue)
qtyShort = riskMoney / (slDistShort * tickValue)
// Ограничение: не меньше 0
qtyLong := math.max(qtyLong, 0)
qtyShort := math.max(qtyShort, 0)
// ===== Entries
if inSession and longTrig and strategy.position_size <= 0
strategy.entry("Long", strategy.long, qty=qtyLong)
if inSession and shortTrig and strategy.position_size >= 0
strategy.entry("Short", strategy.short, qty=qtyShort)
// ===== Exits: фиксированный TP по R и стоп
// Храним цену входа
var float entryPrice = na
if strategy.position_size != 0 and na(entryPrice)
entryPrice := strategy.position_avg_price
if strategy.position_size == 0
entryPrice := na
// Цели
longTP = na(entryPrice) ? na : entryPrice + tpRR * (entryPrice - longSL)
shortTP = na(entryPrice) ? na : entryPrice - tpRR * (shortSL - entryPrice)
// Трейлинг: Chandelier
trailLong = close - trailMult * atr
trailShort = close + trailMult * atr
// Итоговые уровни выхода
useTrailLong = useTrail and strategy.position_size > 0
useTrailShort = useTrail and strategy.position_size < 0
// Для лонга
if strategy.position_size > 0
stopL = math.max(longSL, na) // базовый стоп
tStop = useTrailLong ? trailLong : longSL
// Выход по стопу/трейлу и ТП
strategy.exit("L-Exit", from_entry="Long", stop=tStop, limit=longTP)
// Для шорта
if strategy.position_size < 0
stopS = math.min(shortSL, na)
tStopS = useTrailShort ? trailShort : shortSL
strategy.exit("S-Exit", from_entry="Short", stop=tStopS, limit=shortTP)
// ===== Visuals
plot(ema1, "EMA1", display=display.all, linewidth=1)
plot(ema2, "EMA2", display=display.all, linewidth=1)
plot(ema3, "EMA3", display=display.all, linewidth=2)
plot(ema4, "EMA4", display=display.all, linewidth=1)
plot(ema5, "EMA5", display=display.all, linewidth=1)
plot(riverTop, "River Top", style=plot.style_linebr, linewidth=1)
plot(riverBot, "River Bot", style=plot.style_linebr, linewidth=1)
fill(plot1=plot(riverTop, display=display.none), plot2=plot(riverBot, display=display.none), title="River Fill", transp=80)
plot(longTP, "Long TP", style=plot.style_linebr)
plot(shortTP, "Short TP", style=plot.style_linebr)
plot(useTrailLong ? trailLong : na, "Trail Long", style=plot.style_linebr)
plot(useTrailShort ? trailShort : na, "Trail Short", style=plot.style_linebr)
// Маркеры сигналов
plotshape(longTrig, title="Long Trigger", style=shape.triangleup, location=location.belowbar, size=size.tiny, text="L")
plotshape(shortTrig, title="Short Trigger", style=shape.triangledown, location=location.abovebar, size=size.tiny, text="S")
// ===== Alerts
alertcondition(longTrig, title="Long Signal", message="Long signal: trend aligned + pullback + momentum")
alertcondition(shortTrig, title="Short Signal", message="Short signal: trend aligned + pullback + momentum")
Mã nguồn mở
Theo đúng tinh thần TradingView, người tạo ra tập lệnh này đã biến tập lệnh thành mã nguồn mở để các nhà giao dịch có thể xem xét và xác minh công năng. Xin dành lời khen tặng cho tác giả! Mặc dù bạn có thể sử dụng miễn phí, nhưng lưu ý nếu đăng lại mã, bạn phải tuân theo Quy tắc nội bộ của chúng tôi.
Thông báo miễn trừ trách nhiệm
Thông tin và ấn phẩm không có nghĩa là và không cấu thành, tài chính, đầu tư, kinh doanh, hoặc các loại lời khuyên hoặc khuyến nghị khác được cung cấp hoặc xác nhận bởi TradingView. Đọc thêm trong Điều khoản sử dụng.
Mã nguồn mở
Theo đúng tinh thần TradingView, người tạo ra tập lệnh này đã biến tập lệnh thành mã nguồn mở để các nhà giao dịch có thể xem xét và xác minh công năng. Xin dành lời khen tặng cho tác giả! Mặc dù bạn có thể sử dụng miễn phí, nhưng lưu ý nếu đăng lại mã, bạn phải tuân theo Quy tắc nội bộ của chúng tôi.
Thông báo miễn trừ trách nhiệm
Thông tin và ấn phẩm không có nghĩa là và không cấu thành, tài chính, đầu tư, kinh doanh, hoặc các loại lời khuyên hoặc khuyến nghị khác được cung cấp hoặc xác nhận bởi TradingView. Đọc thêm trong Điều khoản sử dụng.