Dynamic Moving Average Crossover Trend Following and Reversal Strategy

MA SMA EMA VWMA 移动平均线 趋势跟踪 止损 交叉策略 动态阈值 多空交易
Created on: 2025-04-29 09:28:25 Modified on: 2025-04-29 09:28:25
Copy: 0 Number of hits: 315
avatar of ianzeng123 ianzeng123
2
Follow
319
Followers

 Dynamic Moving Average Crossover Trend Following and Reversal Strategy  Dynamic Moving Average Crossover Trend Following and Reversal Strategy

Overview

The Dynamic Moving Average Crossover Trend Following and Reversal Strategy is a quantitative trading system based on the relationship between price and moving averages. This strategy determines trading signals by judging the direction of moving averages and price breakouts, with dynamic profit-taking and stop-loss mechanisms. Its core philosophy is to go long in uptrends, short in downtrends, and manage risk through precise entry and exit rules, thereby achieving better performance than simple buy-and-hold in volatile markets.

Strategy Principles

This strategy is designed based on the following core principles:

  1. Dynamic Trend Determination Mechanism: The strategy uses the directional change of moving averages (optional SMA, EMA, or VWMA) to judge market trends. When the moving average rises above a set threshold (default 0.25%), it is determined to be an uptrend; when it falls below the same threshold, it is determined to be a downtrend.

  2. Precise Entry Conditions:

    • Long Entry: During trading sessions, enter when the moving average is in an uptrend and the price breaks above the moving average by a specific percentage.
    • Long Re-entry: Provides re-entry opportunity when still in an uptrend but the price pulls back near the moving average (within 1.01 times MA).
    • Short Entry: During trading sessions, enter when the moving average is in a downtrend and the price breaks below the moving average by a specific percentage.
    • Short Re-entry: Provides re-entry opportunity when still in a downtrend and the price rebounds near the moving average (above 0.998 times MA).
  3. Multi-level Exit Mechanism:

    • Long Exit: Exit when the price retraces a specific percentage (default 1%) from the highest point or drops below the moving average.
    • Short Exit: Exit when the price rebounds a specific percentage (default 0.5%) from the lowest point or rises above the moving average.
    • Short Hard Stop-Loss: To control short risks, a hard stop-loss is set at a specific percentage (default 1.5%) above the entry price.
  4. Time Filtering: The strategy integrates trading session filtering, defaulting to trading only between 9:30 and 15:15, avoiding volatility impacts during non-trading hours.

  5. Backtest Time Range: Users can customize the start and end dates for backtesting, facilitating strategy evaluation under different market conditions.

Strategy Advantages

After in-depth analysis, this strategy has the following significant advantages:

  1. Adaptability to Market Environments: Through dynamic moving average direction judgment, the strategy can automatically adjust trading direction according to market trends, adapting to different market environments.

  2. Fine-tuned Risk Control: The strategy has designed multi-level risk control mechanisms, including trend filtering, retracement exits, moving average crossover exits, and hard stop-losses, effectively preventing significant losses.

  3. Adjustable Sensitivity: By adjusting the type of moving average (SMA/EMA/VWMA), calculation basis (closing price/OHLC/4, etc.), and length parameters, users can optimize the strategy’s sensitivity to market fluctuations.

  4. Diversified Entry Opportunities: The strategy not only provides main breakthrough entry signals but also includes pullback re-entry mechanisms, increasing trading opportunities and optimizing average entry prices.

  5. Visualized Trading Status: The code integrates trading status labels and entry/exit markers, intuitively displaying strategy execution for analysis and optimization.

  6. Complete Alert System: Built-in trading signal alert functions support real-time monitoring and reminders, improving strategy execution efficiency.

Strategy Risks

Despite the comprehensive design, the strategy still has the following potential risks:

  1. False Signals in Choppy Markets: In sideways, choppy markets, the moving average direction may change frequently, leading to excessive trading and losses. The solution is to increase direction confirmation thresholds or integrate other indicators to filter signals.

  2. Parameter Sensitivity: Strategy performance highly depends on parameter settings, such as moving average length and various threshold percentages. Different trading instruments may require different parameter settings, necessitating thorough parameter optimization.

  3. Lack of Volume Confirmation: The current strategy is mainly based on price and moving average relationships, without considering volume factors, which may generate misleading signals in low-volume environments.

  4. Gap Risk Due to Trading Session Restrictions: The strategy is limited to trading in specific sessions, potentially unable to respond to major market changes overnight or outside trading hours, especially in price gap situations.

  5. Lagged Response to Trend Reversals: Although there is a dynamic trend judgment mechanism, the response to sudden drastic trend reversals may lag, potentially causing larger drawdowns in rapidly reversing markets.

Strategy Optimization Directions

Based on code analysis, the strategy can be optimized in the following directions:

  1. Integrate Momentum Indicators: Incorporate momentum indicators such as RSI and MACD into the signal confirmation system to improve trend judgment accuracy and reduce false signals. This is because pure price breakouts may sometimes lead to misjudgments, while momentum indicators can provide additional confirmation.

  2. Add Adaptive Volatility Components: Dynamically adjust entry thresholds and stop-loss ranges based on market volatility, increasing threshold requirements in high-volatility environments to reduce trigger frequency; lowering thresholds in low-volatility environments to increase sensitivity.

  3. Add Volume Filtering: Introduce volume confirmation mechanisms, requiring price breakouts to be accompanied by increased volume, filtering weak breakthrough signals in low-volume environments.

  4. Position Size Optimization: Dynamically adjust position sizes based on trading performance, drawdown magnitude, and win rates, increasing positions on high-conviction signals and reducing positions in high-uncertainty situations.

  5. Timeframe Synthesis: Combine signals from multiple timeframes, such as requiring daily and hourly trends to be consistent before trading, enhancing system robustness.

  6. Partial Position Building and Closing Strategy: Implement mechanisms for partial entry and exit to avoid single-point entry risks while protecting profits through partial profit-taking.

Summary

The Dynamic Moving Average Crossover Trend Following and Reversal Strategy is an elegantly designed trading system that provides traders with a systematic tool to handle market volatility through dynamic trend judgment, flexible entry conditions, and multi-level risk management. Its greatest feature is combining the advantages of trend following and pullback entries, controlling risk through precise entry points while respecting the larger trend.

This strategy is particularly suitable for markets with medium to long-term volatility. Traders can optimize the strategy for different trading instruments by adjusting the type of moving average, length, and various threshold parameters. Although there are risks such as parameter sensitivity and false signals in choppy markets, the strategy’s robustness and adaptability can be further enhanced through the suggested optimization directions, such as integrating momentum indicators, volatility adjustments, and multi-timeframe confirmations.

Overall, this strategy provides traders with a structured quantitative trading framework that has the potential to achieve better risk-adjusted returns than traditional buy-and-hold under correct parameter configuration and appropriate risk management.

Strategy source code
/*backtest
start: 2024-04-29 00:00:00
end: 2024-07-27 00:00:00
period: 2h
basePeriod: 2h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/

//@version=6
// @ipuneetg 
strategy("PG MA Crossover Buy and Sell Options Special", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

// === INPUTS ===
maType = input.string("SMA", title="Select MA Type", options=["SMA", "EMA", "VWMA"])
calcBasis = input.string("close", title="Calculation Basis", options=["close", "OHLC/4", "HLC/3", "HLCC/4"])
maLength = input.int(21, title="Moving Average Length")
reversalThresholdPercent = input.float(0.25, title="Reversal Threshold (%)", step=0.01)
percentBelowTop = input.float(1.0, title="Exit % Below Top (%)", step=0.1, minval=0.1)
shortProfitPercent = input.float(0.5, title="Short Profit Protection (%)", minval=0.1, step=0.1)
stopLossPercent = input.float(1.5, title="Stop Loss % Above Entry (for Shorts)", step=0.1, minval=0.1)
allowShorts = input.bool(true, title="Allow Short Trades?")

// === SESSION SETTINGS ===
startHour = input.int(9, title="Trade Start Hour")
startMinute = input.int(30, title="Start Minute")
endHour = input.int(15, title="Trade End Hour")
endMinute = input.int(15, title="End Minute")

tradeSession = str.tostring(startHour, "00") + str.tostring(startMinute, "00") + "-" + str.tostring(endHour, "00") + str.tostring(endMinute, "00")
sessionActive = not na(time(timeframe.period, tradeSession))


// === PRICE BASIS ===
basis = switch calcBasis
    "OHLC/4" => (open + high + low + close) / 4
    "HLC/3" => (high + low + close) / 3
    "HLCC/4" => (high + low + close + close) / 4
    => close

// === MOVING AVERAGE ===
ma = switch maType
    "SMA" => ta.sma(basis, maLength)
    "EMA" => ta.ema(basis, maLength)
    "VWMA" => ta.vwma(basis, maLength)

// === DYNAMIC REVERSAL DETECTION ===
var float lastReversal = na
var bool isRising = true
thresholdValue = ma * reversalThresholdPercent / 100

if na(lastReversal)
    lastReversal := ma

if ma > lastReversal + thresholdValue
    isRising := true
    lastReversal := ma
else if ma < lastReversal - thresholdValue
    isRising := false
    lastReversal := ma

maColor = isRising ? color.green : color.red

// === TRADE VARIABLES ===
var float tradeHigh = na
var float tradeLow = na
var float shortEntryPrice = na
var bool inLong = false
var bool inShort = false

// === LONG & SHORT CONDITIONS ===
longEntry = sessionActive and isRising and close >= ma * (1 + reversalThresholdPercent / 100)
longReEntry = sessionActive and isRising and not inLong and close <= ma * 1.01

shortEntry = sessionActive and not isRising and close <= ma * (1 - reversalThresholdPercent / 100)
shortReEntry = sessionActive and not inShort and close >= ma * 0.998

// === EXIT CONDITIONS ===
exitLongBelowTop = close < tradeHigh * (1 - percentBelowTop / 100)
exitLongBelowMA = close < ma

exitShortAboveTop = close > tradeHigh * (1 + percentBelowTop / 100)
exitShortAboveMA = close > ma

// === EXECUTE TRADES ===

// === LONG SIDE ===
if not inLong and (longEntry or longReEntry)
    strategy.entry("Long", strategy.long)
    tradeHigh := close
    inLong := true

if inLong
    tradeHigh := math.max(tradeHigh, high)
    if exitLongBelowTop or exitLongBelowMA
        strategy.close("Long")
        reason = exitLongBelowTop ? "Exit Long (Below Top)" : "Exit Long (Below MA)"
        inLong := false

// === SHORT SIDE ===
if allowShorts
    if not inShort and (shortEntry or shortReEntry)
        if close >= ma * 0.996 and close <= ma * 1.002
            strategy.entry("Short", strategy.short)
            tradeHigh := close
            tradeLow := close
            shortEntryPrice := close
            inShort := true

    if inShort
        // Update tradeLow dynamically
        tradeLow := na(tradeLow) ? close : math.min(tradeLow, close)

        // Calculate Stop Levels
        hardStopLossPrice = shortEntryPrice * (1 + stopLossPercent / 100)
        hardStopLossTriggered = high >= hardStopLossPrice

        normalExitPrice1 = tradeLow * (1 + shortProfitPercent / 100)
        normalExitTriggered = close > normalExitPrice1 or close > ma

        // Exit Conditions
        if hardStopLossTriggered
            strategy.close("Short", comment="Hard Stop Loss")
            inShort := false
            tradeLow := na
        else
            if normalExitTriggered
                reason = close > normalExitPrice1 ? "Exit Short (Above Profit %)" : "Exit Short (Above MA)"
                strategy.close("Short", comment=reason)
                inShort := false
                tradeLow := na

// === PLOT MA ===
plot(ma, color=maColor, title="Dynamic Moving Average", linewidth=2)

// === TRADE STATUS BOX ===
var label tradeStatusLabel = na
var color statusColor = color.blue
var string statusText = "No Open Trade"

if inLong
    statusColor := color.green
    statusText := "Long Trade Open"
else if inShort
    statusColor := color.red
    statusText := "Short Trade Open"

if not na(tradeStatusLabel)
    label.delete(tradeStatusLabel)