EMA Trend Filter for Ichimoku Trading

EMA Trend Filter
The EMA 100 trend filter ensures we only trade in the direction of the prevailing trend

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

Coming Up Next: In Part 5, we will define our exact entry conditions — when the EMA trend is confirmed AND the Ichimoku cloud gives us a retracement signal. Continue to Part 5 →

Understanding the Kumo Cloud

Understanding the Kumo Cloud
Bullish and bearish cloud formations with price piercing through

Ichimoku Trading Series: Part 3 of 10 | ← Previous | View Full Series

The Cloud (Kumo)

The space between Senkou Span A and Senkou Span B creates the “cloud” — a dynamic zone of support and resistance.

Bullish Cloud (Green)

When Span A > Span B, the cloud is bullish:

Price → [Span A (top)] → [Span B (bottom)]

Bearish Cloud (Red)

When Span B > Span A, the cloud is bearish:

Price → [Span B (top)] → [Span A (bottom)]

What the Cloud Tells Us

1. Trend Direction

  • Price above cloud = Bullish trend
  • Price below cloud = Bearish trend
  • Price inside cloud = Consolidation/uncertainty

2. Support/Resistance Strength

  • Thick cloud = Strong support/resistance
  • Thin cloud = Weak support/resistance, easier breakouts

3. Future Sentiment

The cloud projects forward, showing where support/resistance WILL BE.

Critical: Avoiding Look-Ahead Bias

The Problem

Standard Ichimoku implementations shift Span A and Span B 26 periods into the future. In backtesting, this means your strategy “knows” future support/resistance levels — data leakage!

Our Solution

# We use UNshifted spans for signal logic
span_a_raw = (tenkan_line + kijun_line) / 2.0  # raw (no forward shift)
span_b_raw = (h.rolling(senkou_b).max() + l.rolling(senkou_b).min()) / 2.0  # raw

From the source material:

“I decided to compute the Ichimoku manually for one reason… The Ichimoku by default shifts or reads a bit in the future. This would be a look-ahead bias for our backtesting.”

Cloud Boundaries for Signals

cloud_top = df[["ich_spanA", "ich_spanB"]].max(axis=1)
cloud_bot = df[["ich_spanA", "ich_spanB"]].min(axis=1)

Cloud Twist

When the cloud changes colour (Span A and Span B cross), it signals a potential trend reversal. This is called a Kumo Twist or Senkou Span Cross.

  • Bullish Twist: Span A crosses above Span B → Cloud turns green
  • Bearish Twist: Span A crosses below Span B → Cloud turns red

Coming Up Next: The cloud tells us about support and resistance, but we need a trend filter to avoid false signals. In Part 4, we add our EMA Trend Filter. Continue to Part 4 →

The Five Ichimoku Components Explained

The Five Ichimoku Components
The five sacred lines of Ichimoku Kinko Hyo

Ichimoku Trading Series: Part 2 of 10 | ← Previous | View Full Series

The Sacred Five Lines

Ichimoku Kinko Hyo (一目均衡表) translates to “one glance equilibrium chart” — a complete trading system visible at a glance.

1. Tenkan-sen (Conversion Line) — Period: 9

tenkan = (highest_high_9 + lowest_low_9) / 2

The fastest-moving line, representing short-term momentum.

Trading Insight: When Tenkan crosses above Kijun, it is bullish. Below = bearish.

2. Kijun-sen (Base Line) — Period: 26

kijun = (highest_high_26 + lowest_low_26) / 2

The medium-term equilibrium. Price tends to return to this line.

Trading Insight: Acts as dynamic support/resistance. A flat Kijun indicates consolidation.

3. Senkou Span A (Leading Span A)

span_a = (tenkan + kijun) / 2
# Traditionally plotted 26 periods ahead

The faster of the two cloud boundaries.

4. Senkou Span B (Leading Span B) — Period: 52

span_b = (highest_high_52 + lowest_low_52) / 2
# Traditionally plotted 26 periods ahead

The slower, more stable cloud boundary.

5. Chikou Span (Lagging Span)

chikou = close  # Plotted 26 periods BEHIND

Current price shown lagged for momentum confirmation.

The Parameters

Component Default Period Our Setting
Tenkan 9 9
Kijun 26 26
Senkou B 52 52

These are the original parameters developed for Japanese rice markets in the 1930s. They translate to roughly:

  • 9 = 1.5 trading weeks
  • 26 = 1 trading month
  • 52 = 2 trading months

Code Implementation

# Ichimoku params (defaults)
TENKAN       = 9
KIJUN        = 26
SENKOU_B     = 52

How the Lines Interact

TK Cross (Tenkan/Kijun Cross)

  • Bullish: Tenkan crosses ABOVE Kijun
  • Bearish: Tenkan crosses BELOW Kijun
  • Strongest: When cross happens above the cloud (bullish) or below (bearish)

Chikou Confirmation

  • Bullish: Chikou is above price from 26 periods ago
  • Bearish: Chikou is below price from 26 periods ago

Coming Up Next: In Part 3, we will explore the Kumo Cloud itself — how to read bullish vs bearish clouds and why cloud thickness matters. Continue to Part 3 →

Introduction to Ichimoku Cloud Trading

Ichimoku Cloud Trading Strategy Overview
The Ichimoku Cloud combined with EMA trend filtering creates high-probability trade setups

Ichimoku Trading Series: Part 1 of 10 | View Full Series

What You Will Build

In this 10-part series, you will learn to automate a trading strategy that combines:

  • Ichimoku Cloud (Ichimoku Kinko Hyo) for entry signals
  • EMA 100 as a trend filter
  • ATR-based stop-loss and take-profit management

The strategy achieved ~40% yearly returns in backtests across multiple FX pairs on the 4-hour timeframe, with a 53-69% win rate and controlled drawdowns.

Why This Strategy Works

The core principle is simple but powerful:

  1. Trade WITH the trend — The EMA filter ensures we only take trades in the prevailing market direction
  2. Wait for retracements — The Ichimoku Cloud identifies perfect pullback entries
  3. Enter at the bounce — When price dips INTO the cloud and closes OUTSIDE, the retracement is likely over

Visual Signal Example

Green triangles = Long signals (buy)
Red triangles = Short signals (sell)

The strategy only takes trades that align with both the EMA trend AND the Ichimoku setup.

What Makes This Approach Unique

Problem with Standard Ichimoku

Most Ichimoku implementations suffer from look-ahead bias — they shift the cloud forward in time, which gives misleadingly good backtest results.

Our Solution

We compute the Ichimoku components without forward-shifting the spans, ensuring honest backtesting results that translate to real trading.

Key Backtest Results

Metric Value
Annual Return 28-43%
Win Rate 53-69%
Max Drawdown -6% to -21%
Sharpe Ratio 1.0-1.38
Trades per Year ~13 (selective)

Important Note: The strategy is SELECTIVE — only ~13 trades per year. This is a feature, not a bug. Quality over quantity.

Course Overview

Over the next 10 parts, you will learn:

  • Part 2: The Five Ichimoku Components
  • Part 3: Understanding the Kumo Cloud
  • Part 4: EMA Trend Filter
  • Part 5: Entry Signal Conditions
  • Part 6: Trade Management with ATR
  • Part 7: Python Backtesting Setup
  • Part 8: Building the Strategy Class
  • Part 9: Parameter Optimisation
  • Part 10: Results Analysis & Next Steps

Prerequisites

  • Basic Python knowledge
  • Understanding of candlestick charts
  • Familiarity with trading concepts (SL, TP, R:R)

Coming Up Next: In Part 2, we will dive deep into the five Ichimoku components and understand exactly what each line tells us about market structure. Continue to Part 2 →

Concept Vectors and Analogy in LLMs

LLM Architecture Series – Bonus Lesson. In earlier lessons you saw how tokens become vectors. This article goes deeper into what those vectors mean and how simple arithmetic on them can reveal structure in concepts.

Concept vectors in embedding space

Concept vectors in embedding space, generated with Nano Banana.

(more…)

The Complete LLM Pipeline – Putting It All Together

LLM Architecture Series – Lesson 20 of 20. We have visited every component of the architecture. This lesson ties them together into a single mental model.

By walking through a full end to end example you can see how tokenization, embeddings, attention, MLPs, and the output layer cooperate to produce text.

(more…)

Scaling LLMs – nano-GPT to GPT-3

LLM Architecture Series – Lesson 19 of 20. You now understand the core architecture. Scaling is about what happens when we make models wider, deeper, and train them on more data.

Surprisingly, performance often follows smooth scaling laws, which lets practitioners predict the benefit of using larger models.

(more…)

From Logits to Probabilities – Softmax Output

LLM Architecture Series – Lesson 18 of 20. The output layer produces one logit per token in the vocabulary. Softmax converts these logits into a proper probability distribution.

These probabilities drive sampling strategies such as greedy decoding, top k sampling, and nucleus sampling.

(more…)

The Output Layer and Language Model Head

LLM Architecture Series – Lesson 17 of 20. After many transformer layers, we have a final hidden vector for each position. The output layer turns this into raw scores for every token in the vocabulary.

This linear layer is often called the language model head and is where most parameters of the model live.

(more…)

Stacking Transformer Layers

LLM Architecture Series – Lesson 16 of 20. A single transformer block is powerful, but modern LLMs use many of them in sequence.

Each additional layer can capture longer range patterns and refine the representations produced by earlier layers.

(more…)