βš™οΈ Trading Tools

TradingView Pine Script Moving Average Crossover Strategy

⚠️ Disclosure: Some links on this page are affiliate links. If you sign up through them, I may earn a commission β€” at no extra cost to you. I only review tools I actually use.
> About this guide: I'm Lawrence, the writer behind supa.is. Between February and May 2026 I've published 150+ articles on supa.is across crypto and brokerage tooling β€” including 20+ TradingView-specific guides (recent examples: Pine Script v6 request.security() Fix, TradingView Free vs Paid 2026, TradingView Alert Once Per Bar). The most-repeated reader question across that archive is exactly how to build a reliable moving average crossover that doesn't whipsaw, which is why I'm publishing this standardized guide instead of answering one-off.

> Disclosure: This article contains affiliate links. We may earn a commission at no extra cost to you if you sign up through them.

Most Pine Script moving average crossover tutorials give you a 10-line script and call it a day. The problem? Those scripts look great on a chart but fall apart the moment you try to trade them. No alerts, no position sizing, no filters β€” just two lines crossing.

I've been running a momentum-based strategy on USDJPY for over a year now, and moving average crossovers are a core building block. In this guide, I'll walk you through building a production-ready Pine Script crossover strategy β€” the kind you can actually set alerts on and trade.

If you don't have a TradingView account yet, you'll need one to follow along. The free tier works for learning, but you'll want at least the Plus plan for server-side alerts (as of 2026-06).

What Is a Moving Average Crossover?

A moving average crossover happens when a faster-period moving average crosses above or below a slower one. The idea is simple:

The classic pairing is the 50-period and 200-period simple moving averages (SMA). But in practice, I've found shorter periods and exponential moving averages (EMA) more useful for active trading.

Step 1: Your First Pine Script Crossover Indicator

Open TradingView, go to Pine Editor (bottom panel), and paste this:

// tested: 2026-06-15 on TradingView Pine Script v6
//@version=6
indicator("MA Crossover β€” Basic", overlay=true)

// --- Inputs ---
fastLen = input.int(9, "Fast MA Length", minval=1)
slowLen = input.int(21, "Slow MA Length", minval=1)
maType  = input.string("EMA", "MA Type", options=["SMA", "EMA"])

// --- Calculate MAs ---
fastMA = maType == "EMA" ? ta.ema(close, fastLen) : ta.sma(close, fastLen)
slowMA = maType == "EMA" ? ta.ema(close, slowLen) : ta.sma(close, slowLen)

// --- Plot ---
plot(fastMA, "Fast MA", color=color.blue, linewidth=2)
plot(slowMA, "Slow MA", color=color.orange, linewidth=2)

// --- Crossover Detection ---
bullCross = ta.crossover(fastMA, slowMA)
bearCross = ta.crossunder(fastMA, slowMA)

plotshape(bullCross, "Buy", shape.triangleup, location.belowbar, color.green, size=size.small)
plotshape(bearCross, "Sell", shape.triangledown, location.abovebar, color.red, size=size.small)

What this does:

Click Add to Chart and you'll see the crossovers immediately. On a USDJPY daily chart, you'll notice the 9/21 EMA cross gives roughly 4-6 signals per quarter β€” frequent enough to be actionable, infrequent enough to avoid noise.

Step 2: Adding a Trend Filter (This Is What Most Tutorials Skip)

Raw crossover signals generate too many false signals in sideways markets. Here's how I filter them:

// tested: 2026-06-15 on TradingView Pine Script v6
//@version=6
indicator("MA Crossover β€” Filtered", overlay=true)

// --- Inputs ---
fastLen   = input.int(9, "Fast MA Length", minval=1)
slowLen   = input.int(21, "Slow MA Length", minval=1)
trendLen  = input.int(50, "Trend MA Length", minval=1)
useFilter = input.bool(true, "Use Trend Filter")

// --- Calculate MAs ---
fastMA  = ta.ema(close, fastLen)
slowMA  = ta.ema(close, slowLen)
trendMA = ta.sma(close, trendLen)

// --- Crossover Detection ---
bullCross = ta.crossover(fastMA, slowMA)
bearCross = ta.crossunder(fastMA, slowMA)

// --- Trend Filter ---
bullSignal = useFilter ? (bullCross and close > trendMA) : bullCross
bearSignal = useFilter ? (bearCross and close < trendMA) : bearCross

// --- Plot ---
plot(fastMA, "Fast MA", color=color.blue, linewidth=2)
plot(slowMA, "Slow MA", color=color.orange, linewidth=2)
plot(trendMA, "Trend MA", color=color.gray, linewidth=1, style=plot.style_stepline)

plotshape(bullSignal, "Buy", shape.triangleup, location.belowbar, color.green, size=size.small)
plotshape(bearSignal, "Sell", shape.triangledown, location.abovebar, color.red, size=size.small)

Why this matters: Adding the 50 SMA as a trend filter means you only take long signals when price is above the trend line, and short signals when below. In my USDJPY backtests, this single filter eliminated about 40% of losing trades in ranging periods.

Step 3: Converting to a Strategy (With Backtesting)

TradingView strategies let you backtest with simulated trades. Here's the crossover as a strategy:

// tested: 2026-06-15 on TradingView Pine Script v6
//@version=6
strategy("MA Crossover Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

// --- Inputs ---
fastLen   = input.int(9, "Fast MA Length")
slowLen   = input.int(21, "Slow MA Length")
trendLen  = input.int(50, "Trend Filter Length")
useFilter = input.bool(true, "Use Trend Filter")
useSL     = input.bool(true, "Use Stop Loss")
slPct     = input.float(2.0, "Stop Loss %", step=0.1)

// --- Calculate ---
fastMA  = ta.ema(close, fastLen)
slowMA  = ta.ema(close, slowLen)
trendMA = ta.sma(close, trendLen)

bullCross = ta.crossover(fastMA, slowMA)
bearCross = ta.crossunder(fastMA, slowMA)

bullSignal = useFilter ? (bullCross and close > trendMA) : bullCross
bearSignal = useFilter ? (bearCross and close < trendMA) : bearCross

// --- Entry ---
if bullSignal
    strategy.entry("Long", strategy.long)

if bearSignal
    strategy.entry("Short", strategy.short)

// --- Stop Loss ---
if useSL
    strategy.exit("Long SL", "Long", stop=strategy.position_avg_price * (1 - slPct / 100))
    strategy.exit("Short SL", "Short", stop=strategy.position_avg_price * (1 + slPct / 100))

// --- Plot ---
plot(fastMA, "Fast", color.blue, 2)
plot(slowMA, "Slow", color.orange, 2)
plot(trendMA, "Trend", color.gray, 1)

After adding to chart, click the Strategy Tester tab to see backtest results. Pay attention to:

> My experience: On USDJPY daily with the 9/21 EMA + 50 SMA filter, I've seen a profit factor around 1.3-1.6 depending on the period. Not spectacular, but consistent β€” and that's the point. A strategy that survives sideways markets beats one that prints 300% in a trending market and then gives it all back.

Step 4: Setting Up Alerts for Live Trading

This is where TradingView becomes genuinely useful for execution. You can set alerts on crossover events and route them to Telegram, email, or webhook.

πŸ’‘ TradingView

Like what you're reading? Try it yourself β€” this link supports ChartedTrader at no cost to you.

Try TradingView Free β†’
🎁 You receive: 30-day free trial (Essential / Plus / Premium) · no credit card needed

// tested: 2026-06-15 on TradingView Pine Script v6
// Add these to your indicator (not the strategy version):
alertcondition(bullSignal, "MA Cross Buy", "🟒 MA Crossover BUY signal on {{ticker}} at {{close}}")
alertcondition(bearSignal, "MA Cross Sell", "πŸ”΄ MA Crossover SELL signal on {{ticker}} at {{close}}")

To create an alert:

1. Right-click on the chart β†’ Add Alert 2. Select your indicator from the condition dropdown 3. Choose "MA Cross Buy" or "MA Cross Sell" 4. Set notification method (Telegram, webhook, app notification) 5. Set expiration (paid plans get longer alert durations)

I route my alerts to a private Telegram channel. When a signal fires, I review the chart manually before deciding whether to act on it. Fully automated execution is a separate topic β€” if you're interested, I wrote about building automated strategies with Interactive Brokers' Python API.

Step 5: Optimizing Your Parameters

The default 9/21 EMA is a good starting point, but optimal parameters vary by instrument and timeframe:

MarketTimeframeFast/SlowTrend FilterNotes
USDJPYDaily9/21 EMA50 SMAMy production setup
BTC/USDT4H12/26 EMA50 SMACrypto needs slightly wider windows
S&P 500Daily20/50 SMA200 SMAClassic institutional setup
EUR/USD1H5/13 EMA34 EMAScalping-friendly
How I optimize: I don't curve-fit to historical data. Instead, I test a handful of parameter sets across different market regimes (trending, ranging, volatile) and pick the one that's *consistently decent* rather than occasionally spectacular.

Common Mistakes to Avoid

1. Overfitting parameters. If your strategy only works with a 13.7 EMA and a 27.3 SMA on USDJPY 4H from 2023-2024, you've curve-fitted. Use round numbers. If it doesn't work with 10/20, it probably doesn't work. 2. Ignoring transaction costs. TradingView's strategy tester defaults to zero commission. Set realistic values: as of 2026-06, for forex, expect 1-2 pips spread; for crypto on a platform like Hyperliquid, 0.035% taker fees add up fast. 3. No stop loss. A moving average crossover can keep you in a losing trade for weeks while it waits for the reverse cross. Always have a stop loss β€” 2-3% of position value is a reasonable starting point. 4. Trading every crossover. The trend filter exists for a reason. In a ranging market, MAs whipsaw constantly and every cross is a false signal.

Going Beyond: What I Actually Use

The Pine Script crossover above is a building block. My actual USDJPY strategy layers additional filters:

If you want to see how a complete systematic strategy looks in production (with Python, not Pine Script), check out my guide on building a momentum strategy with Interactive Brokers' Python API.

---

FAQ

Is a moving average crossover strategy still profitable in 2026?

On its own, a raw MA crossover is marginal at best. The edge comes from combining it with filters β€” trend direction, momentum, volatility, or seasonality. Think of the crossover as a timing mechanism, not a complete strategy.

What's the best moving average type for crossover strategies β€” SMA or EMA?

EMA reacts faster to recent price changes, which means earlier entries but more false signals. SMA is smoother but slower. For shorter timeframes (1H, 4H), I prefer EMA. For daily charts, either works β€” I use EMA for the fast line and SMA for the trend filter.

Can I automate Pine Script crossover signals for live trading?

Yes β€” TradingView alerts can send webhooks to external systems. You'd need a webhook receiver that connects to your broker's API. I use TradingView for signal generation and Interactive Brokers' Python API for execution. Some traders also use services like 3Commas or Alertatron as middleware.

What timeframe works best for MA crossover strategies?

Daily charts produce the most reliable signals with the least noise. 4H is good for active traders who can monitor positions. Anything below 1H generates too many false signals for MA crossovers to be practical β€” you'd need additional confluence (volume, orderflow, etc.).

How do I avoid false signals from moving average crossovers?

Three approaches that work in practice: (1) Add a trend filter β€” only take signals in the direction of a longer-term MA. (2) Require a close above/below the crossover level, not just an intrabar touch. (3) Wait for a confirmation bar after the crossover before entering.

---

Try It Yourself

TradingView is hands-down the best platform for developing and testing Pine Script strategies. The free plan lets you build indicators; paid plans unlock server-side alerts and more historical data for backtesting (as of 2026-06).

Start with the filtered crossover (Step 2), apply it to whatever market you trade, and see how it performs before committing real capital.

---

*This article contains affiliate links. If you sign up through them, I may earn a commission at no extra cost to you. I only recommend tools I actually use. Trading involves risk β€” past performance doesn't guarantee future results.*

TradingView

Ready to get started? Use the link below β€” it helps support ChartedTrader at no cost to you.

Try TradingView Free β†’
🎁 You receive: 30-day free trial (Essential / Plus / Premium) · no credit card needed
πŸ“ˆ

About the author

I'm a systematic trader running live strategies on IB (USDJPY momentum) and Hyperliquid (crypto perps). Every tool reviewed here is something I've used with real capital. Questions? Reach out.

πŸ“š Related Articles

βš™οΈ
Trading Tools

TradingView Hotlists & Premarket Filters 2026

How to use TradingView hotlists, top gainers, and premarket filters to find active stocks before the open. A 2026 scanner workflow for day traders.

July 9, 2026 ⏱ 10 min read
βš™οΈ
Trading Tools

TradingView Keyboard Shortcuts: Order Panel & Drawing (2026)

Master TradingView keyboard shortcuts for chart drawing and the order panel. Speed up your workflow with essential keybindings for faster trading in 2026.

July 3, 2026 ⏱ 11 min read
βš™οΈ
Trading Tools

Hyperliquid Android: Email vs Wallet Login (2026)

Email vs wallet login on Hyperliquid Android: setup time, custody, fees, recovery, and security walked through end-to-end (2026).

May 15, 2026 ⏱ 11 min read

πŸ“¬ Get weekly trading insights

Real trades, honest reviews, no fluff. One email per week.