Trading Strategy Based on Multiple Time Frame EMA Breakthrough and K-line Pattern Combination

Author: ChaoZhang, Date: 2024-02-21 15:00:06



This strategy integrates multiple time frame EMA indicators and K-line pattern judgments to achieve relatively sensitive long-term signal capture and stop-loss exits.

Strategy Principle

The strategy is mainly based on the following indicators for judgment:

  1. EMA: Uses 2 sets of 13 and 21 cycles of EMA to determine the trading signal when price breakthrough.

  2. K-line pattern: Judges the direction of K-line entity and uses it with the EMA indicator to filter false breakthroughs.

  3. Support Resistance: Constructed by the highest points in the last 10 cycles to determine if the breakthrough passes this area to enhance signal reliability.

  4. Rise in Time Division: 120 cycle of close is above open to judge as rise in time division, as an auxiliary judgment.

The rules for generating trading signals are:

  1. Bullish signal: Fast EMA breaks through slow EMA upwards with a Yang line K-line, close short position and open long.

  2. Bearish signal: Fast EMA breaks down through slow EMA with a Yin line K-line, flatten long position.

  3. Stop loss exit: Stop loss exit at current position when reverse signal appears.


  1. Multiple time frame EMA indicators judge the trend more reliably and avoid false breakthroughs.
  2. Combined with K-line entity direction for filtering to identify trends more accurately.
  3. Increase time division judgments and support resistance judgments to ensure signal quality.
  4. Use reverse signals as stop loss to reduce risk of loss.


  1. Risk of invalid breakthroughs resulting in losses. Multi time frame EMA and K-line entity judgments still cannot completely avoid the impact of invalid breakthroughs on the strategy.
  2. Risk of inappropriate parameter selection. Improper settings of EMA cycles, K-line judgment cycles will lead to decline in signal quality.
  3. Risk of failure in support resistance. Historical support resistance failure is common, this will also lead to lack of momentum when signals are generated.
  4. Risk of time division failure. Time division situation changes and cannot completely rely on it for judgment.

The above risks can be mitigated through methods like avoiding excessive optimization, careful parameter selection, strictly controlling position sizing.

Optimization Directions

  1. Introduce machine learning models to assist judgment. Train classification models to judge K-line entity directions for higher accuracy.
  2. Increase adaptive stop loss mechanism like trailing stops or volatility based stops.
  3. Combine sentimental analysis. Introduce certain media opinion judgments to avoid major negative news impact.
  4. Add position sizing management module. Introduce fixed position sizing ratios or fund management based sizing.


The strategy integrates multiple time frame EMA and K-line entity judgments for relatively reliable trend judgments. Auxiliary judgments using support resistance and time division ensure signal quality. Using reverse signals for stop loss can effectively control single stop loss. Future optimizations can be done through introducing machine learning models, adaptive stops, sentimental analysis and position sizing management modules to make the strategy more robust.

start: 2023-02-14 00:00:00
end: 2024-02-20 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

strategy(title='ck - CryptoSniper Longs Only (Strategy)', shorttitle='ck - CryptoSniper Longs (S) v1', overlay=true, precision=2, commission_value=0.25, default_qty_type=strategy.percent_of_equity, pyramiding=0, default_qty_value=100, initial_capital=100)

open_long = 0
close_position = 0

//Candle body resistance Channel-----------------------------//
len = 34
src = input(close, title="Candle body resistance Channel")
out = sma(src, len)
last8h = highest(close, 13)
lastl8 = lowest(close, 13)
bearish = cross(close,out) == 1 and falling(close, 1)
bullish = cross(close,out) == 1 and rising(close, 1)

//-----------------Support and Resistance 
RST = input(title='Support / Resistance length:', defval=10) 
RSTT = valuewhen(high >= highest(high, RST), high, 0)
RSTB = valuewhen(low <= lowest(low, RST), low, 0)

//--------------------Trend colour ema------------------------------------------------// 
src0 = close, len0 = input(13, minval=1, title="EMA 1")
ema0 = ema(src0, len0)
direction = rising(ema0, 2) ? +1 : falling(ema0, 2) ? -1 : 0

//-------------------- ema 2------------------------------------------------//
src02 = close, len02 = input(21, minval=1, title="EMA 2")
ema02 = ema(src02, len02)
direction2 = rising(ema02, 2) ? +1 : falling(ema02, 2) ? -1 : 0

//=============Hull MA//
show_hma = false
hma_src = input(close, title="HullMA Source:")
hma_base_length = input(8, minval=1, title="HullMA Base Length:")
hma_length_scalar = input(5, minval=0, title="HullMA Length Scalar:")
hullma(src, length)=>wma(2*wma(src, length/2)-wma(src, length), round(sqrt(length)))

//============ signal Generator ==================================//
Period=input(title='Period', defval='120')
ch1 =, Period, open)
ch2 =, Period, close)

// Signals//
long = crossover(, Period, close),, Period, open))
short = crossunder(, Period, close),, Period, open))
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])
long_signal = crossover(last_long, last_short) ? 1 : -1
short_signal = crossover(last_short, last_long) ? -1 : 1

if (long_signal == 1)
    strategy.entry("Long Open", strategy.long)

if (short_signal == -1)
    strategy.close("Long Open")
if (long_signal[1] == 1 and short_signal[1] == 1)
    open_long := 1
    close_position := 0

if (short_signal[1] == -1 and long_signal[1] == -1)
    open_long := 0
    close_position := 1

plotshape(open_long == 1, title="Open Long", location=location.belowbar, style=shape.triangleup, size=size.small, color=green, transp=10)
plotshape(close_position == 1, title="Close Long", location=location.abovebar, style=shape.triangledown, size=size.small, color=red, transp=10)
//plot(0, title="Trigger", color=white)