OPEN-SOURCE SCRIPT

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

44
// 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))

Pernyataan Penyangkalan

Informasi dan publikasi tidak dimaksudkan untuk menjadi, dan bukan merupakan saran keuangan, investasi, perdagangan, atau rekomendasi lainnya yang diberikan atau didukung oleh TradingView. Baca selengkapnya di Persyaratan Penggunaan.