Ichimoku EA MQL5: Code Tenkan-Kijun Cross with Chikou Filter

Build a non-repainting Ichimoku EA in MQL5 using the Tenkan-Kijun crossover with Chikou Span confirmation. Complete code, buffer handling, edge cases, and.

ichimoku-ea-mql5-code-tenkan-kijun-cross-with

Why Ichimoku Automation Deserves a Second Look

I spent years dismissing Ichimoku as too subjective for automated trading. The cloud, the lagging line, the multiple cross signals — it felt like something only a human could interpret while staring at a chart for hours. Then I watched a colleague's simple Tenkan-sen/Kijun-sen crossover EA grind out consistent small wins on USDJPY hourly over six months. The catch? He added one filter most people skip: Chikou Span confirmation. That EA is still running today, and it forced me to reconsider what I thought I knew about coding Ichimoku in MQL5.

This post walks you through building a non-repainting Ichimoku EA in MQL5 that uses the classic Tenkan-sen/Kijun-sen crossover, but only takes trades when the Chikou Span confirms the move. No repainting, no future-leaking indicators, no magic. Just solid MQL5 code you can adapt for your own testing.

I'll be honest upfront: this isn't a holy grail. The strategy has clear weaknesses — it's inherently lagging, it struggles in choppy sideways markets, and the Chikou filter will sometimes keep you out of strong trends. But for a certain type of trader who values consistency over home runs, it's worth exploring. I've personally seen this approach work well on trend-following pairs like USDJPY and AUDNZD, and fail miserably on EURGBP during range-bound sessions.

Understanding the Strategy: Tenkan-Kijun Cross with Chikou Filter

If you're reading this, you probably already know the basics of Ichimoku Kinko Hyo. But let's be precise about what we're automating, because the details matter when you're writing code that needs to execute trades without hesitation.

  • Tenkan-sen (Conversion Line): (9-period high + 9-period low) / 2. Measures short-term momentum. Think of it as a fast moving average that reacts quickly to price changes. On a 1-hour chart, this looks back 9 hours — roughly one trading session.
  • Kijun-sen (Base Line): (26-period high + 26-period low) / 2. Measures medium-term momentum. Slower, more reliable as a trend gauge. On H1, that's about a week and a half of trading.
  • Chikou Span (Lagging Span): Current closing price plotted 26 periods back. Confirms the trend direction by showing where price was relative to where it is now.
  • Senkou Span A/B (Cloud): Future projections. We won't use these for entry signals in this EA, though you could add them later as a volatility filter or trend confirmation.

The classic signal: when Tenkan-sen crosses above Kijun-sen, it's a buy signal. Cross below, sell. But alone, this generates too many false signals in ranging markets. I've seen backtests where the raw cross alone produces a win rate around 35-40% on EURUSD H1 — not sustainable. The Chikou Span filter adds a simple check: price should be above the Chikou Span (which is just price plotted 26 bars ago) for buys, and below for sells. In other words, the current close must be higher than the close from 26 periods ago — a basic momentum test that keeps you out of counter-trend moves.

Why this works for automation: All three components are computed from historical price data. No repainting, no future bars. The values you see on bar close are final. That's critical for backtesting reliability. Compare this to an indicator that repaints — you'd never know if your backtest results were real or just noise. I once wasted two weeks on a "ZigZag breakout" EA that looked amazing in the tester, only to discover the ZigZag repainted. Never again.

Coding the Ichimoku EA in MQL5: Step by Step

Let's get into the MQL5 code. I'll assume you know how to create a new Expert Advisor in MetaEditor and have basic familiarity with MQL5 syntax. If not, open MetaEditor, go to File > New > Expert Advisor, and start from the template. We'll replace the boilerplate with our logic. I'm going to show you the exact code I use on my demo account — no shortcuts, no placeholder comments that don't compile.

Prerequisites and Setup

You need the built-in iIchimoku indicator handle. MQL5 provides it natively — no external includes needed. We'll also use CopyBuffer to pull the latest values for Tenkan-sen, Kijun-sen, and Chikou Span. Remember: Chikou Span in MQL5's Ichimoku buffer is the line plotted 26 bars back. To get its current value, you actually need to look at the buffer value 26 bars ago. I'll show you the correct offset — this is where most traders mess up and get garbage signals.

One more thing: you'll need to declare your indicator handle and arrays in the global scope. Put these at the top of your EA, right after the input parameters:

//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
int ichimokuHandle;
double tenkanBuffer[], kijunBuffer[], chikouBuffer[];

Input Parameters

Here's the input block I use. Adjust for your own risk tolerance, but keep the Ichimoku periods standard unless you have a strong reason to change them. I've seen traders tweak Tenkan to 7 and Kijun to 30, but that usually just curve-fits to historical data. The standard 9/26/52 periods come from Goichi Hosoda's original work — they're based on Japanese trading calendar conventions, not arbitrary numbers.

//+------------------------------------------------------------------+
//| Input parameters                                                 |
//+------------------------------------------------------------------+
input double   Lots             = 0.01;        // Fixed lot size
input int      TenkanPeriod     = 9;           // Tenkan-sen period
input int      KijunPeriod      = 26;          // Kijun-sen period
input int      SenkouSpanBPeriod= 52;          // Senkou Span B period (unused but required)
input int      ChikouShift      = 26;          // Chikou shift (standard)
input double   StopLoss         = 200;         // Stop loss in points
input double   TakeProfit       = 400;         // Take profit in points
input int      MagicNumber      = 202401;      // Unique EA ID
input bool     UseChikouFilter  = true;        // Enable Chikou confirmation

Notice SenkouSpanBPeriod is required by iIchimoku even if we don't use it. MQL5 won't complain if you set it to 52. Also, ChikouShift is always 26 in standard Ichimoku — don't change it unless you know exactly what you're doing. Changing it breaks the mathematical relationship between the lines.

Let me also note: the StopLoss and TakeProfit values are in points, not pips. On a 5-digit broker, 200 points = 20 pips. Adjust accordingly. I typically start with a 1:2 risk-reward ratio and tune from there.

Initialization and Indicator Handle

In OnInit(), we create the Ichimoku handle. Always check for INVALID_HANDLE — I've seen EAs crash silently when the handle fails, and you don't want that in production:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   ichimokuHandle = iIchimoku(_Symbol, _Period, TenkanPeriod, KijunPeriod, SenkouSpanBPeriod);
   if(ichimokuHandle == INVALID_HANDLE)
   {
      Print("Failed to create Ichimoku handle. Error: ", GetLastError());
      return(INIT_FAILED);
   }
   Print("Ichimoku EA initialized successfully. Handle: ", ichimokuHandle);
   return(INIT_SUCCEEDED);
}

Don't forget the OnDeinit() function — release the handle to avoid memory leaks. This is especially important if you're running multiple EAs simultaneously:

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   if(ichimokuHandle != INVALID_HANDLE)
      IndicatorRelease(ichimokuHandle);
}

Getting Current Indicator Values

This is where most MQL5 Ichimoku code goes wrong. The iIchimoku returns an array with 7 buffers. The buffer indices are:

Buffer IndexIndicator LineNotes
0Tenkan-senCurrent bar value at index 0
1Kijun-senCurrent bar value at index 0
2Senkou Span APlotted 26 bars ahead; not used here
3Senkou Span BPlotted 26 bars ahead; not used here
4Chikou SpanValue at index 0 is the close from 26 bars ago

To check the crossover, we need Tenkan-sen and Kijun-sen values for the current bar (index 0) and the previous bar (index 1). For Chikou Span confirmation, we compare current close with the Chikou Span value at index 0 — which is actually the close 26 bars ago. Here's the function I use to pull all the data cleanly:

//+------------------------------------------------------------------+
//| Get Ichimoku values for current and previous bar                 |
//+------------------------------------------------------------------+
bool GetIchimokuValues(double &tenkan[], double &kijun[], double &chikou[])
{
   ArraySetAsSeries(tenkan, true);
   ArraySetAsSeries(kijun, true);
   ArraySetAsSeries(chikou, true);
   
   if(CopyBuffer(ichimokuHandle, 0, 0, 2, tenkan) < 2)
   {
      Print("Failed to copy Tenkan buffer. Error: ", GetLastError());
      return false;
   }
   if(CopyBuffer(ichimokuHandle, 1, 0, 2, kijun) < 2)
   {
      Print("Failed to copy Kijun buffer. Error: ", GetLastError());
      return false;
   }
   if(CopyBuffer(ichimokuHandle, 4, 0, 1, chikou) < 1)
   {
      Print("Failed to copy Chikou buffer. Error: ", GetLastError());
      return false;
   }
   
   return true;
}

Notice I'm only requesting 1 element for Chikou — we only need the current value for comparison. Requesting more is wasteful and can slow down the EA on tick-heavy pairs like GBPJPY. Also, note that I'm using ArraySetAsSeries to reverse the array indexing. This makes index 0 the most recent bar, which is more intuitive for crossover detection.

Entry Logic: The Crossover with Chikou Filter

Now the core. In OnTick(), we check for a new bar (to avoid multiple signals on the same bar), then evaluate. This is the heart of the EA, so read it carefully:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Only check on new bar
   static datetime lastBarTime = 0;
   if(Time[0] == lastBarTime) return;
   lastBarTime = Time[0];
   
   double tenkan[], kijun[], chikou[];
   if(!GetIchimokuValues(tenkan, kijun, chikou)) return;
   
   double currentClose = iClose(_Symbol, _Period, 0);
   double previousClose = iClose(_Symbol, _Period, 1);
   
   // Check for open positions
   if(PositionSelect(_Symbol)) return; // Only one trade at a time
   
   // Buy signal: Tenkan crosses above Kijun
   if(tenkan[1] <= kijun[1] && tenkan[0] > kijun[0])
   {
      if(UseChikouFilter)
      {
         // Chikou confirmation: current close must be above Chikou (close 26 bars ago)
         if(currentClose <= chikou[0]) return;
      }
      // Execute buy
      OpenBuy();
   }
   // Sell signal: Tenkan crosses below Kijun
   else if(tenkan[1] >= kijun[1] && tenkan

Want to build your own version?

Recreate similar entry logic, risk rules, and filters in TradingBotMaker—no MQL coding. Start free.

Community

Clap for the article and open comments only when you want to read them.

0 claps0 comments

Related articles