Strategy vault / Trend following
Dynamic Trend Following EMA ADX Multi Level Take Profit Strategy
This strategy is a trend-following trading system that combines EMA and ADX indicators with multi-level take-profit and trailing stop-loss mechanisms for optimized money management. It uses EMA for trend direction…

Overview
This strategy is a trend-following trading system that combines EMA and ADX indicators with multi-level take-profit and trailing stop-loss mechanisms for optimized money management. It uses EMA for trend direction determination, ADX for trend strength filtering, and implements a three-tiered take-profit mechanism for batch profit-taking, while using ATR for dynamic stop-loss adjustment to control risk.
Strategy Principles
The core logic includes several key components:
- Uses 50-period EMA to determine trend direction, entering long when price crosses above EMA and short when crossing below
- Filters weak trends using 14-period ADX, confirming valid trends when ADX>20
- Calculates dynamic stop-loss positions based on 14-period ATR, setting stops at low-1ATR for longs and high+1ATR for shorts
- Implements a three-tiered take-profit mechanism:
- First tier: 30% position closes at 1x ATR
- Second tier: 50% position closes at 2x ATR
- Third tier: 20% position uses 3x ATR trailing stop
- Automatically closes all remaining positions when price reaches second-tier take-profit level
Strategy Advantages
- Multi-level take-profit design secures profits while maintaining exposure to larger moves
- Trailing stop mechanism adapts to market volatility, providing dynamic risk control
- ADX filtering effectively avoids false signals in ranging markets
- EMA and price crossovers provide clear entry signals
- Batch profit-taking reduces emotional volatility, supporting long-term strategy execution
Strategy Risks
- May result in frequent trading and increased costs in ranging markets
- EMA as a lagging indicator might be slow to react in rapid reversals
- Fixed ADX threshold may need adjustment in different market conditions
- Multi-level take-profit might reduce position size too early in strong trends Mitigation measures:
- Dynamically adjust ADX threshold based on market cycles
- Consider adding trend confirmation indicators
- Optimize take-profit ratio parameters more precisely
Strategy Optimization Directions
- Incorporate volume indicators for enhanced trend confirmation
- Implement dynamic ADX thresholds based on market volatility
- Optimize position allocation ratios for take-profit levels
- Add trend strength classification with corresponding take-profit strategies
- Consider incorporating seasonality and market cycle factors
Summary
This is a well-structured trend-following strategy with clear logic, balancing returns and risks through multi-level take-profits and dynamic stop-losses. The strategy design adheres to basic quantitative trading principles, offering good scalability and optimization potential. Through appropriate parameter adjustment and optimization upgrades, this strategy has the potential to maintain stable performance across different market conditions.
Source Pine Script
/*backtest
start: 2024-03-06 18:40:00
end: 2025-02-17 00:00:00
period: 4h
basePeriod: 4h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=6
strategy("BTC Optimized Strategy v6", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=250)
// === Parameter Settings ===
lengthEMA = input(50, title="EMA Cycle")
adxLength = input(14, title="ADX Cycle")
atrLength = input(14, title="ATR Cycle")
riskReward = input(2.0, title="Risk-reward ratio")
tp1_ratio = input(1.0, title="TP1 (ATR multiple)")
tp2_ratio = input(2.0, title="TP2 (ATR multiple)")
trailATR = input(3.0, title="Moving Take Profit ATR Multiple")
// === Calculate technical indicators ===
ema = ta.ema(close, lengthEMA)
atr = ta.atr(atrLength)
// === Calculate ADX ===
upMove = math.max(high - nz(high[1], high), 0)
downMove = math.max(nz(low[1], low) - low, 0)
tr = math.max(math.max(high - low, math.abs(high - nz(close[1], close))), math.abs(low - nz(close[1], close)))
plusDM = upMove > downMove and upMove > 0 ? upMove : 0
minusDM = downMove > upMove and downMove > 0 ? downMove : 0
plusDI = 100 * ta.rma(plusDM, adxLength) / ta.rma(tr, adxLength)
minusDI = 100 * ta.rma(minusDM, adxLength) / ta.rma(tr, adxLength)
dx = 100 * math.abs(plusDI - minusDI) / (plusDI + minusDI)
adx = ta.rma(dx, adxLength)
// === Trend filter conditions ===
isTrending = adx > 20
// === Entry Conditions ===
longCondition = ta.crossover(close, ema) and isTrending
shortCondition = ta.crossunder(close, ema) and isTrending
// === Calculate stop loss and take profit prices ===
longStopLoss = low - atr
shortStopLoss = high + atr
longTP1 = close + tp1_ratio * atr
longTP2 = close + tp2_ratio * atr
shortTP1 = close - tp1_ratio * atr
shortTP2 = close - tp2_ratio * atr
// === Set Entry and Exit ===
if longCondition
strategy.entry("Long", strategy.long)
strategy.exit("Long_Exit1", from_entry="Long", qty_percent=30, limit=longTP1, stop=longStopLoss)
strategy.exit("Long_Exit2", from_entry="Long", qty_percent=50, limit=longTP2, stop=longStopLoss)
strategy.exit("Long_Trail", from_entry="Long", qty_percent=20,
trail_points=atr * trailATR,
trail_offset=atr * trailATR)
if shortCondition
strategy.entry("Short", strategy.short)
strategy.exit("Short_Exit1", from_entry="Short", qty_percent=30, limit=shortTP1, stop=shortStopLoss)
strategy.exit("Short_Exit2", from_entry="Short", qty_percent=50, limit=shortTP2, stop=shortStopLoss)
strategy.exit("Short_Trail", from_entry="Short", qty_percent=20,
trail_points=atr * trailATR,
trail_offset=atr * trailATR)
// === When price exceeds TP2 Automatically close positions afterwards ===
if close >= longTP2
strategy.close("Long")
if close <= shortTP2
strategy.close("Short")
// === Draw Markings ===
plotshape(series=longCondition, location=location.belowbar, color=color.blue, style=shape.labelup, title="Buy")
plotshape(series=shortCondition, location=location.abovebar, color=color.red, style=shape.labeldown, title="Sell")
plot(ema, color=color.orange, title="EMA")
Published by ChaoZhang on the FMZ strategy square · last modified 2025-02-18. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.
Build this with AgenKit
A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Dynamic-Trend-Following-EMA-ADX-Multi-Level-Take-Profit-Strategy.md- npx agenkit install engineering-kit in your project
- Paste the command into your agent and approve each phase
- Get tests, backtest, risk controls and a paper-trading switch
Understand it first
Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.
Related specs
- Dual EMA Filtered ATR Adaptive Trend Following StrategyPine Script · Trend following · 1h
- Dual Moving Average Trend Detection with Volatility Based Stop Loss StrategyPine Script · Trend following · 1d
- Dynamic EMA Trend Detection with ATR Threshold StrategyPine Script · Trend following · 1h
- Multi Exponential Moving Average Crossover Strategy with Volume Based ATR Dynamic Stop Loss OptimizationPine Script · Trend following · 2d
- Multi Factor Trend Price Action Strategy with Dynamic Risk Management SystemPine Script · Trend following · 2h
- Multi Indicator Dynamic Trend Following Strategy Based on EMA and SMAPine Script · Trend following · 1d