⚙️ Trading Tools

TradingView Pine Script Moving Average Crossover: Build a Real Strategy Step by Step (2026)

⚠️ 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.
# TradingView Pine Script Moving Average Crossover: Build a Real Strategy Step by Step (2026)

*A practical Pine Script tutorial using a moving average crossover I actually trade — not another copy-paste template.*

---

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.

---

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:

//@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:

//@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:

//@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.

// 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: for forex, 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.

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 →
📈

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

Best Charting Software for Forex Traders 2026: TradingView vs MT4 vs cTrader

I tested 6 charting platforms for live forex trading. TradingView wins overall, but MT4 still beats it for algo execution and cTrader for order flow. Honest comparison with real trading screenshots.

February 25, 2026 ⏱ 9 min read
⚙️ Trading Tools

TradingView Review 2026: Complete Guide for Serious Traders (Free vs Pro vs Premium)

I chart USDJPY daily on TradingView and built custom Pine Script indicators. Full breakdown: is Pro worth $13/month? Mobile vs desktop, alerts that actually work, and the features most reviews skip.

February 22, 2026 ⏱ 3 min read
📖 Guides

TradingView Strategy Tester Backtest Settings Explained (2026 Guide)

I backtested 200+ USDJPY trades on TradingView and discovered my results were 40% off until I fixed 3 settings. Here's what actually matters.

March 2, 2026 ⏱ 10 min read

📬 Get weekly trading insights

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