EMA Crossover Strategy
Learn to build a sophisticated trend-following strategy using Exponential Moving Averages (EMAs) with additional confirmation filters. This intermediate tutorial builds on the basics and introduces multi-condition entry logic.
Strategy Overview
This strategy improves upon simple moving average crossovers by:
- Using EMAs instead of SMAs (more responsive to recent price action)
- Adding price position filter (price must be above both EMAs for long entries)
- Including volume confirmation
- Implementing trailing stops to maximize profits
- Using partial exits to lock in gains progressively
Expected Performance
- Win Rate: 40-50%
- Profit Factor: 1.8-2.5
- Best Markets: Trending stocks/commodities
- Timeframe: 15m to 1h
- Risk-Reward: 1:3
Why EMA Over SMA?
Exponential Moving Average (EMA) gives more weight to recent prices, making it:
- More responsive to price changes
- Better for trend-following
- Generates earlier signals
- Reduces lag compared to SMA
Formula: EMA = (Close × Multiplier) + (Previous EMA × (1 - Multiplier))
- Multiplier = 2 / (Period + 1)
Step 1: Basic Configuration
Strategy Details
Name: EMA Trend Follower
Description: EMA crossover with price and volume confirmation
Strategy Type: Momentum
Timeframe: 15m
Symbols: NSE:RELIANCE, NSE:TCS, NSE:INFY
Trading multiple symbols:
- Diversifies risk across different stocks
- Increases signal opportunities
- Reduces impact of single stock volatility
- Ensure symbols are not highly correlated
Step 2: Position Sizing
Use Risk-based position sizing for better risk management:
{
"method": "risk_based",
"riskPercentage": 1.5,
"stopLossPercentage": 2
}
How It Works
Position Size = (Account Balance × Risk%) / Stop Loss Distance
Example:
- Account: ₹100,000
- Risk per trade: 1.5% = ₹1,500
- Stop loss: 2% = ₹40 per share (if entry at ₹2,000)
- Position size: ₹1,500 / ₹40 = 37.5 shares ≈ 37 shares
This automatically adjusts position size based on stop loss distance, ensuring consistent risk per trade.
Step 3: Entry Conditions
Create a multi-condition entry system with three filters:
Condition 1: EMA Crossover (Primary Signal)
For Long Entries:
{
"type": "indicator_indicator",
"indicator1": "EMA",
"period1": 9,
"indicator2": "EMA",
"period2": 21,
"operator": "crosses_above"
}
The 9 EMA crossing above the 21 EMA signals bullish momentum.
- 9 EMA: Fast-moving, captures short-term trends
- 21 EMA: Medium-term trend filter
- 50 EMA: Long-term trend direction (we'll use this next)
Common combinations: 9/21, 12/26, 20/50
Condition 2: Price Above EMAs (Trend Filter)
{
"type": "price_indicator",
"priceType": "close",
"indicator": "EMA",
"period": 50,
"operator": "above"
}
This ensures we only enter when price is above the 50 EMA, confirming an uptrend.
Why This Matters:
- Filters out counter-trend signals
- Increases win rate significantly
- Aligns trades with dominant trend
- Reduces whipsaws in ranging markets
Condition 3: Volume Confirmation
{
"type": "indicator_value",
"indicator": "Volume",
"period": 20,
"operator": "above",
"value": "SMA"
}
Volume must be above its 20-period average, confirming genuine buying interest.
Complete Entry Configuration
{
"positionType": "both",
"logicalOperator": "AND",
"confirmationCandles": 2,
"conditions": [
{
"type": "indicator_indicator",
"indicator1": "EMA",
"period1": 9,
"indicator2": "EMA",
"period2": 21,
"operator": "crosses_above"
},
{
"type": "price_indicator",
"priceType": "close",
"indicator": "EMA",
"period": 50,
"operator": "above"
},
{
"type": "indicator_value",
"indicator": "Volume",
"period": 20,
"operator": "above",
"value": "SMA"
}
]
}
Setting confirmationCandles: 2 means:
- Wait for 2 candles after signal
- Reduces false breakouts
- Slightly delays entry but improves quality
- Recommended for 15m timeframe
Step 4: Exit Conditions
Implement a sophisticated exit strategy with multiple components:
Stop Loss: ATR-Based
{
"type": "ATR",
"period": 14,
"multiplier": 2.0
}
Average True Range (ATR) adapts to market volatility:
- High volatility → Wider stops (avoids premature exits)
- Low volatility → Tighter stops (protects capital)
- 2.0 multiplier is standard (1.5 for aggressive, 2.5 for conservative)
Example:
Entry: ₹2,000
ATR(14): ₹30
Stop Loss: ₹2,000 - (₹30 × 2.0) = ₹1,940
Take Profit: Multiple Targets (Partial Exits)
{
"type": "multiple_targets",
"targets": [
{
"percentage": 3,
"exitPercentage": 33,
"moveStopTo": "breakeven"
},
{
"percentage": 6,
"exitPercentage": 33
},
{
"percentage": 9,
"exitPercentage": 34
}
]
}
Scaling Out Strategy:
- First Target (3%): Exit 33% of position, move stop to breakeven
- Second Target (6%): Exit another 33%
- Third Target (9%): Exit remaining 34%
Benefits:
- Locks in profits progressively
- Reduces risk after first target
- Lets winners run
- Psychological comfort (guaranteed profit after target 1)
Trailing Stop
{
"enabled": true,
"type": "percentage",
"percentage": 2,
"activationThreshold": 2
}
How It Works:
- Activates after 2% profit
- Trails price by 2%
- Locks in profits as price rises
- Never moves down (only up for longs)
Example:
Entry: ₹2,000
Price rises to ₹2,100 (+5%)
Trailing stop: ₹2,100 - 2% = ₹2,058
Price rises to ₹2,150 (+7.5%)
Trailing stop: ₹2,150 - 2% = ₹2,107
Exit on Opposite Signal
{
"enabled": true,
"closeImmediately": true
}
Exit long positions when 9 EMA crosses below 21 EMA (and vice versa for shorts).
Step 5: Risk Parameters
{
"maxPositionSize": 15,
"maxDailyLoss": 4,
"maxOpenPositions": 5,
"riskRewardRatio": 2
}
Parameter Explanations
maxPositionSize: 15%
- Allows larger positions than beginner strategy
- Still maintains diversification
- Suitable for liquid stocks
maxDailyLoss: 4%
- Circuit breaker for bad days
- Prevents emotional trading
- Protects capital
maxOpenPositions: 5
- Can trade multiple symbols simultaneously
- Increases opportunity
- Manages overall exposure
riskRewardRatio: 2
- Minimum 1:2 risk-reward
- With 40% win rate, still profitable
- Ensures favorable odds
Complete Strategy Configuration
Here's the full JSON configuration:
{
"name": "EMA Trend Follower",
"description": "EMA crossover with price and volume confirmation",
"strategyType": "momentum",
"timeframe": "15m",
"symbols": ["NSE:RELIANCE", "NSE:TCS", "NSE:INFY"],
"positionSizing": {
"method": "risk_based",
"riskPercentage": 1.5,
"stopLossPercentage": 2
},
"entryConditions": {
"positionType": "both",
"logicalOperator": "AND",
"confirmationCandles": 2,
"conditions": [
{
"type": "indicator_indicator",
"indicator1": "EMA",
"period1": 9,
"indicator2": "EMA",
"period2": 21,
"operator": "crosses_above"
},
{
"type": "price_indicator",
"priceType": "close",
"indicator": "EMA",
"period": 50,
"operator": "above"
},
{
"type": "indicator_value",
"indicator": "Volume",
"period": 20,
"operator": "above",
"value": "SMA"
}
]
},
"exitConditions": {
"stopLoss": {
"type": "ATR",
"period": 14,
"multiplier": 2.0
},
"takeProfit": {
"type": "multiple_targets",
"targets": [
{
"percentage": 3,
"exitPercentage": 33,
"moveStopTo": "breakeven"
},
{
"percentage": 6,
"exitPercentage": 33
},
{
"percentage": 9,
"exitPercentage": 34
}
]
},
"trailingStop": {
"enabled": true,
"type": "percentage",
"percentage": 2,
"activationThreshold": 2
},
"exitOnOppositeSignal": {
"enabled": true,
"closeImmediately": true
}
},
"riskParameters": {
"maxPositionSize": 15,
"maxDailyLoss": 4,
"maxOpenPositions": 5,
"riskRewardRatio": 2
}
}
Running a Backtest
Before deploying, test the strategy:
1. Create Backtest
Navigate to Backtests → New Backtest
2. Configure Parameters
Date Range: Last 6 months
Initial Balance: ₹100,000
Symbols: NSE:RELIANCE, NSE:TCS, NSE:INFY
Slippage: 0.1%
Commission: 0.05% per trade
3. Interpret Results
Look for these metrics:
Good Results:
Total Trades: 45
Win Rate: 44%
Profit Factor: 2.1
Total Return: +18.5%
Max Drawdown: -8.2%
Sharpe Ratio: 1.8
Warning Signs:
Win Rate: <35% (too many losses)
Profit Factor: <1.5 (not profitable enough)
Max Drawdown: >20% (too risky)
Total Trades: <20 (not enough data)
4. Analyze Trade Distribution
Check the trade distribution chart:
- Should see more winning trades than losing
- Winning trades should be larger than losing trades
- Drawdown periods should recover quickly
Optimization Tips
If Win Rate is Too Low (<40%)
- Increase confirmation candles from 2 to 3
- Add RSI filter: Only enter when RSI is between 40-60 (neutral zone)
- Tighten trend filter: Require price above both 21 and 50 EMAs
If Profit Factor is Low (<1.5)
- Widen stop loss: Increase ATR multiplier from 2.0 to 2.5
- Adjust targets: Change to 4%, 8%, 12% instead of 3%, 6%, 9%
- Use trailing stop more aggressively: Activate at 1% instead of 2%
If Too Few Signals
- Reduce confirmation candles from 2 to 1
- Remove volume filter (keep only EMA and price filters)
- Add more symbols to trade
- Use shorter timeframe (5m instead of 15m)
If Too Many Signals
- Add time filters: Trade only during high-volume hours (10 AM - 2 PM)
- Increase EMA periods: Use 12/26 instead of 9/21
- Add ADX filter: Only trade when ADX > 25 (strong trend)
Common Mistakes to Avoid
1. Ignoring Market Conditions
Problem: Strategy works in trending markets but fails in ranging markets.
Solution:
- Add ADX filter (ADX > 25 for trending markets)
- Pause algorithm during low-volatility periods
- Monitor market regime (trending vs ranging)
2. Over-Optimization
Problem: Tweaking parameters until backtest looks perfect.
Solution:
- Use walk-forward optimization
- Test on out-of-sample data
- Keep parameters simple and logical
- Avoid curve-fitting
3. Ignoring Slippage and Commissions
Problem: Backtest shows profit but live trading loses money.
Solution:
- Always include realistic slippage (0.1-0.2%)
- Add broker commissions (0.03-0.05% per trade)
- Account for STT and GST (Indian markets)
- Test with conservative assumptions
4. Not Adapting to Volatility
Problem: Fixed stops get hit too often in volatile markets.
Solution:
- Use ATR-based stops (already implemented)
- Adjust position size based on volatility
- Consider volatility-adjusted position sizing
Next Steps
1. Add Advanced Filters
Enhance the strategy with:
- RSI divergence detection: RSI Divergence Strategy
- Multi-timeframe confirmation: Multi-Timeframe Strategy
- Candlestick patterns: Add hammer/engulfing confirmation
2. Optimize Parameters
Use walk-forward optimization:
- Test different EMA periods (9/21, 12/26, 20/50)
- Experiment with ATR multipliers (1.5, 2.0, 2.5)
- Try various partial exit levels
Learn more: Strategy Optimization
3. Deploy to Paper Trading
Test in real-time:
- Run for 2-4 weeks minimum
- Monitor signal quality
- Track slippage and execution
- Compare to backtest results
4. Go Live
When ready:
- Start with 1 symbol
- Use 50% of intended position size
- Monitor closely for first week
- Gradually scale up
Learn more: Paper to Live Transition
Summary
You've learned to build a sophisticated EMA crossover strategy with:
- ✅ Multi-condition entry logic (EMA crossover + price filter + volume)
- ✅ ATR-based adaptive stops
- ✅ Partial exits for progressive profit-taking
- ✅ Trailing stops to maximize gains
- ✅ Risk-based position sizing
- ✅ Comprehensive backtesting
Key Improvements Over Simple MA Crossover:
- EMAs respond faster than SMAs
- Price filter ensures trend alignment
- Volume confirms genuine moves
- ATR adapts to volatility
- Partial exits optimize profit-taking
- Trailing stops capture extended moves
This strategy works best in trending markets with clear directional moves. In ranging markets, consider adding filters or pausing the algorithm.
Ready for more advanced techniques? Try the RSI Divergence Strategy next!