Multi-EMA, RSI and Standard Deviation-Based Exit Candlestick Height Breakout Trading Strategy

Author: ChaoZhang, Date: 2024-03-28 16:13:45


Strategy Overview

This strategy combines multiple Exponential Moving Averages (EMAs), the Relative Strength Index (RSI), and a standard deviation-based exit condition to identify potential buy and sell opportunities. It uses short-term (6, 8, 12 days), medium-term (55 days), and long-term (150, 200, 250 days) EMAs to analyze the direction and strength of market trends. The RSI, with configurable buy (30) and sell (70) thresholds, is employed to assess momentum and identify overbought or oversold conditions. The strategy also features a unique exit mechanism that triggers when the closing price reaches a configurable standard deviation range (default 0.5) from the 12-day EMA, providing a method for potentially protecting profits or minimizing losses.

Strategy Principles

  1. Calculate multiple EMAs (6, 8, 12, 55, 100, 150, 200) as visual references to assess market trends.
  2. Determine the highest high and lowest low of the most recent N candles based on user input (3-4 candles).
  3. Entry Long: The current close is higher than the highest high of the recent N candles and above the EMA filter (if enabled).
  4. Entry Short: The current close is lower than the lowest low of the recent N candles and below the EMA filter (if enabled).
  5. Exit Long: The current close is below the 12-day EMA + 0.5 standard deviations, or below the 12-day EMA.
  6. Exit Short: The current close is above the 12-day EMA - 0.5 standard deviations, or above the 12-day EMA.
  7. Use RSI as a supplementary indicator with a default period of 14, an oversold threshold of 30, and an overbought threshold of 70.

Strategy Advantages

  1. Combines both trend-following (multiple EMAs) and momentum (RSI) dimensions for a more comprehensive market analysis perspective.
  2. Unique standard deviation-based exit mechanism can balance protecting profits and controlling risks.
  3. Highly modularized code with key parameters configurable by users for strong flexibility.
  4. Applicable to multiple instruments and timeframes, especially daily stocks and Bitcoin trading.

Risk Analysis

  1. Frequent false signals during market consolidation or early trend reversals, leading to consecutive losses.
  2. Default parameters may not be effective for all market conditions; optimization based on backtesting is necessary.
  3. Relying solely on this strategy for trading is risky; it is recommended to combine with other indicators, support/resistance levels for decision-making.
  4. Slow to respond to trend reversals triggered by sudden major events.

Optimization Directions

  1. Optimize EMA and RSI parameters: Perform exhaustive searches for optimal parameter ranges based on instruments, timeframes, and market characteristics.
  2. Introduce stop-loss and take-profit mechanisms: Set reasonable stop-loss and take-profit levels with reference to volatility indicators like ATR to control single-trade risks.
  3. Implement position sizing: Adjust position sizes based on trend strength (e.g., ADX) or proximity to key support/resistance levels.
  4. Combine with other technical indicators: Such as Bollinger Bands, MACD, moving average crossovers to improve the reliability of entry/exit signals.
  5. Optimize for different market states: Fine-tune parameter combinations for trending, ranging, and transitioning markets separately.


This article proposes a candlestick height breakout trading strategy based on multiple moving averages, RSI, and a standard deviation exit. The strategy analyzes the market from both trend and momentum dimensions while employing a unique standard deviation exit mechanism to capture trend opportunities and manage risks. The strategy logic is clear, rigorous, and the code implementation is concise and efficient. With proper optimization, this strategy has the potential to become a robust intraday medium-to-high frequency trading strategy. However, it is important to note that any strategy has its limitations, and blind usage may introduce risks. Quantitative trading should not be a mechanical “signal-order” process but rather be built upon a grasp of the overall market situation and prudent risk management. Traders also need to continuously evaluate strategy performance, make timely adjustments, and combine it with their own trading styles and risk tolerance to achieve long-term success.

start: 2023-03-22 00:00:00
end: 2024-03-27 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

strategy("Candle Height Breakout with Configurable Exit and Signal Control", shorttitle="CHB Single Signal", overlay=true)

// Input parameters for EMA filter and its length
useEmaFilter = input.bool(true, "Use EMA Filter", group="Entry Conditions")
emaFilterLength =, "EMA Filter Length", minval=1, group="Entry Conditions")
candleCount =, "SamG Configurable Candle Count for Entry", minval=3, maxval=4, step=1, group="Entry Conditions")
exitEmaLength =, "Exit EMA Length", minval=1, group="Exit Conditions", defval=12)
exitStdDevMultiplier = input.float(0.5, "Exit Std Dev Multiplier", minval=0.1, maxval=2.0, step=0.1, group="Exit Conditions")

// State variables to track if we are in a long or short position
var bool inLong = false
var bool inShort = false

// Calculating EMAs with fixed periods for visual reference
ema6 = ta.ema(close, 6)
ema8 = ta.ema(close, 8)
ema12 = ta.ema(close, 12)
ema55 = ta.ema(close, 55)
ema100 = ta.ema(close, 100)
ema150 = ta.ema(close, 150)
ema200 = ta.ema(close, 200)
emaFilter = ta.ema(close, emaFilterLength)
exitEma = ta.ema(close, exitEmaLength)

// Plotting EMAs
plot(ema6, "EMA 6",
plot(ema8, "EMA 8",
plot(ema12, "EMA 12", color=color.yellow)
plot(ema55, "EMA 55",
plot(ema100, "EMA 100",
plot(ema150, "EMA 150", color=color.purple)
plot(ema200, "EMA 200", color=color.fuchsia)
plot(emaFilter, "EMA Filter",
plot(exitEma, "Exit EMA", color=color.gray)

// Calculating the highest and lowest of the last N candles based on user input
highestOfN = ta.highest(high[1], candleCount)
lowestOfN = ta.lowest(low[1], candleCount)

// Entry Conditions with EMA Filter
longEntryCondition = not inLong and not inShort and (close > highestOfN) and (not useEmaFilter or (useEmaFilter and close > emaFilter))
shortEntryCondition = not inLong and not inShort and (close < lowestOfN) and (not useEmaFilter or (useEmaFilter and close < emaFilter))

// Update position state on entry
if (longEntryCondition)
    strategy.entry("Buy", strategy.long, comment="B")
    inLong := true
    inShort := false

if (shortEntryCondition)
    strategy.entry("Sell", strategy.short, comment="S")
    inLong := false
    inShort := true

// Exit Conditions based on configurable EMA and Std Dev Multiplier
smaForExit = ta.sma(close, exitEmaLength)
upperExitBand = smaForExit + exitStdDevMultiplier * ta.stdev(close, exitEmaLength)
lowerExitBand = smaForExit - exitStdDevMultiplier * ta.stdev(close, exitEmaLength)

exitConditionLong = inLong and (close < upperExitBand or close < exitEma)
exitConditionShort = inShort and (close > lowerExitBand or close > exitEma)

// Strategy exits
if (exitConditionLong)
    strategy.close("Buy", comment="Exit")
    inLong := false

if (exitConditionShort)
    strategy.close("Sell", comment="Exit")
    inShort := false

// Visualizing entry and exit points
plotshape(series=longEntryCondition, style=shape.labelup, location=location.belowbar,, size=size.tiny, title="Buy Signal", text="B")
plotshape(series=shortEntryCondition, style=shape.labeldown, location=location.abovebar,, size=size.tiny, title="Sell Signal", text="S")