OPEN-SOURCE SCRIPT

Scalp EMA+RSI+ADX+Vol v7 (универсальная, x25)

104
// version=6
// Scalp EMA+RSI+ADX+Vol v7 — универсальная версия с ликвидационным стопом (x25)
// Автор: ChatGPT

// === ПАРАМЕТРЫ ===
percent_of_equity = input.float(2.0, "Position size (% of equity)", step=0.1, minval=0.1)
fastLen = input.int(8, "Fast EMA length", minval=1)
slowLen = input.int(21, "Slow EMA length", minval=1)
rsiLen = input.int(7, "RSI length", minval=1)
rsiConfirm= input.int(50, "RSI confirmation level")
adxLen = input.int(10, "ADX length", minval=1)
adxThresh = input.int(15, "ADX threshold (min trend strength)")
volSmaLen = input.int(20, "Volume SMA length", minval=1)
volMult = input.float(0.8, "Min volume multiplier", step=0.1, minval=0.1)
atrLen = input.int(10, "ATR length", minval=1)
atrTP = input.float(1.6, "TP = x * ATR", step=0.1, minval=0.1)
useTrailing = input.bool(false, "Use trailing stop")
trailOffsetMult = input.float(0.8, "Trailing offset = x * ATR", step=0.1, minval=0.1)
maxTradesPerDay = input.int(0, "Max trades per day (0 = unlimited)")
useTimeFilter = input.bool(false, "Enable time filter (exchange time)")
startH = input.int(0, "Start hour (0-23)")
startM = input.int(0, "Start minute (0-59)")
endH = input.int(23, "End hour (0-23)")
endM = input.int(59, "End minute (0-59)")
leverage = input.int(25, "Leverage (для расчета ликвидации)", minval=1) // ← по умолчанию 25

// === STRATEGY DECLARATION ===
strategy("Scalp EMA+RSI+ADX+Vol v7 (универсальная, x25)", overlay=true,
default_qty_type=strategy.percent_of_equity, default_qty_value=2.0,
initial_capital=10000, pyramiding=1)

// === ИНДИКАТОРЫ ===
fastEMA = ta.ema(close, fastLen)
slowEMA = ta.ema(close, slowLen)
rsi = ta.rsi(close, rsiLen)
volSMA = ta.sma(volume, volSmaLen)
atr = ta.atr(atrLen)

plot(fastEMA, title="Fast EMA", linewidth=1, color=color.teal)
plot(slowEMA, title="Slow EMA", linewidth=1, color=color.orange)

// === ADX (ручной расчет) ===
upMove = high - high[1]
downMove = low[1] - low
plusDM = (upMove > downMove and upMove > 0) ? upMove : 0.0
minusDM = (downMove > upMove and downMove > 0) ? downMove : 0.0
tr = math.max(high - low, math.max(math.abs(high - close[1]), math.abs(low - close[1])))
atr_adx = ta.rma(tr, adxLen)
smPlus = ta.rma(plusDM, adxLen)
smMinus = ta.rma(minusDM, adxLen)
plusDI = atr_adx == 0 ? 0.0 : 100.0 * smPlus / atr_adx
minusDI = atr_adx == 0 ? 0.0 : 100.0 * smMinus / atr_adx
sumDI = plusDI + minusDI
dx = sumDI == 0 ? 0.0 : 100.0 * math.abs(plusDI - minusDI) / sumDI
adx = ta.rma(dx, adxLen)

// === СИГНАЛЫ ===
crossUp = ta.crossover(fastEMA, slowEMA)
crossDown = ta.crossunder(fastEMA, slowEMA)
volOK = volume > volSMA * volMult
rsiOK_long = rsi > rsiConfirm
rsiOK_short = rsi < rsiConfirm
adxOK = adx >= adxThresh
candleBull= close > open
candleBear= close < open

longSignal = crossUp and rsiOK_long and adxOK and volOK and candleBull
shortSignal = crossDown and rsiOK_short and adxOK and volOK and candleBear

// === TIME FILTER ===
s = useTimeFilter ? timestamp(year(time), month(time), dayofmonth(time), startH, startM) : na
e = useTimeFilter ? timestamp(year(time), month(time), dayofmonth(time), endH, endM) : na
inTradeHours = not useTimeFilter ? true : (e > s ? (time >= s and time <= e) : (time >= s or time <= e))

// === DAILY COUNTER ===
var int tradesToday = 0
var int lastDay = na
if dayofmonth(time) != lastDay
tradesToday := 0
lastDay := dayofmonth(time)
canOpenMore = (maxTradesPerDay == 0) or (tradesToday < maxTradesPerDay)

// === ENTRIES / EXITS ===
if longSignal and inTradeHours and canOpenMore and strategy.position_size == 0
entryPrice = close
liqPrice = entryPrice - entryPrice / leverage // стоп по ликвидации x25
takePrice = entryPrice + atr * atrTP
if useTrailing
strategy.entry("Long", strategy.long)
strategy.exit("Long Exit", from_entry="Long", limit=takePrice, trail_offset=atr * trailOffsetMult)
else
strategy.entry("Long", strategy.long)
strategy.exit("Long Exit", from_entry="Long", stop=liqPrice, limit=takePrice)
tradesToday += 1

if shortSignal and inTradeHours and canOpenMore and strategy.position_size == 0
entryPrice = close
liqPrice = entryPrice + entryPrice / leverage // стоп по ликвидации x25
takePrice = entryPrice - atr * atrTP
if useTrailing
strategy.entry("Short", strategy.short)
strategy.exit("Short Exit", from_entry="Short", limit=takePrice, trail_offset=atr * trailOffsetMult)
else
strategy.entry("Short", strategy.short)
strategy.exit("Short Exit", from_entry="Short", stop=liqPrice, limit=takePrice)
tradesToday += 1

// === ВИЗУАЛИЗАЦИЯ ===
plotshape(longSignal, title="Long Signal", location=location.belowbar, style=shape.triangleup, size=size.small, color=color.green, text="LONG")
plotshape(shortSignal, title="Short Signal", location=location.abovebar, style=shape.triangledown, size=size.small, color=color.red, text="SHORT")

// INFO BOX
var label info = na
if barstate.islast
label.delete(info)
infoText = "EMA: " + str.tostring(fastLen) + "/" + str.tostring(slowLen) +
" | RSI: " + str.tostring(rsiLen) + " (conf=" + str.tostring(rsiConfirm) + ")" +
" | ADX: " + str.tostring(adxLen) + "(thr=" + str.tostring(adxThresh) + ")" +
" | VolMult=" + str.tostring(volMult) +
" | ATR TP=" + str.tostring(atrTP) +
" | Leverage=" + str.tostring(leverage) + "x" +
" | TradesToday=" + str.tostring(tradesToday)
info := label.new(bar_index, high, infoText, xloc=xloc.bar_index, yloc=yloc.abovebar,
style=label.style_label_left, size=size.small, color=color.new(color.blue, 70))

Disclaimer

The information and publications are not meant to be, and do not constitute, financial, investment, trading, or other types of advice or recommendations supplied or endorsed by TradingView. Read more in the Terms of Use.