Multi-Factor Adaptive Swing Trading Strategy: Optimized Risk-Reward System Based on Moving Average Crossovers and Bollinger Band Oscillations

EMA WMA RSI SMA VWAP HEIKIN ASHI ATR Pivot Points VOLUME
Created on: 2025-08-11 09:05:39 Modified on: 2025-08-11 09:05:39
Copy: 2 Number of hits: 217
avatar of ianzeng123 ianzeng123
2
Follow
319
Followers

 Multi-Factor Adaptive Swing Trading Strategy: Optimized Risk-Reward System Based on Moving Average Crossovers and Bollinger Band Oscillations  Multi-Factor Adaptive Swing Trading Strategy: Optimized Risk-Reward System Based on Moving Average Crossovers and Bollinger Band Oscillations

Overview

The Multi-Factor Adaptive Swing Trading Strategy is a comprehensive trading system that combines market structure analysis, momentum indicators, and volatility measurements. Built on Heikin Ashi candlestick technology, the strategy integrates multiple moving averages (EMA, WMA, SMA, VWAP), RSI indicators, and volume confirmation to identify potential trend reversal points and execute high-probability trades. The strategy’s key feature is its utilization of two distinct trading logics (RSI mode and Scalping mode) combined with a fixed risk-reward ratio (default 1:3), allowing it to adapt to different market environments. By using swing highs and lows as stop-loss references, the strategy both protects capital and maximizes potential returns.

Strategy Principles

The core principle of this strategy is to capture market structure change points through multiple indicator confirmations while strictly controlling risk. The specific implementation mechanisms are as follows:

  1. Heikin Ashi Transformation: The strategy first converts standard candlesticks to Heikin Ashi candles to reduce market noise and highlight trend direction. The Heikin Ashi calculation formula is:

    • HA_Close = (Open + High + Low + Close) / 4
    • HA_Open = (Previous HA_Open + Previous HA_Close) / 2
    • HA_High = max(High, max(HA_Open, HA_Close))
    • HA_Low = min(Low, min(HA_Open, HA_Close))
  2. Multiple Moving Average Synthesis: The strategy calculates and synthesizes four different types of 34-period moving averages:

    • 34-period EMA (Exponential Moving Average)
    • 34-period WMA (Weighted Moving Average)
    • 34-period SMA (Simple Moving Average)
    • 34-period VWMA (Volume Weighted Moving Average) The average of these four moving averages is used as a key price reference line.
  3. Dual-Mode Trading Logic:

    • RSI Mode: Uses the crossover of 3-period EMA and 10-period EMA of RSI as the initial signal, combined with high volume confirmation. Buy signals are generated when price is below the moving average and RSI shows an oversold upward cross; sell signals are generated when price is above the moving average and RSI shows an overbought downward cross.
    • Scalping Mode: Uses crossover of 34-period EMA and 34-period WMA as the initial signal, then confirms the trading direction through price breakout of reference highs or lows.
  4. State Management System: The strategy uses state variables (“NEUTRAL”, “WAIT_ENTRY”, “BUY”, “SELL”) to track and manage trading states, avoiding frequent trading and false signals.

  5. Intelligent Stop-Loss and Profit Targets:

    • Stop-loss is set at the most recent swing low (for longs) or swing high (for shorts) after entry
    • Profit target is based on a fixed risk-reward ratio (default 1:3), meaning the potential reward is 3 times the potential risk
    • Additionally, reverse signals also trigger position closing

Strategy Advantages

Through in-depth analysis of the code, this strategy demonstrates the following significant advantages:

  1. Multi-Factor Confirmation Reduces False Signals: Combining moving averages, RSI indicators, volume, and price confirmation greatly reduces the possibility of false breakouts, improving trade quality.

  2. Strong Adaptability: Through two different trading logics (RSI and Scalping), the strategy can adapt to different market environments, operating effectively in both trending and ranging markets.

  3. Clear Risk Management: Adopting a fixed risk-reward ratio and market structure-based stop-loss placement, each trade has clearly defined risk control, avoiding excessive losses caused by subjective judgment.

  4. State Management Reduces Overtrading: By tracking and managing trading states through state variables, the strategy avoids frequent market entries and exits, reducing trading costs and emotional fluctuations.

  5. Heikin Ashi Smoothing: Using Heikin Ashi technology reduces market noise, making trends clearer and helping identify true market turning points.

  6. Flexible Parameter Settings: Key parameters such as swing lookback period and risk-reward ratio can be adjusted according to different markets and personal risk preferences.

  7. Multiple Moving Average Synthesis: By combining four different types of moving averages, the strategy reduces bias that might come from a single indicator, providing a more stable price reference.

Strategy Risks

Despite its sophisticated design, the strategy still has the following potential risks:

  1. Overtrading in Ranging Markets: In sideways markets lacking clear trends, the strategy may generate too many trading signals, leading to frequent market entries and exits and increased trading costs. The solution is to add filtering conditions or pause trading when a ranging market is identified.

  2. Stop-Loss Placement May Be Too Far: Using swing highs and lows as stop-loss placement may in some cases lead to stop-loss positions being too far from the entry point, increasing risk exposure for individual trades. Consider setting a maximum stop-loss distance limit or using ATR multiples to optimize stop-loss placement.

  3. Limitations of Fixed Risk-Reward Ratio: The optimal risk-reward ratio may differ in different market environments. In strong trending markets, a 1:3 risk-reward ratio may be too small; in less volatile markets, it may be difficult to achieve. Consider dynamically adjusting the risk-reward ratio based on market volatility.

  4. Dependence on Historical Swing Points: The strategy’s dependence on historical swing points may produce lag in rapidly changing markets. In severe volatility, past swing points may no longer have reference value. Additional risk control measures are recommended in extreme market conditions.

  5. Lack of Volatility Adaptation Mechanism: The strategy lacks a mechanism to adjust parameters based on market volatility, potentially performing inconsistently in high and low volatility environments. Consider introducing the ATR indicator to dynamically adjust trading parameters.

Strategy Optimization Directions

Based on in-depth analysis of the code, the following are possible optimization directions:

  1. Dynamic Risk-Reward Ratio: Automatically adjust the risk-reward ratio based on market volatility (such as ATR), using smaller ratios in low-volatility environments and larger ratios in high-volatility environments to adapt to different market conditions.

  2. Add Trend Filter: Introduce a longer-period trend filter, only trading in the direction consistent with the main trend to avoid risks from counter-trend trading.

  3. Optimize Moving Average Parameters: The current strategy uses a fixed 34-period setting; consider testing different period settings or using adaptive periods to better suit different market environments.

  4. Introduce Partial Profit Locking Mechanism: When price reaches a certain profit level, move the stop-loss to break-even or lock in partial profits to protect realized gains from market pullbacks.

  5. Add Time Filter: Avoid trading during periods of particularly low market volatility (such as Asian session) or before and after major news releases to reduce unnecessary risk.

  6. Optimize Volume Confirmation Conditions: The current strategy uses a simple volume threshold (1.5 times the 20-period average); consider more complex volume pattern recognition, such as volume trend consistency or sudden volume characteristics.

  7. Add Position Management Module: Dynamically adjust position size based on current market volatility and signal strength, increasing positions on high-conviction signals and reducing positions on ambiguous signals.

  8. Lookback Period Optimization: Conduct comprehensive backtesting on different swing lookback periods to find the parameter settings that perform most stably under various market conditions.

Summary

The Multi-Factor Adaptive Swing Trading Strategy is a comprehensive trading system combining multiple technical indicators and market structure analysis. Its core advantages lie in multiple signal confirmation, flexible trading logic selection, and strict risk management. By reducing market noise through Heikin Ashi technology, using multiple moving averages as price references, and combining RSI and volume confirmation, the strategy can effectively identify potential trend reversal points.

The fixed risk-reward ratio and swing point-based stop-loss placement provide a clear risk control framework but also bring some limitations. By implementing the suggested optimization measures, such as dynamic risk-reward ratio, trend filters, and partial profit locking mechanisms, the strategy can further improve its adaptability and stability.

Most importantly, traders should understand the principles and limitations of this strategy and make necessary adjustments based on their own risk preferences and market observations. There is no perfect strategy, but through continuous optimization and strict risk management, the Multi-Factor Adaptive Swing Trading Strategy can become a powerful weapon in a trader’s toolbox.

Strategy source code
/*backtest
start: 2025-07-11 00:00:00
end: 2025-08-06 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT","balance":5000000}]
*/

//@version=6
strategy("Cnagda Fixed Swing SL & RR 1:3", overlay=true, max_boxes_count=500, max_labels_count=500)
input_strategy = input.string("RSI", "Trade Logic", options=["RSI", "Scalp"])
swing_lookback = input.int(34, "Swing Lookback", minval=5)
rr_multiple = input.int(3, "Risk Reward Multiple", minval=1)

// --- Heikin Ashi Calculation ---
ha_close = (open + high + low + close) / 4
var float ha_open = na
if bar_index == 0
    ha_open := (open + close) / 2
else
    ha_open := (ha_open[1] + ha_close[1]) / 2
ha_high = math.max(high, math.max(ha_open, ha_close))
ha_low = math.min(low, math.min(ha_open, ha_close))

// --- MA/Signal Logic on Heikin Ashi ---
ma1 = ta.ema(ha_close, 34)
ma2 = ta.wma(ha_close, 34)
wma34 = ta.wma(ha_close, 34)
ema34 = ta.ema(ha_close, 34)
sma34 = ta.sma(ha_close, 34)
vwma34 = ta.vwma(ha_close, 34)
ma_sum = (not na(wma34) ? wma34 : 0) + (not na(vwma34) ? vwma34 : 0) + (not na(ema34) ? ema34 : 0) + (not na(sma34) ? sma34 : 0)
ma_avg = ma_sum / 4

// --- Scalp/Swing Logic ---
buySignal = ta.crossover(ma1, ma2)
sellSignal = ta.crossunder(ma1, ma2)
var string scalp_state = "NEUTRAL"
var float refHigh = na
var float refLow = na
if buySignal or sellSignal
    refHigh := ha_high
    refLow := ha_low
    scalp_state := "WAIT_ENTRY"
if (scalp_state == "WAIT_ENTRY" or scalp_state == "SELL") and not na(refHigh) and ha_close > refHigh
    scalp_state := "BUY"
if (scalp_state == "WAIT_ENTRY" or scalp_state == "BUY") and not na(refLow) and ha_close < refLow
    scalp_state := "SELL"
if scalp_state == "BUY" and ha_close < ma_avg
    scalp_state := "NEUTRAL"
    refHigh := na
    refLow := na
if scalp_state == "SELL" and ha_close > ma_avg
    scalp_state := "NEUTRAL"
    refHigh := na
    refLow := na

// --- RSI Logic ---
rsi_val = ta.rsi(ha_close, 14)
rsi_ema_3 = ta.ema(rsi_val, 3)
rsi_ema_10 = ta.ema(rsi_val, 10)
high_vol = volume > ta.sma(volume, 20) * 1.5
bar_is_high = high_vol
prev_bar_is_high = high_vol[1]
any_high_bar = bar_is_high or prev_bar_is_high
_base_rsi_cross_bull = ta.crossover(rsi_ema_3, rsi_ema_10) and any_high_bar
_base_rsi_cross_bear = ta.crossunder(rsi_ema_3, rsi_ema_10) and any_high_bar
rsi_cross_bull = _base_rsi_cross_bull and (ha_close < ma_avg)
rsi_cross_bear = _base_rsi_cross_bear and (ha_close > ma_avg)

// ENTRY LOGIC
var float rsi_signal_high = na
var float rsi_signal_low = na
var int rsi_signal_bar = na
var string rsi_entry_state = ""

if rsi_cross_bull
    rsi_signal_high := high
    rsi_signal_low := na
    rsi_signal_bar := bar_index
    rsi_entry_state := "WAIT ENTRY"
else if rsi_cross_bear
    rsi_signal_low := low
    rsi_signal_high := na
    rsi_signal_bar := bar_index
    rsi_entry_state := "WAIT ENTRY"
else if not na(rsi_signal_bar)
    if not na(rsi_signal_high)
        if close > rsi_signal_high and bar_index > rsi_signal_bar
            rsi_entry_state := "BUY"
            rsi_signal_high := na
            rsi_signal_bar := na
        else
            rsi_entry_state := "WAIT ENTRY"
    else if not na(rsi_signal_low)
        if close < rsi_signal_low and bar_index > rsi_signal_bar
            rsi_entry_state := "SELL"
            rsi_signal_low := na
            rsi_signal_bar := na
        else
            rsi_entry_state := "WAIT ENTRY"
    else
        rsi_entry_state := ""
else
    rsi_entry_state := ""

// --- Swing High/Low (Stoploss reference) ---
swingLow  = ta.pivotlow(ha_low, swing_lookback, swing_lookback)
swingHigh = ta.pivothigh(ha_high, swing_lookback, swing_lookback)

// -- Entry/Exit conditions --
long_condition  = input_strategy == "RSI" ? (rsi_entry_state == "BUY" and rsi_entry_state[1] != "BUY") : (scalp_state == "BUY" and scalp_state[1] != "BUY")
short_condition = input_strategy == "RSI" ? (rsi_entry_state == "SELL" and rsi_entry_state[1] != "SELL") : (scalp_state == "SELL" and scalp_state[1] != "SELL")
exit_long_condition  = input_strategy == "RSI" ? (rsi_entry_state == "SELL" and rsi_entry_state[1] != "SELL") : (scalp_state == "SELL" and scalp_state[1] != "SELL")
exit_short_condition = input_strategy == "RSI" ? (rsi_entry_state == "BUY" and rsi_entry_state[1] != "BUY") : (scalp_state == "BUY" and scalp_state[1] != "BUY")

// --- Final Entry & SL/Target (NO TRAIL) ---
var float sl_long = na
var float sl_short = na
var float tg_long = na
var float tg_short = na

if long_condition and not na(swingLow)
    sl_long := swingLow         // SL = last swing low after entry candle close
    entry_price = close
    risk = entry_price - sl_long
    tg_long := entry_price + (risk * rr_multiple)
    strategy.entry("Long", strategy.long)
    strategy.exit("Long_SL", from_entry="Long", stop=sl_long, limit=tg_long)

if short_condition and not na(swingHigh)
    sl_short := swingHigh      // SL = last swing high after entry candle close
    entry_price = close
    risk = sl_short - entry_price
    tg_short := entry_price - (risk * rr_multiple)
    strategy.entry("Short", strategy.short)
    strategy.exit("Short_SL", from_entry="Short", stop=sl_short, limit=tg_short)

if exit_long_condition
    strategy.close("Long")
if exit_short_condition
    strategy.close("Short")

// --- Visuals (optional, for clarity) ---
barcolor(long_condition ? color.green : short_condition ? color.red : na)
plot(ma_avg, "MA Avg", color=color.blue, linewidth=2)