
Ichimoku Trading Series: Part 4 of 10 | ← Previous | View Full Series
Why Add an EMA Filter?
The Ichimoku Cloud alone can generate signals in choppy markets. The EMA filter ensures we only trade when a clear trend is established.
The Rule: EMA 100
We use a 100-period Exponential Moving Average as our trend identifier.
Long Trend Conditions
Current candle + at least 5 previous candles ALL trading FULLY ABOVE the EMA
“Fully above” means:
- Open > EMA
- Close > EMA
Short Trend Conditions
Current candle + at least 5 previous candles ALL trading FULLY BELOW the EMA
Why 5+ Candles?
From the source material:
“We need the current candle plus at least five previous candles all trading fully above the EMA curve. Meaning both the open and close of each of these candles are above the line.”
This confirms we are in a sustained trend, not just a momentary spike.
Code Implementation
def MovingAverageSignal(df: pd.DataFrame, back_candles: int = 5) -> pd.DataFrame:
"""
Add a single-column EMA trend signal to the DataFrame.
Rules (evaluated per bar, using *only* current/past data):
+1 (uptrend): For the window [t-back_candles .. t], EVERY bar has
Open > EMA and Close > EMA.
-1 (downtrend): For the same window, EVERY bar has
Open < EMA and Close < EMA.
0 otherwise.
"""
out = df.copy()
# Window size: current bar + back_candles bars behind it
w = int(back_candles) + 1
# Booleans per-bar relative to EMA
above = (out["Open"] > out["EMA"]) & (out["Close"] > out["EMA"])
below = (out["Open"] < out["EMA"]) & (out["Close"] < out["EMA"])
# "All true in the last w bars" via rolling sum == w
above_all = (above.rolling(w, min_periods=w).sum() == w)
below_all = (below.rolling(w, min_periods=w).sum() == w)
# Single signal column
signal = np.where(above_all, 1, np.where(below_all, -1, 0)).astype(int)
out["EMA_signal"] = signal
return out
# Usage: require 7 candles above/below EMA
df = MovingAverageSignal(df, back_candles=7)
Tuning the Parameter
| Setting | Effect |
|---|---|
back_candles=5 |
More signals, less trend confirmation |
back_candles=7 |
Balanced (recommended) |
back_candles=10 |
Fewer signals, stronger trend confirmation |
