Multi-Timeframe Multi-Indicator Dynamic Breakout Quantitative Trading Strategy

EMA SMA RSI ATR 突破策略 时间过滤 追踪止损 动态风险管理
Created on: 2025-08-04 11:57:30 Modified on: 2025-08-04 11:57:30
Copy: 0 Number of hits: 241
avatar of ianzeng123 ianzeng123
2
Follow
319
Followers

 Multi-Timeframe Multi-Indicator Dynamic Breakout Quantitative Trading Strategy  Multi-Timeframe Multi-Indicator Dynamic Breakout Quantitative Trading Strategy

Overview

The Multi-Timeframe Multi-Indicator Dynamic Breakout Quantitative Trading Strategy is a high-performance trading system designed for high-frequency scalping. Developed using Pine Script 5, this strategy combines multiple technical indicators and time filtering capabilities to identify market breakout signals and execute rapid trades. The core principle involves validating trades through multiple indicators such as EMA, SMA, and RSI, coupled with price breakout detection and ATR-based dynamic risk management, to capture short-term opportunities within specific trading sessions. The strategy calculates in real-time for each price movement (calc_on_every_tick=true), making it particularly suitable for 1-5 minute timeframes, and can be automated through PineConnector integration with MetaTrader 5.

Strategy Principle

The core logic of this strategy is based on a price breakout system with multiple confirmation conditions, implemented as follows:

  1. Technical Indicator Combination:

    • Fast EMA (34 periods) and slow EMA (63 periods) to determine trend direction
    • SMA (34 periods) as a price filter
    • RSI (14 periods) to identify overbought/oversold areas
    • ATR (14 periods) to calculate dynamic stop-loss and take-profit levels
  2. Breakout Detection Logic:

    • Identifies the highest price within N periods (default 1) as resistance
    • Identifies the lowest price within N periods (default 1) as support
    • Triggers a long signal when price breaks above resistance and other conditions are met
    • Triggers a short signal when price breaks below support and other conditions are met
  3. Multiple Confirmation Conditions:

    • Long conditions: Price breaks above resistance + Fast EMA above slow EMA + RSI not overbought + Price above SMA
    • Short conditions: Price breaks below support + Fast EMA below slow EMA + RSI not oversold + Price below SMA
  4. Time Filtering System:

    • Implements 4 customizable trading sessions for flexible trading windows
    • Optimized time calculation algorithm converting time to cumulative minutes for efficient processing
  5. Dynamic Risk Management:

    • ATR-based dynamic stop-loss, default at 3x ATR
    • ATR-based dynamic take-profit targets, default at 3x ATR
    • Optional trailing stop functionality that automatically adjusts stop positions based on market volatility
  6. Performance Optimization Design:

    • Pre-calculated constants to reduce repetitive calculations
    • Cached indicator results to improve processing speed
    • Array storage for time filter settings for efficient handling

Strategy Advantages

This strategy offers the following significant advantages:

  1. High-Speed Execution Capability: Through the calc_on_every_tick=true setting, it can respond immediately to each price movement, making it particularly suitable for high-frequency trading environments. The code employs constant pre-calculation and indicator caching techniques to further enhance execution speed.

  2. Multiple Confirmation Mechanism: Combines various indicators including EMA, SMA, and RSI to validate trading signals, significantly reducing false breakout risks. This confirmation system ensures positions are only opened when multiple conditions are simultaneously met, improving trade quality.

  3. Flexible Time Filtering: Through four customizable trading sessions, traders can focus on high-liquidity and high-volatility market periods while avoiding low-activity and unstable market conditions.

  4. Dynamic Risk Management: ATR-based dynamic stop-loss and take-profit targets enable the strategy to automatically adjust risk parameters according to market volatility, adapting to different market conditions.

  5. Complete Automation Support: Integration with MT5 via PineConnector achieves fully automated trading, reducing manual intervention and emotional impact. The code includes a complete alert system supporting fast execution mode.

  6. Resource Usage Optimization: Through pre-calculated constants and cached indicator results, computational resource consumption is effectively reduced, ensuring efficient operation in real-time trading environments.

  7. Visualization Decision Support: The strategy includes built-in performance metric display panels and position markers, providing intuitive visualization of trading status and signals to assist manual monitoring and decision-making.

Strategy Risks

Despite its many advantages, this strategy still presents the following risks and challenges:

  1. High-Frequency Trading Specific Risks: In high-frequency trading environments, slippage, latency, and transaction costs can significantly impact actual trading results. While the code implements a fast execution mode, execution speed in real trading environments may still be limited by trading platforms and brokers.

  2. False Breakout Traps: Despite using multiple confirmation mechanisms, false breakout signals may still be triggered in highly volatile markets, leading to unnecessary trading losses. This risk is particularly significant when parameters are improperly set or market conditions change rapidly.

  3. Over-Optimization Risk: The strategy involves multiple parameters (EMA, SMA, RSI period settings, etc.), creating a risk of curve-fitting that may lead to poor performance in live trading.

  4. Time Filtering Limitations: While time filtering can avoid inefficient trading sessions, it may also miss favorable trading opportunities outside specific periods, especially during major market events or news releases.

  5. Limitations of ATR-Based Risk Control: In extreme market conditions, ATR-based stop-loss and take-profit targets may be insufficient to handle sudden large fluctuations, causing stop-loss failures or premature profit-taking.

Risk Mitigation Measures: - Thorough backtesting and demo trading before live implementation - Adjusting parameter settings for different market conditions, especially ATR multiples and indicator periods - Consider adding additional market state filters, such as volatility indicators or volume conditions - Implementing money management rules to limit per-trade risk - Regular monitoring and evaluation of strategy performance, with timely adjustments based on market changes

Strategy Optimization Directions

Based on code analysis, the following are potential areas for further strategy optimization:

  1. Dynamic Parameter Adaptation:

    • Implement dynamic adjustment of EMA, SMA, RSI and other indicator parameters, automatically optimizing based on market state
    • Consider introducing machine learning algorithms for parameter adaptation to improve strategy adaptability
  2. Market State Classification:

    • Add market state recognition module to distinguish between trending and ranging markets
    • Apply different trading logic and risk parameters based on different market states
  3. Enhanced Filtering System:

    • Introduce volume indicators as additional filtering conditions to avoid false breakouts in low-liquidity environments
    • Add volatility filters to pause trading during excessive or insufficient volatility conditions
  4. Stop-Loss Strategy Optimization:

    • Implement more sophisticated stop-loss strategies, such as intelligent stops based on support/resistance levels
    • Add partial profit-taking functionality to allow scaling out of positions to lock in partial profits
  5. Signal Quality Assessment:

    • Develop a signal strength scoring system to rate signal quality based on multiple factors
    • Dynamically adjust position size based on signal strength for more refined money management
  6. Drawdown Control:

    • Add maximum drawdown control mechanisms to pause trading when consecutive losses reach thresholds
    • Implement profit protection mechanisms to ensure not returning to losses from profitable states
  7. Computational Efficiency Optimization:

    • Further optimize computation-intensive operations, such as using lookup tables to replace repetitive calculations
    • Implement more efficient time filtering algorithms to reduce per-bar computational burden

These optimization directions not only can improve the strategy’s performance and stability but also enhance its ability to adapt to different market conditions, achieving more sustainable long-term profitability.

Summary

The Multi-Timeframe Multi-Indicator Dynamic Breakout Quantitative Trading Strategy is a comprehensive high-frequency trading system designed for short-term traders. By combining multiple technical indicators, price breakout recognition, time filtering, and dynamic risk management, it establishes a complete trading framework. Its core advantages lie in high-speed execution capability, multiple confirmation mechanisms, and flexible automation support, making it particularly suitable for application on short timeframes in volatile assets.

The strategy’s main technical features include EMA crossovers for trend determination, SMA as a price filter, RSI to avoid trading in overbought/oversold areas, and ATR-based dynamic risk management. The time filtering system and PineConnector integration further enhance the strategy’s practicality and flexibility.

While the strategy faces challenges specific to high-frequency trading and false breakout traps, these risks can be effectively controlled through proper risk management and parameter optimization. Future optimization directions include parameter adaptation, market state classification, enhanced filtering systems, and intelligent stop-loss strategies, which will further improve the strategy’s robustness and profitability.

For traders seeking an edge in short-term trading, this strategy provides a technically advanced, logically rigorous quantitative trading solution, particularly suitable for users interested in high-speed trading who wish to improve trading efficiency through automation technology.

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

//@version=5
strategy("Scalper TURBO", overlay=true, initial_capital=1000, 
         default_qty_type=strategy.percent_of_equity, default_qty_value=50,
         calc_on_every_tick=true, process_orders_on_close=false)

// ==================== PERFORMANCE OPTIMIZATIONS ====================
// Pre-calculate constants to avoid repeated calculations
const int MINUTES_PER_HOUR = 60

// ==================== INPUT PARAMETERS ====================
// Technical Parameters
emaFastLen    = input.int(34, "EMA Rápida", minval=1)
emaSlowLen    = input.int(63, "EMA Lenta", minval=1)
smaLen        = input.int(34, "SMA Filtro", minval=1)
rsiLen        = input.int(14, "Periodo RSI", minval=1)
rsiOverbought = input.int(70, "RSI Sobrecompra", minval=1, maxval=100)
rsiOversold   = input.int(30, "RSI Sobreventa", minval=1, maxval=100)
breakoutPeriod = input.int(1, "Periodos para Breakout", minval=1)
atrLen        = input.int(14, "Periodo ATR", minval=1)
atrMultSL     = input.float(3, "Multiplicador ATR Stop-Loss", step=0.1)
atrMultTrail  = input.float(3, "Multiplicador ATR Trailing Stop", step=0.1)

// ==================== TIME FILTER SETTINGS ====================
var g_timefilters = "Time Filters"

// Time Filter Arrays for faster processing
useTimeFilter = array.new_bool(4)
startHour = array.new_int(4)
startMin = array.new_int(4)
endHour = array.new_int(4)
endMin = array.new_int(4)

// Time Filter 1
array.set(useTimeFilter, 0, input.bool(false, "Enable Time Filter 1", group=g_timefilters))
array.set(startHour, 0, input.int(9, "Start Hour", minval=0, maxval=23, group=g_timefilters, inline="tf1start"))
array.set(startMin, 0, input.int(0, "Start Minute", minval=0, maxval=59, group=g_timefilters, inline="tf1start"))
array.set(endHour, 0, input.int(11, "End Hour", minval=0, maxval=23, group=g_timefilters, inline="tf1end"))
array.set(endMin, 0, input.int(30, "End Minute", minval=0, maxval=59, group=g_timefilters, inline="tf1end"))

// Time Filter 2
array.set(useTimeFilter, 1, input.bool(false, "Enable Time Filter 2", group=g_timefilters))
array.set(startHour, 1, input.int(13, "Start Hour", minval=0, maxval=23, group=g_timefilters, inline="tf2start"))
array.set(startMin, 1, input.int(30, "Start Minute", minval=0, maxval=59, group=g_timefilters, inline="tf2start"))
array.set(endHour, 1, input.int(15, "End Hour", minval=0, maxval=23, group=g_timefilters, inline="tf2end"))
array.set(endMin, 1, input.int(0, "End Minute", minval=0, maxval=59, group=g_timefilters, inline="tf2end"))

// Time Filter 3
array.set(useTimeFilter, 2, input.bool(false, "Enable Time Filter 3", group=g_timefilters))
array.set(startHour, 2, input.int(16, "Start Hour", minval=0, maxval=23, group=g_timefilters, inline="tf3start"))
array.set(startMin, 2, input.int(0, "Start Minute", minval=0, maxval=59, group=g_timefilters, inline="tf3start"))
array.set(endHour, 2, input.int(18, "End Hour", minval=0, maxval=23, group=g_timefilters, inline="tf3end"))
array.set(endMin, 2, input.int(30, "End Minute", minval=0, maxval=59, group=g_timefilters, inline="tf3end"))

// Time Filter 4
array.set(useTimeFilter, 3, input.bool(false, "Enable Time Filter 4", group=g_timefilters))
array.set(startHour, 3, input.int(20, "Start Hour", minval=0, maxval=23, group=g_timefilters, inline="tf4start"))
array.set(startMin, 3, input.int(0, "Start Minute", minval=0, maxval=59, group=g_timefilters, inline="tf4start"))
array.set(endHour, 3, input.int(22, "End Hour", minval=0, maxval=23, group=g_timefilters, inline="tf4end"))
array.set(endMin, 3, input.int(30, "End Minute", minval=0, maxval=59, group=g_timefilters, inline="tf4end"))

// ==================== PINECONNECTOR SETTINGS ====================
var g_connector = "PineConnector Settings"
pcID = input.string(" ", "Pine Connector ID", group=g_connector)
symbolName = input.string("XAUUSD", "Symbol Name", tooltip="Symbol exactly as it appears in your MT5", group=g_connector)
lotSize = input.float(0.01, "Lot Size", step=0.01, group=g_connector)
enableRealTrading = input.bool(true, "Enable Real Trading", group=g_connector)
useFastExecution = input.bool(true, "Use Fast Execution Mode", group=g_connector)
showLabels = input.bool(true, "Show Info Labels", group=g_connector)

// Risk Management
useStopLoss = input.bool(true, "Use Stop Loss", group=g_connector)
useTakeProfit = input.bool(true, "Use Take Profit", group=g_connector)
useTrailingStop = input.bool(false, "Use Trailing Stop", group=g_connector)
stopLossATRMult = input.float(3, "Stop Loss ATR Multiple", step=0.1, group=g_connector)
takeProfitATRMult = input.float(3, "Take Profit ATR Multiple", step=0.1, group=g_connector)
trailingStopATRMult = input.float(3, "Trailing Stop ATR Multiple", step=0.1, group=g_connector)

// ==================== OPTIMIZED TIME FILTER FUNCTION ====================
// Cache current time components
currentHour = hour(time)
currentMin = minute(time)
currentTimeMinutes = currentHour * MINUTES_PER_HOUR + currentMin

// Optimized time check function
isTimeAllowed() =>
    anyEnabled = false
    timeOK = false
    
    for i = 0 to 3
        if array.get(useTimeFilter, i)
            anyEnabled := true
            startTimeMin = array.get(startHour, i) * MINUTES_PER_HOUR + array.get(startMin, i)
            endTimeMin = array.get(endHour, i) * MINUTES_PER_HOUR + array.get(endMin, i)
            
            inRange = startTimeMin <= endTimeMin ? 
                     (currentTimeMinutes >= startTimeMin and currentTimeMinutes <= endTimeMin) :
                     (currentTimeMinutes >= startTimeMin or currentTimeMinutes <= endTimeMin)
            
            if inRange
                timeOK := true
                break
    
    not anyEnabled or timeOK

// ==================== CACHED INDICATOR CALCULATIONS ====================
// Calculate indicators only once per bar
emaFast = ta.ema(close, emaFastLen)
emaSlow = ta.ema(close, emaSlowLen)
sma34   = ta.sma(close, smaLen)
rsi     = ta.rsi(close, rsiLen)
atr     = ta.atr(atrLen)

// Support/Resistance with caching
var float resistenciaReciente = na
var float soporteReciente = na
if barstate.isconfirmed
    resistenciaReciente := ta.highest(high, breakoutPeriod)[1]
    soporteReciente := ta.lowest(low, breakoutPeriod)[1]

// ==================== SIGNAL CONDITIONS ====================
// Pre-calculate all conditions
tendenciaAlcista = emaFast > emaSlow
tendenciaBajista = emaFast < emaSlow
rsiNotOverbought = rsi < rsiOverbought
rsiNotOversold = rsi > rsiOversold
priceAboveSMA = close > sma34
priceBelowSMA = close < sma34
timeAllowed = isTimeAllowed()

// Breakout conditions
breakoutUp = close > resistenciaReciente
breakoutDown = close < soporteReciente

// Final entry conditions - simplified logic
longSignal = breakoutUp and tendenciaAlcista and rsiNotOverbought and priceAboveSMA and timeAllowed
shortSignal = breakoutDown and tendenciaBajista and rsiNotOversold and priceBelowSMA and timeAllowed

// ==================== POSITION MANAGEMENT ====================
// Efficient position tracking
var int currentPosition = 0  // 1 = long, -1 = short, 0 = flat
var bool positionChanged = false
var string pendingAlert = ""

// Detect position changes
newLong = longSignal and currentPosition <= 0
newShort = shortSignal and currentPosition >= 0

// ==================== OPTIMIZED ALERT SYSTEM ====================
// Pre-build alert components for faster execution
stopPips = useStopLoss ? str.tostring(math.round(atr * stopLossATRMult * 100)) : ""
tpPips = useTakeProfit ? str.tostring(math.round(atr * takeProfitATRMult * 100)) : ""
trailPips = useTrailingStop ? str.tostring(math.round(atr * trailingStopATRMult * 100)) : ""

// Build risk management string once
riskParams = useStopLoss ? ",sl=" + stopPips : ""
riskParams += useTakeProfit ? ",tp=" + tpPips : ""
riskParams += useTrailingStop ? ",trailingstop=" + trailPips : ""

// ==================== FAST EXECUTION MODE ====================
if enableRealTrading
    // LONG ENTRY
    if newLong
        // Close short first if needed
        if currentPosition < 0
            alert(pcID + ",closeshort," + symbolName, alert.freq_once_per_bar)
        
        // Enter long
        strategy.entry("Long", strategy.long)
        longAlert = pcID + ",buy," + symbolName + ",risk=" + str.tostring(lotSize) + riskParams
        alert(longAlert, useFastExecution ? alert.freq_once_per_bar : alert.freq_once_per_bar_close)
        currentPosition := 1
    
    // SHORT ENTRY
    else if newShort
        // Close long first if needed
        if currentPosition > 0
            alert(pcID + ",closelong," + symbolName, alert.freq_once_per_bar)
        
        // Enter short
        strategy.entry("Short", strategy.short)
        shortAlert = pcID + ",sell," + symbolName + ",risk=" + str.tostring(lotSize) + riskParams
        alert(shortAlert, useFastExecution ? alert.freq_once_per_bar : alert.freq_once_per_bar_close)
        currentPosition := -1
else
    // Backtest mode
    if newLong
        strategy.entry("Long", strategy.long)
        currentPosition := 1
    else if newShort
        strategy.entry("Short", strategy.short)
        currentPosition := -1

// ==================== STOP LOSS MANAGEMENT ====================
// Calculate stops only when in position
if currentPosition != 0
    if currentPosition > 0
        stopLong = strategy.position_avg_price - atr * atrMultSL
        strategy.exit("Exit Long", "Long", stop=stopLong, trail_points=atr * atrMultTrail, trail_offset=atr * atrMultTrail)
    else
        stopShort = strategy.position_avg_price + atr * atrMultSL
        strategy.exit("Exit Short", "Short", stop=stopShort, trail_points=atr * atrMultTrail, trail_offset=atr * atrMultTrail)

// Detect exits
if strategy.position_size == 0 and currentPosition != 0
    if enableRealTrading
        exitAlert = currentPosition > 0 ? pcID + ",closelong," + symbolName : pcID + ",closeshort," + symbolName
        alert(exitAlert, alert.freq_once_per_bar)
    currentPosition := 0