
Представьте себе, что у вас есть старый водитель, который умеет управлять автомобилем и двигаться в обратном направлении, и он уверенно держится в ногу с рынком, независимо от того, в какую сторону он идет!
В этой стратегии используется комбинация из пяти сверхмощных показателей:
Самый умный аспект этой стратегии - это “многократная проверка”, которая требует, как при покупке жилья, отслеживания площади, типа жилья и цены:
Эта стратегия по управлению рисками, как в учебниках!
Если вы хотите использовать эту стратегию, помните о следующем:
Самая большая особенность этой стратегии заключается в том, что “вы можете атаковать, а вы можете защитить”, что бык может сделать больше, медведь может сделать меньше, а рынок не боится колебаний!
/*backtest
start: 2025-01-01 00:00:00
end: 2025-10-28 00:00:00
period: 10m
basePeriod: 10m
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
//@version=5
strategy("BankNifty LONG & SHORT Multi-Confluence",
shorttitle="BN Long-Short",
overlay=true)
// ═══════════════════════════════════════════════════════════
// 📊 STRATEGY INFO
// ═══════════════════════════════════════════════════════════
// Timeframe: 5-MINUTE CHART (Recommended)
// Direction: LONG & SHORT (Both directions)
// Asset: BankNifty Futures
// Style: Intraday Momentum Trading
// ═══════════════════════════════════════════════════════════
// ═══════════════════════════════════════════════════════════
// ⚙️ INPUT PARAMETERS
// ═══════════════════════════════════════════════════════════
// Trading Direction
tradingDirection = input.string("Both", "Trading Direction",
options=["Long Only", "Short Only", "Both"], group="🎯 Strategy Type")
// Trading Hours (IST)
startHour = input.int(9, "Start Hour", minval=0, maxval=23, group="⏰ Trading Session")
startMinute = input.int(15, "Start Minute", minval=0, maxval=59, group="⏰ Trading Session")
endHour = input.int(15, "End Hour", minval=0, maxval=23, group="⏰ Trading Session")
endMinute = input.int(15, "End Minute", minval=0, maxval=59, group="⏰ Trading Session")
avoidFirstCandles = input.int(2, "Skip First N Candles", minval=0, maxval=10, group="⏰ Trading Session")
// Position Sizing
lotSize = input.int(25, "Lot Size", minval=15, maxval=75, group="💰 Position Management")
maxContracts = input.int(75, "Max Contracts", minval=25, maxval=200, step=25, group="💰 Position Management")
riskPercent = input.float(1.0, "Risk % Per Trade", minval=0.5, maxval=3.0, step=0.1, group="💰 Position Management")
// Kernel Regression
kernelLength = input.int(20, "Kernel Length", minval=10, maxval=50, group="📈 Indicators")
// VWAP
vwapSource = input.string("Session", "VWAP Type", options=["Session", "Rolling"], group="📈 Indicators")
vwapRollingLength = input.int(20, "Rolling VWAP Length", minval=10, maxval=100, group="📈 Indicators")
// Volume
volumeLength = input.int(20, "Volume MA Length", minval=10, maxval=50, group="📊 Volume")
volumeMultiplier = input.float(1.5, "Volume Spike", minval=1.1, maxval=3.0, step=0.1, group="📊 Volume")
// CVD
useCVD = input.bool(true, "Use CVD Filter", group="📊 Volume")
cvdLength = input.int(10, "CVD Smoothing", minval=5, maxval=30, group="📊 Volume")
// RSI
useRSI = input.bool(true, "Use RSI Filter", group="🎯 Filters")
rsiLength = input.int(14, "RSI Length", minval=7, maxval=30, group="🎯 Filters")
rsiOverbought = input.int(70, "RSI Overbought", minval=60, maxval=85, group="🎯 Filters")
rsiOversold = input.int(30, "RSI Oversold", minval=15, maxval=40, group="🎯 Filters")
// Price Action
candleBodyPercent = input.float(0.6, "Min Body %", minval=0.4, maxval=0.9, step=0.05, group="🎯 Filters")
minCandlePoints = input.float(20.0, "Min Candle Size", minval=10.0, maxval=100.0, step=5.0, group="🎯 Filters")
// Stop Loss
stopLossType = input.string("ATR", "Stop Loss Type", options=["Fixed", "ATR", "Swing"], group="🛡️ Exits")
atrLength = input.int(14, "ATR Length", minval=7, maxval=30, group="🛡️ Exits")
atrMultiplier = input.float(1.5, "ATR Multiplier", minval=0.5, maxval=3.0, step=0.1, group="🛡️ Exits")
fixedStopLoss = input.float(50.0, "Fixed SL (points)", minval=20.0, maxval=200.0, step=10.0, group="🛡️ Exits")
swingLookback = input.int(10, "Swing Lookback", minval=5, maxval=30, group="🛡️ Exits")
// Targets
rrTarget1 = input.float(1.5, "Target 1 R:R", minval=0.5, maxval=3.0, step=0.1, group="🛡️ Exits")
rrTarget2 = input.float(2.5, "Target 2 R:R", minval=1.0, maxval=5.0, step=0.5, group="🛡️ Exits")
partialExitPercent = input.int(50, "Partial Exit %", minval=25, maxval=75, step=5, group="🛡️ Exits")
// Trailing
useTrailing = input.bool(true, "Trailing Stop", group="🛡️ Exits")
trailActivationRR = input.float(1.2, "Activate at R:R", minval=0.5, maxval=2.0, step=0.1, group="🛡️ Exits")
trailStopRR = input.float(0.8, "Trail Stop R:R", minval=0.3, maxval=1.5, step=0.1, group="🛡️ Exits")
// Risk Management
maxTradesPerDay = input.int(5, "Max Trades/Day", minval=1, maxval=20, group="🚨 Risk")
maxConsecutiveLosses = input.int(2, "Stop After Losses", minval=1, maxval=5, group="🚨 Risk")
dailyLossLimit = input.float(2.5, "Daily Loss %", minval=1.0, maxval=10.0, step=0.5, group="🚨 Risk")
dailyProfitTarget = input.float(5.0, "Daily Target %", minval=2.0, maxval=20.0, step=0.5, group="🚨 Risk")
// ═══════════════════════════════════════════════════════════
// 📊 INDICATORS
// ═══════════════════════════════════════════════════════════
// Kernel Regression
kernel = ta.linreg(close, kernelLength, 0)
kernelSlope = kernel - kernel[1]
// VWAP
vwapValue = vwapSource == "Session" ? ta.vwap(close) : ta.sma(hlc3, vwapRollingLength)
vwapSlope = vwapValue - vwapValue[1]
// Volume
volumeMA = ta.sma(volume, volumeLength)
highVolume = volume > volumeMA * volumeMultiplier
volumeIncreasing = volume > volume[1] and volume[1] > volume[2]
// CVD
buyVolume = close > open ? volume : 0
sellVolume = close < open ? volume : 0
volumeDelta = buyVolume - sellVolume
cvd = ta.cum(volumeDelta)
cvdMA = ta.sma(cvd, cvdLength)
// RSI
rsi = ta.rsi(close, rsiLength)
// ATR
atr = ta.atr(atrLength)
// Price Action
candleRange = high - low
candleBody = math.abs(close - open)
bodyPercent = candleRange > 0 ? candleBody / candleRange : 0
// Swing High/Low
swingHigh = ta.highest(high, swingLookback)
swingLow = ta.lowest(low, swingLookback)
// ═══════════════════════════════════════════════════════════
// ⏰ TIME MANAGEMENT
// ═══════════════════════════════════════════════════════════
currentMinutes = hour * 60 + minute
startMinutes = startHour * 60 + startMinute
endMinutes = endHour * 60 + endMinute
tradingTime = currentMinutes >= startMinutes and currentMinutes <= endMinutes
var int barsToday = 0
newDay = ta.change(dayofweek)
if newDay
barsToday := 0
if tradingTime
barsToday += 1
skipInitialBars = barsToday <= avoidFirstCandles
forceExitTime = currentMinutes >= (endMinutes - 5)
// ═══════════════════════════════════════════════════════════
// 💼 POSITION TRACKING
// ═══════════════════════════════════════════════════════════
var int todayTrades = 0
var int consecutiveLosses = 0
var float todayPnL = 0.0
var float entryPrice = na
var int entryBar = 0
var float stopLoss = na
var float target1 = na
var float target2 = na
var float trailStop = na
var bool target1Hit = false
var bool trailActive = false
// Daily Reset
if newDay
todayTrades := 0
consecutiveLosses := 0
todayPnL := 0.0
// Track P&L
if strategy.closedtrades > 0 and strategy.closedtrades != strategy.closedtrades[1]
lastPnL = strategy.closedtrades.profit(strategy.closedtrades - 1)
todayPnL += lastPnL
if lastPnL < 0
consecutiveLosses += 1
else
consecutiveLosses := 0
// Risk Limits
lossLimit = strategy.initial_capital * (dailyLossLimit / 100)
profitTarget = strategy.initial_capital * (dailyProfitTarget / 100)
hitDailyTarget = todayPnL >= profitTarget
hitLossLimit = math.abs(todayPnL) >= lossLimit
canTrade = todayTrades < maxTradesPerDay and
consecutiveLosses < maxConsecutiveLosses and
not hitDailyTarget and
not hitLossLimit and
tradingTime and
not skipInitialBars and
strategy.position_size == 0
// ═══════════════════════════════════════════════════════════
// 🎯 LONG ENTRY CONDITIONS
// ═══════════════════════════════════════════════════════════
// Bullish Trend
longTrend = kernelSlope > 0 and close > kernel
longVWAP = close > vwapValue and vwapSlope > 0
longCVD = useCVD ? cvd > cvdMA and ta.rising(cvd, 2) : true
longRSI = useRSI ? rsi > rsiOversold and rsi < rsiOverbought : true
longVolume = highVolume or volumeIncreasing
longCandle = close > open and bodyPercent >= candleBodyPercent and
candleRange >= minCandlePoints and close >= (high - (candleRange * 0.25))
longSignal = longTrend and longVWAP and longCVD and longRSI and longVolume and longCandle and canTrade and
(tradingDirection == "Long Only" or tradingDirection == "Both")
// ═══════════════════════════════════════════════════════════
// 🎯 SHORT ENTRY CONDITIONS
// ═══════════════════════════════════════════════════════════
// Bearish Trend
shortTrend = kernelSlope < 0 and close < kernel
shortVWAP = close < vwapValue and vwapSlope < 0
shortCVD = useCVD ? cvd < cvdMA and ta.falling(cvd, 2) : true
shortRSI = useRSI ? rsi < rsiOverbought and rsi > rsiOversold : true
shortVolume = highVolume or volumeIncreasing
shortCandle = close < open and bodyPercent >= candleBodyPercent and
candleRange >= minCandlePoints and close <= (low + (candleRange * 0.25))
shortSignal = shortTrend and shortVWAP and shortCVD and shortRSI and shortVolume and shortCandle and canTrade and
(tradingDirection == "Short Only" or tradingDirection == "Both")
// ═══════════════════════════════════════════════════════════
// 💰 POSITION SIZING
// ═══════════════════════════════════════════════════════════
calcPositionSize(stopDistance) =>
riskAmount = strategy.initial_capital * (riskPercent / 100)
contracts = math.floor(riskAmount / stopDistance)
math.min(contracts, maxContracts)
// ═══════════════════════════════════════════════════════════
// 📥 LONG ENTRY
// ═══════════════════════════════════════════════════════════
if longSignal
entryPrice := close
entryBar := bar_index
// Calculate Stop Loss
if stopLossType == "ATR"
stopLoss := close - (atr * atrMultiplier)
else if stopLossType == "Swing"
stopLoss := math.min(swingLow, close - (atr * atrMultiplier))
else
stopLoss := close - fixedStopLoss
risk = entryPrice - stopLoss
target1 := entryPrice + (risk * rrTarget1)
target2 := entryPrice + (risk * rrTarget2)
qty = calcPositionSize(risk)
trailStop := stopLoss
target1Hit := false
trailActive := false
todayTrades += 1
strategy.entry("LONG", strategy.long, qty=qty, comment="Long-" + str.tostring(todayTrades))
// ═══════════════════════════════════════════════════════════
// 📥 SHORT ENTRY
// ═══════════════════════════════════════════════════════════
if shortSignal
entryPrice := close
entryBar := bar_index
// Calculate Stop Loss
if stopLossType == "ATR"
stopLoss := close + (atr * atrMultiplier)
else if stopLossType == "Swing"
stopLoss := math.max(swingHigh, close + (atr * atrMultiplier))
else
stopLoss := close + fixedStopLoss
risk = stopLoss - entryPrice
target1 := entryPrice - (risk * rrTarget1)
target2 := entryPrice - (risk * rrTarget2)
qty = calcPositionSize(risk)
trailStop := stopLoss
target1Hit := false
trailActive := false
todayTrades += 1
strategy.entry("SHORT", strategy.short, qty=qty, comment="Short-" + str.tostring(todayTrades))
// ═══════════════════════════════════════════════════════════
// 🏃 TRAILING STOP (LONG)
// ═══════════════════════════════════════════════════════════
if strategy.position_size > 0 and useTrailing
unrealizedProfit = close - entryPrice
risk = entryPrice - stopLoss
if unrealizedProfit >= (risk * trailActivationRR) and not trailActive
trailActive := true
trailStop := close - (risk * trailStopRR)
if trailActive
newTrailStop = close - (risk * trailStopRR)
if newTrailStop > trailStop
trailStop := newTrailStop
// ═══════════════════════════════════════════════════════════
// 🏃 TRAILING STOP (SHORT)
// ═══════════════════════════════════════════════════════════
if strategy.position_size < 0 and useTrailing
unrealizedProfit = entryPrice - close
risk = stopLoss - entryPrice
if unrealizedProfit >= (risk * trailActivationRR) and not trailActive
trailActive := true
trailStop := close + (risk * trailStopRR)
if trailActive
newTrailStop = close + (risk * trailStopRR)
if newTrailStop < trailStop
trailStop := newTrailStop
// ═══════════════════════════════════════════════════════════
// 📤 LONG EXIT
// ═══════════════════════════════════════════════════════════
if strategy.position_size > 0
activeSL = trailActive and useTrailing ? trailStop : stopLoss
// Stop Loss
if low <= activeSL
strategy.close("LONG", comment="Long-SL")
// Target 1
else if high >= target1 and not target1Hit
exitQty = math.floor(strategy.position_size * (partialExitPercent / 100))
strategy.close("LONG", qty=exitQty, comment="Long-T1")
target1Hit := true
stopLoss := entryPrice
// Target 2
else if high >= target2
strategy.close("LONG", comment="Long-T2")
// Force Exit
else if forceExitTime
strategy.close("LONG", comment="Long-EOD")
// ═══════════════════════════════════════════════════════════
// 📤 SHORT EXIT
// ═══════════════════════════════════════════════════════════
if strategy.position_size < 0
activeSL = trailActive and useTrailing ? trailStop : stopLoss
// Stop Loss
if high >= activeSL
strategy.close("SHORT", comment="Short-SL")
// Target 1
else if low <= target1 and not target1Hit
exitQty = math.floor(math.abs(strategy.position_size) * (partialExitPercent / 100))
strategy.close("SHORT", qty=exitQty, comment="Short-T1")
target1Hit := true
stopLoss := entryPrice
// Target 2
else if low <= target2
strategy.close("SHORT", comment="Short-T2")
// Force Exit
else if forceExitTime
strategy.close("SHORT", comment="Short-EOD")
// ═══════════════════════════════════════════════════════════
// ⚠️ REVERSAL EXIT
// ═══════════════════════════════════════════════════════════
longReversal = strategy.position_size > 0 and (close < kernel and kernelSlope < 0 or close < vwapValue)
shortReversal = strategy.position_size < 0 and (close > kernel and kernelSlope > 0 or close > vwapValue)
if longReversal and target1Hit
strategy.close("LONG", comment="Long-Rev")
if shortReversal and target1Hit
strategy.close("SHORT", comment="Short-Rev")
// ═══════════════════════════════════════════════════════════
// 🎨 VISUALIZATION
// ═══════════════════════════════════════════════════════════
// Indicators
plot(kernel, "Kernel", color=color.new(color.purple, 0), linewidth=2)
plot(vwapValue, "VWAP", color=color.new(color.orange, 0), linewidth=2)
kernelUpper = kernel + atr
kernelLower = kernel - atr
plot(kernelUpper, "K Upper", color=color.new(color.purple, 70), linewidth=1, style=plot.style_circles)
plot(kernelLower, "K Lower", color=color.new(color.purple, 70), linewidth=1, style=plot.style_circles)
// Signals
plotshape(longSignal, "LONG", shape.triangleup, location.belowbar,
color=color.new(color.lime, 0), size=size.normal, text="LONG")
plotshape(shortSignal, "SHORT", shape.triangledown, location.abovebar,
color=color.new(color.red, 0), size=size.normal, text="SHORT")
// Position Levels
posColor = strategy.position_size > 0 ? color.blue : strategy.position_size < 0 ? color.orange : na
plot(strategy.position_size != 0 ? entryPrice : na, "Entry",
color=color.new(posColor, 0), style=plot.style_linebr, linewidth=2)
slColor = strategy.position_size > 0 ? color.red : color.fuchsia
plot(strategy.position_size != 0 ? stopLoss : na, "SL",
color=color.new(slColor, 0), style=plot.style_linebr, linewidth=2)
t1Color = strategy.position_size > 0 ? color.green : color.aqua
plot(strategy.position_size != 0 ? target1 : na, "T1",
color=color.new(t1Color, 0), style=plot.style_linebr, linewidth=1)
plot(strategy.position_size != 0 ? target2 : na, "T2",
color=color.new(t1Color, 0), style=plot.style_linebr, linewidth=2)
plot(strategy.position_size != 0 and trailActive ? trailStop : na, "Trail",
color=color.new(color.yellow, 0), style=plot.style_linebr, linewidth=2)
// Volume
barcolor(highVolume ? color.new(color.blue, 70) : na)
// Background
bgcolor(tradingTime ? color.new(color.green, 98) : color.new(color.gray, 95))
bgcolor(strategy.position_size > 0 ? color.new(color.blue, 97) :
strategy.position_size < 0 ? color.new(color.orange, 97) : na)
bgcolor(hitDailyTarget ? color.new(color.green, 92) : hitLossLimit ? color.new(color.red, 92) : na)
// ═══════════════════════════════════════════════════════════
// 📊 STATS TABLE
// ═══════════════════════════════════════════════════════════
var table stats = table.new(position.top_right, 2, 11, border_width=1)
if barstate.islast
// Header
table.cell(stats, 0, 0, "📊 LONG & SHORT", bgcolor=color.blue, text_color=color.white, text_size=size.small)
table.cell(stats, 1, 0, "STRATEGY", bgcolor=color.blue, text_color=color.white, text_size=size.small)
// Trades
table.cell(stats, 0, 1, "Trades", text_size=size.small)
table.cell(stats, 1, 1, str.tostring(todayTrades) + "/" + str.tostring(maxTradesPerDay),
bgcolor=todayTrades >= maxTradesPerDay ? color.red : color.green, text_color=color.white, text_size=size.small)
// Losses
table.cell(stats, 0, 2, "Losses", text_size=size.small)
table.cell(stats, 1, 2, str.tostring(consecutiveLosses),
bgcolor=consecutiveLosses >= maxConsecutiveLosses ? color.red : color.green,
text_color=color.white, text_size=size.small)
// P&L
pnlPct = (todayPnL / strategy.initial_capital) * 100
table.cell(stats, 0, 3, "P&L", text_size=size.small)
table.cell(stats, 1, 3, str.tostring(todayPnL, "#,###") + "\n" + str.tostring(pnlPct, "#.##") + "%",
bgcolor=todayPnL > 0 ? color.green : todayPnL < 0 ? color.red : color.gray,
text_color=color.white, text_size=size.small)
// Position
table.cell(stats, 0, 4, "Position", text_size=size.small)
posText = strategy.position_size > 0 ? "LONG\n" + str.tostring(strategy.position_size) :
strategy.position_size < 0 ? "SHORT\n" + str.tostring(math.abs(strategy.position_size)) : "FLAT"
posBg = strategy.position_size > 0 ? color.blue : strategy.position_size < 0 ? color.orange : color.gray
table.cell(stats, 1, 4, posText, bgcolor=posBg, text_color=color.white, text_size=size.small)
if strategy.position_size != 0
// Entry
table.cell(stats, 0, 5, "Entry", text_size=size.small)
table.cell(stats, 1, 5, str.tostring(entryPrice, "#.##"), text_size=size.small)
// Live P&L
livePnL = strategy.position_size > 0 ? (close - entryPrice) * strategy.position_size :
(entryPrice - close) * math.abs(strategy.position_size)
livePct = strategy.position_size > 0 ? ((close - entryPrice) / entryPrice) * 100 :
((entryPrice - close) / entryPrice) * 100
table.cell(stats, 0, 6, "Live P&L", text_size=size.small)
table.cell(stats, 1, 6, str.tostring(livePnL, "#,###") + "\n" + str.tostring(livePct, "#.##") + "%",
bgcolor=livePnL > 0 ? color.green : color.red, text_color=color.white, text_size=size.small)
// Bars
bars = bar_index - entryBar
table.cell(stats, 0, 7, "Bars", text_size=size.small)
table.cell(stats, 1, 7, str.tostring(bars), text_size=size.small)
// Stop
table.cell(stats, 0, 8, "Stop", text_size=size.small)
table.cell(stats, 1, 8, str.tostring(trailActive ? trailStop : stopLoss, "#.##") +
(trailActive ? " 🟡" : ""), text_size=size.small)
// T1
table.cell(stats, 0, 9, "T1", text_size=size.small)
table.cell(stats, 1, 9, str.tostring(target1, "#.##") + (target1Hit ? " ✓" : ""), text_size=size.small)
// T2
table.cell(stats, 0, 10, "T2", text_size=size.small)
table.cell(stats, 1, 10, str.tostring(target2, "#.##"), text_size=size.small)
// ═══════════════════════════════════════════════════════════
// 🔔 ALERTS
// ═══════════════════════════════════════════════════════════
alertcondition(longSignal, "🟢 LONG SIGNAL", "LONG Entry Signal")
alertcondition(shortSignal, "🔴 SHORT SIGNAL", "SHORT Entry Signal")
alertcondition(longReversal or shortReversal, "⚠️ REVERSAL", "Reversal Detected")