Code: Select all
//@version=5
strategy("Elite Scalper: MTF & Circuit Breakers", overlay=true, initial_capital=10000, margin_long=100, margin_short=100, calc_on_every_tick=true, commission_type=strategy.commission.cash_per_contract, commission_value=3.0, slippage=2)
// =========================================================================
// 1. RISK & ACCOUNT MANAGEMENT
// =========================================================================
riskPerTrade = input.float(1.0, title="Risk Per Trade (%)", group="Risk Management")
maxDailyLossPct = input.float(3.0, title="Max Daily Loss (%)", group="Risk Management", tooltip="Halts trading for the day if drawdown hits this level.")
maxDailyProfitPct = input.float(5.0, title="Max Daily Profit (%)", group="Risk Management", tooltip="Halts trading for the day to secure profits.")
tpPips = input.float(8.0, title="Take Profit (Pips)", group="Trade Execution", minval=1.0, step=0.5)
slPips = input.float(5.0, title="Stop Loss (Pips)", group="Trade Execution", minval=1.0, step=0.5)
ticksPerPip = input.int(10, title="Ticks per Pip", group="Trade Execution")
// =========================================================================
// 2. TIMING & SESSION
// =========================================================================
sessionTime = input.session("0800-1200", title="Trading Session (EST)", group="Session Settings")
sessionZone = input.string("America/New_York", title="Timezone", group="Session Settings")
// =========================================================================
// 3. ELITE FILTERS: MTF TREND & VOLATILITY
// =========================================================================
mtfTimeframe = input.timeframe("15", title="Macro Trend Timeframe", group="Institutional Filters")
fastEmaLen = input.int(9, title="Fast EMA (Micro)", group="Institutional Filters")
slowEmaLen = input.int(21, title="Slow EMA (Micro)", group="Institutional Filters")
minAtrPips = input.float(2.0, title="Minimum ATR (Pips)", group="Institutional Filters")
// =========================================================================
// CALCULATIONS & LOGIC
// =========================================================================
pipMultiplier = syminfo.mintick * ticksPerPip
tpTicks = tpPips * ticksPerPip
slTicks = slPips * ticksPerPip
// Session Check
inSession = time(timeframe.period, sessionTime, sessionZone)
bgcolor(inSession ? color.new(color.blue, 94) : na, title="Session Active")
// Micro Indicators (1-Minute)
fastEma = ta.ema(close, fastEmaLen)
slowEma = ta.ema(close, slowEmaLen)
atr = ta.atr(14) / pipMultiplier
// MACRO Indicator (MTF 15-Minute)
// We use request.security to pull higher timeframe data without repainting
macroTrendEma = request.security(syminfo.tickerid, mtfTimeframe, ta.ema(close, 200), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
plot(macroTrendEma, color=color.new(color.orange, 10), linewidth=3, title="Macro 200 EMA (15m)")
// =========================================================================
// CIRCUIT BREAKERS (DAILY PnL TRACKING)
// =========================================================================
var float startOfDayEquity = strategy.initial_capital
var bool circuitBreakerHit = false
// Reset daily equity at the start of a new day
if ta.change(time("D"))
startOfDayEquity := strategy.equity
circuitBreakerHit := false // Reset breaker
// Calculate current day's performance
currentDailyPnL_Pct = ((strategy.equity - startOfDayEquity) / startOfDayEquity) * 100
// Check if limits are breached
if (currentDailyPnL_Pct <= -maxDailyLossPct) or (currentDailyPnL_Pct >= maxDailyProfitPct)
circuitBreakerHit := true
// =========================================================================
// PROFESSIONAL POSITION SIZING
// =========================================================================
equityRiskAmount = (strategy.equity * (riskPerTrade / 100))
slPriceDistance = slPips * pipMultiplier
// Prevents division by zero error in edge cases
positionSize = slPriceDistance > 0 ? (equityRiskAmount / (slPriceDistance * syminfo.pointvalue)) : 0
// =========================================================================
// ENTRY & EXIT EXECUTION
// =========================================================================
validVolatility = atr >= minAtrPips
longTrend = close > macroTrendEma
shortTrend = close < macroTrendEma
longCondition = ta.crossover(fastEma, slowEma) and inSession and longTrend and validVolatility
shortCondition = ta.crossunder(fastEma, slowEma) and inSession and shortTrend and validVolatility
// Only trade if session is active AND circuit breakers are NOT hit
canTrade = inSession and not circuitBreakerHit
if (longCondition and strategy.position_size == 0 and canTrade)
strategy.entry("Long", strategy.long, qty=positionSize)
if (shortCondition and strategy.position_size == 0 and canTrade)
strategy.entry("Short", strategy.short, qty=positionSize)
strategy.exit("Exit Long", from_entry="Long", profit=tpTicks, loss=slTicks)
strategy.exit("Exit Short", from_entry="Short", profit=tpTicks, loss=slTicks)
// Close all positions when session ends or circuit breaker is hit mid-trade
if (not inSession and inSession[1]) or (circuitBreakerHit and not circuitBreakerHit[1])
strategy.close_all(comment="Forced Close (Session/Breaker)")
// =========================================================================
// QUANT ANALYTICS DASHBOARD (HUD)
// =========================================================================
var table hud = table.new(position.bottom_right, 2, 6, border_width=1, border_color=color.rgb(36, 36, 36), frame_color=color.black, frame_width=2, bgcolor=color.new(color.black, 10))
if barstate.islast
// Calculate Win Rate safely
winRate = strategy.closedtrades > 0 ? (strategy.wintrades / strategy.closedtrades) * 100 : 0
// Header
table.cell(hud, 0, 0, "ELITE SCALP TERMINAL", text_color=color.white, text_halign=text.align_left, bgcolor=color.new(color.blue, 30))
table.cell(hud, 1, 0, syminfo.ticker, text_color=color.white, text_halign=text.align_right, bgcolor=color.new(color.blue, 30))
// Breaker Status
table.cell(hud, 0, 1, "Circuit Breaker:", text_color=color.gray, text_halign=text.align_left)
table.cell(hud, 1, 1, circuitBreakerHit ? "🔴 HALTED" : "🟢 CLEAR", text_color=circuitBreakerHit ? color.red : color.lime, text_halign=text.align_right)
// Daily PnL
pnlColor = currentDailyPnL_Pct > 0 ? color.lime : currentDailyPnL_Pct < 0 ? color.red : color.gray
table.cell(hud, 0, 2, "Today's PnL:", text_color=color.gray, text_halign=text.align_left)
table.cell(hud, 1, 2, str.tostring(currentDailyPnL_Pct, "#.##") + "%", text_color=pnlColor, text_halign=text.align_right)
// Win Rate
table.cell(hud, 0, 3, "Strategy Win Rate:", text_color=color.gray, text_halign=text.align_left)
table.cell(hud, 1, 3, str.tostring(winRate, "#.#") + "%", text_color=color.white, text_halign=text.align_right)
// Volatility
table.cell(hud, 0, 4, "Volatility (ATR):", text_color=color.gray, text_halign=text.align_left)
table.cell(hud, 1, 4, str.tostring(atr, "#.##") + " pips", text_color=validVolatility ? color.lime : color.orange, text_halign=text.align_right)
// MTF Trend
trendText = longTrend ? "BULLISH (15m)" : shortTrend ? "BEARISH (15m)" : "FLAT"
trendCol = longTrend ? color.lime : shortTrend ? color.red : color.gray
table.cell(hud, 0, 5, "Macro Trend:", text_color=color.gray, text_halign=text.align_left)
table.cell(hud, 1, 5, trendText, text_color=trendCol, text_halign=text.align_right)