50-day SMA trend with 10% stop: backtest results

Trade the 50-day moving average: buy when price closes above it, sell when it closes below, with a 10% stop loss. We ran it on real daily data for 4 stocks. It beat simply buying and holding on 1 of 4 stocks.

Beat buy & hold1 / 4
Best result+1012.9%
Closed trades262
Stocks tested4
Backtest it on your own stock →Get the TradingView indicator

Results by stock

StockPeriodStrategyBuy & holdBeat it?Worst dropTradesWin rateCaution
Apple (AAPL)2016 → 2025+350.6%+1038.8%no-33.6%7031.4%includes a position still open at the end
Amazon (AMZN)2016 → 2025+278.0%+613.2%no-50.5%8428.6%includes a position still open at the end; fell 51% at its worst
Robinhood (HOOD)2021 → 2025+321.4%+223.5%yes-43.6%3336.4%fell 44% at its worst
Tesla (TSLA)2016 → 2025+1012.9%+2877.2%no-61.9%7526.7%includes a position still open at the end; fell 62% at its worst

Best: Tesla on +1012.9%. One set of rules, fixed in advance, run on every stock: no tuning to make the numbers look better. A strategy with few trades or a big drop deserves less trust than its return suggests.

The exact rules

Buy Apple when the close crosses above the 50 day SMA. Sell when the close crosses below the 50 day SMA. Stop loss 10%.

Paste those words into Extractor and it runs the same test, shows every trade on the chart with entry, stop loss and take profit, and compares it with buy & hold. Change a number and run it again in seconds.

Run these rules now, free

Free TradingView indicator (Pine Script v5)

Copy this into TradingView's Pine Editor and click Add to chart. It marks the buy and sell signals and draws the levels.

//@version=5
// Indicator generated by Extractor from your rules.
// Built for AAPL on the daily (1D) chart.
//   Buy when:  close crosses above sma(50)
//   Sell when: close crosses below sma(50)
//   Stop loss: 10%
// Marks where your rules say buy and sell, and adds alerts you can turn on in TradingView.

indicator("50-day SMA trend with 10% stop signals", overlay=true)

sma50 = ta.sma(close, 50)
cross1 = ta.crossover(close, sma50)
cross2 = ta.crossunder(close, sma50)
entrySignal = cross1
exitSignal = cross2

// Track whether the rules are in a trade, so signals don't repeat while already long.
var bool inTrade = false
var float entryPrice = na
stopHit = inTrade and low <= entryPrice * (1 - 10.0 / 100)
targetHit = false
buy = not inTrade and entrySignal
sell = inTrade and (exitSignal or stopHit or targetHit)
if sell
    inTrade := false
    entryPrice := na
else if buy
    inTrade := true
    entryPrice := close

// Levels stay drawn through the bar where the trade closes.
wasInTrade = inTrade or sell
levelBase = sell ? entryPrice[1] : entryPrice
// Position levels from your inputs
float entryLine = wasInTrade ? levelBase : na
float tpLine = na
float slLine = entryLine * (1 - 10.0 / 100)
pEntry = plot(entryLine, "Entry", color.new(color.gray, 0), 1, plot.style_linebr)
pTp = plot(tpLine, "Take profit (not set)", color.new(color.green, 0), 2, plot.style_linebr)
pSl = plot(slLine, "Stop loss 10%", color.new(color.red, 0), 2, plot.style_linebr)
fill(pEntry, pTp, color.new(color.green, 85))
fill(pEntry, pSl, color.new(color.red, 85))
if (wasInTrade) and not (wasInTrade)[1]
    label.new(bar_index, high, "Entry " + str.tostring(entryLine, format.mintick) + "\nSL " + str.tostring(slLine, format.mintick) + " (-10%)", style=label.style_label_lower_left, color=color.new(color.gray, 20), textcolor=color.white, size=size.small)

plot(sma50, "SMA 50", color.orange)
plotshape(buy, "Buy", shape.labelup, location.belowbar, color.new(color.teal, 0), text="BUY", textcolor=color.white, size=size.small)
plotshape(sell, "Sell", shape.labeldown, location.abovebar, color.new(color.red, 0), text="SELL", textcolor=color.white, size=size.small)
alertcondition(buy, "Buy signal", "50-day SMA trend with 10% stop: buy signal on {{ticker}} at {{close}}")
alertcondition(sell, "Sell signal", "50-day SMA trend with 10% stop: sell signal on {{ticker}} at {{close}}")

Test your own version

Other strategies we tested