Code: Select all
//@version=5
strategy("ALMA Pro Scalper: Partial & Trail", overlay=true, initial_capital=10000,
default_qty_type=strategy.percent_of_equity, default_qty_value=2,
commission_type=strategy.commission.cash_per_order, commission_value=3, slippage=1,
max_labels_count=500, max_lines_count=500)
// ==========================================
// INPUT GROUPS & PARAMETERS
// ==========================================
var string G_ALMA = "ALMA Core Settings"
var string G_MACD = "MACD Momentum Filter"
var string G_FILTER = "Pro Filters (Session & Trend)"
var string G_RISK = "Risk, Partials & Trailing"
var string G_UI = "Visuals & HUD"
// ALMA Settings
almaLength = input.int(9, title="Window Size", group=G_ALMA)
almaOffset = input.float(0.85, title="Offset", step=0.05, group=G_ALMA)
almaSigma = input.int(6, title="Sigma", group=G_ALMA)
// MACD Settings
fastLength = input.int(12, title="Fast Length", group=G_MACD)
slowLength = input.int(26, title="Slow Length", group=G_MACD)
signalLength = input.int(9, title="Signal Length", group=G_MACD)
// Filters
useSession = input.bool(true, title="Enable Session Filter?", group=G_FILTER)
sessionTimes = input.session("0800-1700", title="Trading Session (Exchange Time)", group=G_FILTER)
useHtfEma = input.bool(true, title="Filter with 200 EMA?", group=G_FILTER)
// Risk & Management
atrLength = input.int(14, title="ATR Length", group=G_RISK)
slMultiplier = input.float(1.5, title="Initial SL ATR Multiplier", step=0.1, group=G_RISK)
partialRR = input.float(1.5, title="Partial Profit Target (in R)", step=0.1, group=G_RISK)
partialPct = input.float(50.0, title="Partial Close %", group=G_RISK)
moveToBE = input.bool(true, title="Move to Breakeven on Partial?", group=G_RISK)
trailBuffer = input.int(10, title="Trail Buffer behind ALMA (Ticks/Points)", group=G_RISK)
// Visuals
showHUD = input.bool(true, title="Show Dashboard Table?", group=G_UI)
colorCandles = input.bool(true, title="Color Candles by ALMA Trend?", group=G_UI)
// ==========================================
// INDICATOR CALCULATIONS
// ==========================================
almaLine = ta.alma(close, almaLength, almaOffset, almaSigma)
[macdLine, signalLine, histLine] = ta.macd(close, fastLength, slowLength, signalLength)
atr = ta.atr(atrLength)
ema200 = ta.ema(close, 200)
inSession = useSession ? not na(time(timeframe.period, sessionTimes)) : true
// ==========================================
// STATE VARIABLES FOR TRADE MANAGEMENT
// ==========================================
var float g_entry = na
var float g_sl = na
var float g_tp = na
var bool g_partial_done = false
// Reset state when flat
if strategy.position_size == 0
g_entry := na
g_sl := na
g_tp := na
g_partial_done := false
// Detect Partial Close (if position volume decreases but remains active)
if strategy.position_size > 0 and strategy.position_size[1] > 0 and strategy.position_size < strategy.position_size[1]
g_partial_done := true
if moveToBE
g_sl := math.max(g_sl, g_entry) // Shift SL to entry for Long
if strategy.position_size < 0 and strategy.position_size[1] < 0 and strategy.position_size > strategy.position_size[1]
g_partial_done := true
if moveToBE
g_sl := math.min(g_sl, g_entry) // Shift SL to entry for Short
// ==========================================
// ENTRY LOGIC
// ==========================================
longCross = ta.crossover(close, almaLine)
shortCross = ta.crossunder(close, almaLine)
longCond = longCross and (histLine > 0) and inSession and (useHtfEma ? close > ema200 : true)
shortCond = shortCross and (histLine < 0) and inSession and (useHtfEma ? close < ema200 : true)
if longCond and strategy.position_size == 0
g_entry := close
g_sl := close - (atr * slMultiplier)
risk = close - g_sl
g_tp := close + (risk * partialRR)
strategy.entry("Long", strategy.long)
if shortCond and strategy.position_size == 0
g_entry := close
g_sl := close + (atr * slMultiplier)
risk = g_sl - close
g_tp := close - (risk * partialRR)
strategy.entry("Short", strategy.short)
// ==========================================
// TRAILING SL LOGIC & EXIT EXECUTION
// ==========================================
if strategy.position_size > 0
// Trail SL behind ALMA
trail_level = almaLine - (trailBuffer * syminfo.mintick)
g_sl := math.max(g_sl, trail_level) // Never move stop downwards
// Execute Partials and Trails
if not g_partial_done
strategy.exit("TP1", "Long", qty_percent=partialPct, limit=g_tp, stop=g_sl)
strategy.exit("Trail", "Long", stop=g_sl)
if strategy.position_size < 0
// Trail SL behind ALMA
trail_level = almaLine + (trailBuffer * syminfo.mintick)
g_sl := math.min(g_sl, trail_level) // Never move stop upwards
// Execute Partials and Trails
if not g_partial_done
strategy.exit("TP1", "Short", qty_percent=partialPct, limit=g_tp, stop=g_sl)
strategy.exit("Trail", "Short", stop=g_sl)
// ==========================================
// VISUAL RENDERING
// ==========================================
almaColor = close > almaLine ? color.new(#00E676, 0) : color.new(#FF5252, 0)
plot(almaLine, color=almaColor, linewidth=2, title="ALMA")
plot(useHtfEma ? ema200 : na, color=color.new(color.white, 50), linewidth=1, title="200 EMA")
// Plot the dynamic Trailing Stop Loss line when in a trade
plot(strategy.position_size != 0 ? g_sl : na, color=color.new(color.fuchsia, 0), style=plot.style_stepline, linewidth=1, title="Active Stop Loss")
barcolor(colorCandles ? almaColor : na)
bgcolor(useSession and inSession ? color.new(color.blue, 95) : na, title="Trading Session")
// ==========================================
// DASHBOARD HUD
// ==========================================
if showHUD
var table hud = table.new(position.top_right, 2, 5, border_width = 1)
if barstate.islast
table.cell(hud, 0, 0, "Metric", text_color=color.white, bgcolor=color.gray)
table.cell(hud, 1, 0, "Value", text_color=color.white, bgcolor=color.gray)
table.cell(hud, 0, 1, "ALMA Trend", text_color=color.white, bgcolor=color.black)
table.cell(hud, 1, 1, close > almaLine ? "BULLISH" : "BEARISH", text_color=close > almaLine ? color.green : color.red, bgcolor=color.black)
table.cell(hud, 0, 2, "Session Status", text_color=color.white, bgcolor=color.black)
table.cell(hud, 1, 2, inSession ? "ACTIVE" : "CLOSED", text_color=inSession ? color.green : color.red, bgcolor=color.black)
table.cell(hud, 0, 3, "Volatility (ATR)", text_color=color.white, bgcolor=color.black)
table.cell(hud, 1, 3, str.tostring(atr, "#.#####"), text_color=color.yellow, bgcolor=color.black)
table.cell(hud, 0, 4, "Trade State", text_color=color.white, bgcolor=color.black)
tradeStateText = strategy.position_size == 0 ? "FLAT" : (g_partial_done ? "TRAILING (BE)" : "INITIAL RISK")
tradeStateColor = strategy.position_size == 0 ? color.gray : (g_partial_done ? color.fuchsia : color.orange)
table.cell(hud, 1, 4, tradeStateText, text_color=tradeStateColor, bgcolor=color.black)