DEV Community

FMZQuant
FMZQuant

Posted on

Multi-Timeframe WaveTrend Trend-Following Strategy

Overview
The Multi-Timeframe WaveTrend Trend-Following Strategy is a comprehensive trading system based on the WaveTrend indicator applied across multiple timeframes. Specifically optimized for the 15-minute timeframe, this strategy employs a three-tiered approach: using the 240-minute WaveTrend as a macro trend filter, the 30-minute WaveTrend for momentum confirmation, and the 15-minute WaveTrend for signal generation. The core mechanism identifies WaveTrend crossovers across different timeframes to determine entry and exit points, while incorporating an advanced trailing stop mechanism that includes maximum gain-based tracking logic and percentage-based fallback tolerance to maximize profits and effectively control risk.

Strategy Principles
The fundamental principle of this strategy lies in leveraging the WaveTrend indicator across multiple timeframes to identify trend direction and turning points. The WaveTrend indicator itself is a technical tool that measures overbought and oversold conditions by calculating the relationship between price and its exponential moving average (EMA), combined with a volatility factor.

The strategy implementation process is as follows:

First, the WaveTrend function is defined to calculate two main values (wt1 and wt2):

  • Calculate the EMA of price (typically HLC3)
  • Calculate the EMA of the absolute difference between price and its EMA as a volatility measure
  • Construct a normalized relative price deviation (ci)
  • Calculate the EMA of ci as wt1, and the SMA of wt1 as wt2

The strategy applies the WaveTrend indicator across three timeframes:

  • 15-minute chart (current timeframe) for specific signal generation
  • 30-minute chart for confirming medium-term momentum direction
  • 60-minute chart for providing longer-term trend context

Entry conditions:

  • Long: When wt1 crosses above wt2 on the 15-minute chart, with wt1 value greater than -60, while the trend is up on the 30-minute chart (wt1 > wt2)
  • Short: When wt1 crosses below wt2 on the 15-minute chart, with wt1 value less than 20, while the trend is down on the 30-minute chart (wt1 < wt2)

Stop-loss and exit mechanisms use a composite approach:

  • Fixed percentage marginal stop
  • Profit-triggered trailing stop
  • Maximum gain-based protective stop

The strategy records and tracks the entry price, entry bar number, and maximum gain percentage for each trade, which are used to dynamically adjust exit points.

Strategy Advantages

  1. Multi-Timeframe Synergy: By analyzing the WaveTrend indicator across different timeframes, the strategy can comprehensively grasp market trends, reduce false signal interference, and improve trading accuracy. Lower timeframes provide precise entry points, while higher timeframes ensure that trade direction aligns with the main trend.

  2. Dynamic Stop-Loss Mechanism: The strategy employs a triple protection system, including fixed percentage stops, profit-based trailing stops, and maximum gain protection. This composite stop-loss strategy can protect capital while maximizing gains captured during trends.

  3. Visual Feedback System: Trading entry and exit points are intuitively marked on the chart with colored labels (🟢🔴❅❄) that include bar number information, facilitating backtest analysis and trade review.

  4. Flexible Parameters: The strategy provides multiple customizable parameters, including trailing stop trigger percentage, trailing follow percentage, and maximum allowable drawdown percentage, allowing users to adjust according to their risk preferences and market conditions.

  5. Clear Code Structure: The strategy employs a functional design with distinct logical components, making it easy to understand and maintain, while also facilitating further optimization and extension.

Strategy Risks

  1. Delayed Reaction to Trend Reversals: As a trend-following strategy, it may exhibit delayed responses at trend turning points, leading to larger drawdowns when the market reverses. Solutions include adjusting trailing stop parameters or adding supplementary trend reversal indicators.

  2. Poor Performance in Volatile Markets: In ranging or highly volatile market environments, the strategy may generate frequent false signals and stop-outs, resulting in consecutive losses. It is recommended to enable this strategy only when the market is in a confirmed trend.

  3. Parameter Sensitivity: Strategy performance is quite sensitive to WaveTrend parameter settings (n1=10, n2=21) and stop-loss parameters. Loose parameters may lead to late stops, while tight parameters might exit favorable trends too early. Historical backtesting is needed to optimize these parameters.

  4. Liquidity Risk: The code defaults to using a relative fund amount (10%) for trading, but in low-liquidity markets, this may lead to increased slippage or execution difficulties. Position size should be adjusted according to the actual liquidity conditions of the trading instrument.

  5. External Data Dependency: The strategy uses the request.security() function to obtain higher timeframe data, which may experience delays or data unavailability on some trading platforms. Ensure that the trading environment supports multi-timeframe data requests.

Strategy Optimization Directions

  1. Dynamic Parameter Adjustment: The current strategy uses fixed WaveTrend parameters and stop-loss ratios. Consider dynamically adjusting these parameters based on market volatility (such as ATR). For example, increase stop distances in high-volatility environments and tighten stops in low-volatility environments to adapt to different market conditions.

  2. Add Trend Strength Filtering: ADX or similar indicators can be added to measure trend strength, executing trades only when trend strength exceeds specific thresholds, avoiding excessive trading in weak trend or ranging markets.

  3. Optimize Timeframe Selection: The current strategy uses 15-minute, 30-minute, and 60-minute timeframes. Through backtest analysis, find the optimal timeframe combination, or adjust timeframes based on the characteristics of different trading instruments.

  4. Incorporate Volume Confirmation: Integrate volume indicators into entry conditions to ensure entries only in volume-supported trends, improving signal quality.

  5. Improve Exit Mechanism: Current exits primarily rely on stop-loss triggers. Consider adding profit targets or reverse signals based on the WaveTrend indicator itself as active exit conditions, rather than relying solely on passive stop-losses.

  6. Enhance Position Management Logic: The strategy currently uses fixed percentage fund management. Consider dynamically adjusting position size based on volatility or signal strength, increasing positions in more confident trades and reducing risk exposure in higher uncertainty situations.

Summary
The Multi-Timeframe WaveTrend Trend-Following Strategy is a well-designed trend following system that effectively captures market trends and controls risk through the synergistic action of multi-timeframe WaveTrend indicators combined with flexible trailing stop mechanisms. The main advantages of this strategy lie in its comprehensive market perspective and dynamic risk management approach, though it may face challenges in volatile markets. Through further optimization of timeframe selection, dynamic parameter adjustment, and additional filtering conditions, this strategy has the potential to become an even more robust and adaptive trading system. For professional traders, this represents a trend-following framework worth in-depth research and customized development.

Strategy source code

/*backtest
start: 2024-07-07 00:00:00
end: 2024-11-28 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/

//@version=5
strategy("WT-FLOW: MTF WaveTrend Trend-Follower", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10)

// === WaveTrend Fonksiyonu ===
waveTrend(_src, _n1, _n2) =>
    esa = ta.ema(_src, _n1)
    d = ta.ema(math.abs(_src - esa), _n1)
    ci = (_src - esa) / (0.015 * d)
    wt1 = ta.ema(ci, _n2)
    wt2 = ta.sma(wt1, 4)
    [wt1, wt2]

// === Entry Price and Maximum Profit Variables ===
var float longEntryPrice = na
var float shortEntryPrice = na
var float maxGainLong = 0.0
var float maxGainShort = 0.0
var int longEntryBar = na
var int shortEntryBar = na
var string currentPosition = ""

// === Get WT Values (Different Time Zones) ===
var int n1 = 10
var int n2 = 21
ap = hlc3
[wt1_15, wt2_15] = waveTrend(ap, n1, n2)
[wt1_30, wt2_30] = request.security(syminfo.tickerid, "30", waveTrend(ap, n1, n2))
[wt1_60, wt2_60] = request.security(syminfo.tickerid, "60", waveTrend(ap, n1, n2))

// === User Inputs: Trailing Stop Parameters ===
marginStopPerc = input.float(2.0, "Marginal Stop (%)")
trailTriggerPerc = input.float(1.5, "Trailing Trigger (%)")
trailFollowPerc = input.float(0.8, "Trailing Cap (%)")
trailMaxDropPerc = input.float(3.0, "Maximum Drop (%)")

// === TR calculation for ATR ===
tr = ta.tr(true)

// === Signal Conditions ===
trendUp = wt1_30 > wt2_30
trendDown = wt1_30 < wt2_30
entryLong = ta.crossover(wt1_15, wt2_15) and wt1_15 > -60 and trendUp
entryShort = ta.crossunder(wt1_15, wt2_15) and wt1_15 < 20 and trendDown

// === Position Entries ===
if entryLong and currentPosition != "Long"
    strategy.entry("Long", strategy.long)
    longEntryPrice := close
    maxGainLong := 0.0
    longEntryBar := bar_index
    currentPosition := "Long"
    label.new(bar_index, high + 2 * tr, "🟢 Login Long #" + str.tostring(bar_index), style=label.style_label_up, color=color.green, textcolor=color.white)

if entryShort and currentPosition != "Short"
    strategy.entry("Short", strategy.short)
    shortEntryPrice := close
    maxGainShort := 0.0
    shortEntryBar := bar_index
    currentPosition := "Short"
    label.new(bar_index, low - 2 * tr, "🔴 Login Short #" + str.tostring(bar_index), style=label.style_label_down, color=color.red, textcolor=color.white)

// === Trailing Stop and Marginal Stop Levels ===
if currentPosition == "Long" and not na(longEntryPrice)
    gainFromEntry = (close - longEntryPrice) / longEntryPrice * 100
    maxGainLong := math.max(maxGainLong, gainFromEntry)
    trailTriggerReached = gainFromEntry >= trailTriggerPerc
    trailStop = close * (1 - trailFollowPerc / 100)
    dropStop = longEntryPrice * (1 + (maxGainLong - trailMaxDropPerc) / 100)
    finalStop = trailTriggerReached ? math.max(trailStop, dropStop) : longEntryPrice * (1 - marginStopPerc / 100)
    if close <= finalStop
        strategy.close("Long")
        label.new(bar_index, low - 2 * tr, "❅ Çıkış Long #" + str.tostring(longEntryBar), style=label.style_label_down, color=color.red, textcolor=color.white)
        longEntryPrice := na
        longEntryBar := na
        currentPosition := ""

if currentPosition == "Short" and not na(shortEntryPrice)
    gainFromEntryShort = (shortEntryPrice - close) / shortEntryPrice * 100
    maxGainShort := math.max(maxGainShort, gainFromEntryShort)
    trailTriggerReachedShort = gainFromEntryShort >= trailTriggerPerc
    trailStopShort = close * (1 + trailFollowPerc / 100)
    dropStopShort = shortEntryPrice * (1 - (maxGainShort - trailMaxDropPerc) / 100)
    finalStopShort = trailTriggerReachedShort ? math.min(trailStopShort, dropStopShort) : shortEntryPrice * (1 + marginStopPerc / 100)
    if close >= finalStopShort
        strategy.close("Short")
        label.new(bar_index, high + 2 * tr, "❄ Çıkış Short #" + str.tostring(shortEntryBar), style=label.style_label_up, color=color.green, textcolor=color.white)
        shortEntryPrice := na
        shortEntryBar := na
        currentPosition := ""

Enter fullscreen mode Exit fullscreen mode

Strategy parameters

The original address: Multi-Timeframe WaveTrend Trend-Following Strategy

Top comments (1)

Collapse
 
quant_fmz_5544836beadc814 profile image
Rebecca Chow

Wavetrend on multiple timeframes? Now that’s some inception-level trend following! 😄 Love how this strategy smooths out the noise without overfitting. Might have to teach my indicators to communicate across timeframes like this. Appreciate the share!