A classic trend-following strategy that uses two moving averages of different speeds to identify trend changes and potential entry points.
The Lagging Advantage
While crossovers are known for their lag, the 50/100 EMA pairing on the 4h timeframe is a favorite among intermediate traders for its ability to filter out "noise" while capturing the meat of a macro trend. This implementation has been completely reconstructed to ensure precision in signal detection and risk calculation.
TrendType
4h ChartTimeframe
BeginnerComplexity
TrendingBest Market
Signal Logic
Golden Cross (Buy)
Triggered when the 50 EMA (Fast) crosses above the 100 EMA (Slow).
Death Cross (Sell)
Triggered when the 50 EMA (Fast) crosses below the 100 EMA (Slow).
Implementation
//@version=6strategy("MA Crossover Strategy", shorttitle="MA Cross", overlay=true, initial_capital=1000000, default_qty_type=strategy.percent_of_equity, default_qty_value=100)
// ==========================================// 🔹 INPUTS// ==========================================// Moving Average Settings
grp_ma = "Moving Average Settings"
fastLength = input.int(50, "Fast MA Length", minval=1, group=grp_ma)
slowLength = input.int(100, "Slow MA Length", minval=1, group=grp_ma)
src = input.source(close, "Source", group=grp_ma)
maType = input.string("EMA", "MA Type", options=["SMA", "EMA"], group=grp_ma)
// Risk Management Settings
grp_risk = "Risk Management"
useTP = input.bool(true, "Use Take Profit?", group=grp_risk)
tpPerc = input.float(33.0, "Take Profit (%)", step=0.1, group=grp_risk) / 100
useSL = input.bool(true, "Use Stop Loss?", group=grp_risk)
slPerc = input.float(5, "Stop Loss (%)", step=0.1, group=grp_risk) / 100// Backtest Date Range
grp_time = "Backtest Window"
startDate = input.time(timestamp("2000-01-01 00:00"), "Start Date", group=grp_time)
endDate = input.time(timestamp("2030-01-01 00:00"), "End Date", group=grp_time)
// --- Calculations ---// Function to get MA based on user selectiongetMA(source, length, type) =>
type == "SMA" ? ta.sma(source, length) : ta.ema(source, length)
fastMA = getMA(src, fastLength, maType)
slowMA = getMA(src, slowLength, maType)
// Check if we are in the backtest time window
inDateRange = time >= startDate and time <= endDate
// --- Strategy Logic ---// Long Condition: Fast MA crosses OVER Slow MA
longCondition = ta.crossover(fastMA, slowMA) and inDateRange
// Short Condition: Fast MA crosses UNDER Slow MA
shortCondition = ta.crossunder(fastMA, slowMA) and inDateRange
// --- Execution ---// Entry Logicif longCondition
strategy.entry("Long", strategy.long)
if shortCondition
strategy.entry("Short", strategy.short)
// Exit Logic (Stop Loss / Take Profit)// We calculate the TP/SL price based on the Entry Price of the positionif strategy.position_size > 0
longStop = strategy.position_avg_price * (1 - slPerc)
longTP = strategy.position_avg_price * (1 + tpPerc)
strategy.exit("Exit Long", "Long", stop=useSL ? longStop : na, limit=useTP ? longTP : na)
if strategy.position_size < 0
shortStop = strategy.position_avg_price * (1 + slPerc)
shortTP = strategy.position_avg_price * (1 - tpPerc)
strategy.exit("Exit Short", "Short", stop=useSL ? shortStop : na, limit=useTP ? shortTP : na)
// --- Visuals ---plot(fastMA, color=color.rgb(0, 255, 0), title="Fast MA", linewidth=2)
plot(slowMA, color=color.rgb(255, 0, 0), title="Slow MA", linewidth=2)
// Visual signals on the chartplotshape(longCondition, title="Long Signal", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.small)
plotshape(shortCondition, title="Short Signal", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small)