Multi-Indicator Dynamic Swing Strategy

EMA RSI MACD VOLUME ATR FIBONACCI
Created on: 2025-07-14 10:01:55 Modified on: 2025-07-14 10:01:55
Copy: 2 Number of hits: 220
avatar of ianzeng123 ianzeng123
2
Follow
319
Followers

 Multi-Indicator Dynamic Swing Strategy  Multi-Indicator Dynamic Swing Strategy

Overview

The Multi-Indicator Dynamic Swing Strategy is a comprehensive trading system designed specifically for 4-hour charts, which precisely captures swing opportunities in uptrending markets through the synergistic action of five key technical indicators. This strategy combines the advantages of trend following and pullback entry by using EMA to confirm uptrends, RSI to validate momentum, MACD to confirm direction, volume analysis to strengthen breakout credibility, and Fibonacci retracement levels to find optimal entry points, while incorporating an ATR-based dynamic risk management system to protect capital.

Strategy Principles

The Multi-Indicator Dynamic Swing Strategy is based on a confirmation mechanism involving five complementary indicators:

  1. EMA Trend Filtering: Uses a 50-period Exponential Moving Average (EMA) as the primary trend filter. The strategy only considers long opportunities when price is above the EMA, ensuring that trades align with the main trend direction.

  2. RSI Momentum Confirmation: Requires the Relative Strength Index (RSI) to not only be above 40 but also rising for three consecutive periods, verifying upward price momentum. Additionally, it sets RSI > 70 as an overbought exit condition, effectively mitigating high-level risks.

  3. MACD Bullish Crossover: Provides directional confirmation when the MACD line crosses above the signal line. The strategy employs standard 12/26/9 settings but allows users to customize based on different market characteristics.

  4. Volume Breakout Verification: Identifies whether volume reaches 1.5 times above the 20-period average to confirm the strength and credibility of price breakouts, avoiding false breakout traps.

  5. Fibonacci Retracement Support: Dynamically calculates Fibonacci retracement levels from recent swing highs and lows, providing ideal entry points when price retraces to the 38.2% to 61.8% support zone, enabling low-risk entries in the trend direction.

The risk management system dynamically sets stop-loss (2×ATR below entry price) and profit targets (3×ATR above entry price) based on the 14-period Average True Range (ATR), achieving a reasonable risk-reward ratio of 1:1.5.

Strategy Advantages

  1. Multiple Confirmation Mechanism: Significantly enhances the reliability of trading signals through the collaborative confirmation of five different technical dimensions, reducing interference from false signals and forming a robust filtering system.

  2. Dynamic Adaptability: All indicator parameters can be adjusted according to different market environments and trading instrument characteristics, giving the strategy high flexibility and adaptability.

  3. Precise Entry Timing: By combining trend confirmation with Fibonacci retracement support, the strategy can find entry points in the trend direction with minimal risk and maximum potential return, avoiding the risks of chasing highs.

  4. Risk Management System: The ATR-based dynamic stop-loss and profit-taking settings allow risk control to adjust automatically based on market volatility, maintaining consistent risk-reward characteristics in different volatile environments.

  5. Visualized Decision Support: The strategy provides a clear graphical interface including entry/exit signal markers, condition information tables, and multi-panel indicator displays, greatly enhancing the intuitiveness and convenience of trading decisions.

  6. Comprehensive Alert System: Built-in entry and exit signal alerts ensure traders don’t miss important trading opportunities, improving the timeliness of strategy execution.

Strategy Risks

  1. Over-reliance on Historical Backtesting: Although the strategy may perform excellently in backtesting, changing market conditions may cause future performance to differ from historical backtests. It is recommended to conduct thorough forward testing and small capital verification before live trading.

  2. Parameter Optimization Risk: Parameter settings that overfit specific historical data may cause the strategy to fail in future markets. Excessive optimization should be avoided, maintaining reasonable and robust parameter settings.

  3. Signal Overlap Delay: The condition of all five indicators being satisfied simultaneously may be relatively lagging, potentially missing some profitable opportunities. Consider introducing early warning mechanisms, such as MACD histogram changes or RSI directional changes as advance alerts.

  4. Trend Reversal Risk: The strategy is primarily suitable for markets with clear trends and may produce frequent false signals in ranging or highly volatile markets. Consider adding volatility filters or market state classification modules to mitigate this risk.

  5. Fixed Multiplier Risk: Although ATR is used to dynamically set stop-loss and profit targets, fixed ATR multipliers (2 and 3) may not be suitable for all market environments. Consider dynamically adjusting ATR multipliers in markets with extreme volatility changes.

Strategy Optimization Directions

  1. Adaptive Multiplier Adjustment: ATR multipliers can be dynamically adjusted according to market volatility states, such as using larger multipliers in low-volatility markets and smaller multipliers in high-volatility markets, to optimize risk-reward characteristics. Implementation can be achieved by calculating the standard deviation of historical ATR to determine the current volatility state.

  2. Time Filter Integration: Introduce trading time filters to avoid specific high-volatility or low-efficiency periods, such as during important economic data releases. This can be implemented by checking bar_index and trading time conditions.

  3. Market State Classification: Develop a market state classification module to distinguish between trending and oscillating markets, applying different strategy parameters or trading logic in different market states. This can be implemented through the ADX indicator or the relationship between price and multi-period moving averages.

  4. Dynamic Position Management: Implement a dynamic position management system based on market conditions and signal strength, increasing position size when high-confidence signals appear and reducing position size with weaker signals. This can be achieved by evaluating the strength of conditions satisfied by each indicator.

  5. Partial Profit-Taking Mechanism: Introduce a staged profit-taking mechanism to partially close positions when specific profit targets are reached, both securing partial profits and retaining upside potential. This can be implemented through the qty_percent parameter in the strategy.exit function.

Conclusion

The Multi-Indicator Dynamic Swing Strategy is a comprehensive and robust trading system that provides high-quality long signals through the collaborative work of five dimensions: EMA trend filtering, RSI momentum confirmation, MACD directional verification, volume breakout confirmation, and Fibonacci retracement support. The strategy not only features a reliable signal generation mechanism but is also equipped with an ATR-based dynamic risk management system, suitable for medium to long-term swing traders.

By introducing adaptive multiplier adjustments, time filters, market state classification, dynamic position management, and partial profit-taking mechanisms, the strategy has the potential to further enhance its stability and profitability in various market environments. For investors seeking systematic, clearly defined, and risk-controlled trading methods, the Multi-Indicator Dynamic Swing Strategy provides a worthy consideration.

Strategy source code
/*backtest
start: 2024-07-14 00:00:00
end: 2025-07-12 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © robert-angel
//@version=5
strategy("5-Indicator Swing Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10)

// ===== INPUTS =====
// EMA Settings
ema_length = input.int(50, "EMA Length", minval=1)

// RSI Settings
rsi_length = input.int(14, "RSI Length", minval=1)
rsi_threshold = input.float(40, "RSI Threshold", minval=0, maxval=100)

// MACD Settings
macd_fast = input.int(12, "MACD Fast Length", minval=1)
macd_slow = input.int(26, "MACD Slow Length", minval=1)
macd_signal = input.int(9, "MACD Signal Length", minval=1)

// Volume Settings
volume_multiplier = input.float(1.5, "Volume Spike Multiplier", minval=1.0, step=0.1)
volume_period = input.int(20, "Volume Average Period", minval=1)

// Fibonacci Settings
fib_lookback = input.int(50, "Fibonacci Lookback Period", minval=10)
fib_levels = input.bool(true, "Show Fibonacci Levels")

// Risk Management
atr_length = input.int(14, "ATR Length", minval=1)
stop_loss_atr = input.float(2.0, "Stop Loss ATR Multiple", minval=0.5, maxval=10.0)
take_profit_atr = input.float(3.0, "Take Profit ATR Multiple", minval=1.0, maxval=20.0)

// ===== INDICATOR CALCULATIONS =====

// Calculate ATR for dynamic stop loss and take profit
atr_value = ta.atr(atr_length)

// 1. EMA (50-period)
ema50 = ta.ema(close, ema_length)

// 2. RSI
rsi = ta.rsi(close, rsi_length)
rsi_rising = rsi > rsi[1] and rsi[1] > rsi[2]

// 3. MACD
[macd_line, signal_line, histogram] = ta.macd(close, macd_fast, macd_slow, macd_signal)
macd_bullish_cross = ta.crossover(macd_line, signal_line)

// 4. Volume Analysis
avg_volume = ta.sma(volume, volume_period)
volume_spike = volume > avg_volume * volume_multiplier

// 5. Fibonacci Retracement
// Find recent swing high and low
swing_high = ta.highest(high, fib_lookback)
swing_low = ta.lowest(low, fib_lookback)

// Calculate Fibonacci levels
fib_range = swing_high - swing_low
fib_23_6 = swing_high - (fib_range * 0.236)
fib_38_2 = swing_high - (fib_range * 0.382)
fib_50_0 = swing_high - (fib_range * 0.500)
fib_61_8 = swing_high - (fib_range * 0.618)

// Price near Fibonacci support levels
near_fib_support = close <= fib_38_2 and close >= fib_61_8

// ===== STRATEGY CONDITIONS =====

// Main entry conditions
uptrend = close > ema50
rsi_condition = rsi > rsi_threshold and rsi_rising
macd_condition = macd_bullish_cross
volume_condition = volume_spike
fib_condition = near_fib_support

// Combined long condition
long_condition = uptrend and rsi_condition and macd_condition and volume_condition and fib_condition

// Exit conditions
long_exit = ta.crossunder(close, ema50) or rsi > 70

// ===== STRATEGY EXECUTION =====

// Enter long position
if long_condition and strategy.position_size == 0
    strategy.entry("Long", strategy.long)

// Exit long position
if long_exit and strategy.position_size > 0
    strategy.close("Long")

// Stop Loss and Take Profit using ATR
if strategy.position_size > 0
    stop_price = strategy.position_avg_price - (atr_value * stop_loss_atr)
    profit_price = strategy.position_avg_price + (atr_value * take_profit_atr)
    strategy.exit("Exit", "Long", stop=stop_price, limit=profit_price)

// ===== PLOTTING =====

// Plot EMA
plot(ema50, "EMA 50", color=color.blue, linewidth=2)

// Plot Fibonacci levels
plot(fib_levels ? fib_23_6 : na, "Fib 23.6%", color=color.gray, style=plot.style_line)
plot(fib_levels ? fib_38_2 : na, "Fib 38.2%", color=color.yellow, style=plot.style_line)
plot(fib_levels ? fib_50_0 : na, "Fib 50.0%", color=color.orange, style=plot.style_line)
plot(fib_levels ? fib_61_8 : na, "Fib 61.8%", color=color.red, style=plot.style_line)

// Background color for conditions
bgcolor(uptrend ? color.new(color.green, 95) : color.new(color.red, 95), title="Trend Background")

// Plot entry signals
plotshape(long_condition, style=shape.triangleup, location=location.belowbar, color=color.green, size=size.normal, title="Long Signal")
plotshape(long_exit, style=shape.triangledown, location=location.abovebar, color=color.red, size=size.normal, title="Exit Signal")

// ===== INDICATOR PANELS =====

// RSI Panel
rsi_plot = plot(rsi, "RSI", color=color.purple)
rsi_upper = hline(70, "RSI Upper", color=color.red, linestyle=hline.style_dashed)
rsi_lower = hline(30, "RSI Lower", color=color.green, linestyle=hline.style_dashed)
rsi_mid = hline(50, "RSI Mid", color=color.gray, linestyle=hline.style_dotted)
fill(rsi_upper, rsi_lower, color=color.new(color.gray, 90))

// MACD Panel
macd_histogram_color = histogram > 0 ? color.green : color.red
plot(macd_line, "MACD Line", color=color.blue)
plot(signal_line, "Signal Line", color=color.red)
plot(histogram, "MACD Histogram", color=macd_histogram_color, style=plot.style_histogram)

// Volume Panel
volume_color = volume > avg_volume * volume_multiplier ? color.red : color.gray
plot(volume, "Volume", color=volume_color, style=plot.style_columns)
plot(avg_volume, "Avg Volume", color=color.yellow, linewidth=1)

// ===== ALERTS =====

// Alert conditions
alertcondition(long_condition, "Long Entry", "5-Indicator Swing Strategy: Long Entry Signal")
alertcondition(long_exit, "Long Exit", "5-Indicator Swing Strategy: Long Exit Signal")

// ===== STRATEGY INFORMATION =====

// Create a table to display current conditions
if barstate.islast
    var table info_table = table.new(position.top_right, 2, 7, bgcolor=color.white, border_width=1)
    table.cell(info_table, 0, 0, "Indicator", text_color=color.black, bgcolor=color.gray)
    table.cell(info_table, 1, 0, "Status", text_color=color.black, bgcolor=color.gray)
    
    table.cell(info_table, 0, 1, "Uptrend", text_color=color.black)
    table.cell(info_table, 1, 1, uptrend ? "✓" : "✗", text_color=uptrend ? color.green : color.red)
    
    table.cell(info_table, 0, 2, "RSI > 40 & Rising", text_color=color.black)
    table.cell(info_table, 1, 2, rsi_condition ? "✓" : "✗", text_color=rsi_condition ? color.green : color.red)
    
    table.cell(info_table, 0, 3, "MACD Bullish Cross", text_color=color.black)
    table.cell(info_table, 1, 3, macd_condition ? "✓" : "✗", text_color=macd_condition ? color.green : color.red)
    
    table.cell(info_table, 0, 4, "Volume Spike", text_color=color.black)
    table.cell(info_table, 1, 4, volume_condition ? "✓" : "✗", text_color=volume_condition ? color.green : color.red)
    
    table.cell(info_table, 0, 5, "Fib Support", text_color=color.black)
    table.cell(info_table, 1, 5, fib_condition ? "✓" : "✗", text_color=fib_condition ? color.green : color.red)
    
    table.cell(info_table, 0, 6, "RSI Value", text_color=color.black)
    table.cell(info_table, 1, 6, str.tostring(math.round(rsi, 2)), text_color=color.black)