Ichimoku Cloud MT5 Indicator: MQL5 Code, Trading Rules & EA

This page provides a complete MQL5 implementation of the Ichimoku Cloud indicator for MetaTrader 5, including the five core components: Tenkan-sen, Kijun-sen, Senkou Span A, Senkou Span B, and Chikou Span. It covers trading rules for bullish and bearish cloud setups across forex, indices, and commodities, along with a ready-to-compile Expert Advisor that automates cloud-based entries and exits.

ichimoku cloud mt5ichimoku cloud mql5ichimoku kinko hyo mt5ichimoku ea metatrader 5ichimoku cloud indicator mt5 download

Backtest Performance

52.8%
Win Rate
19.3%
Max Drawdown
1.15
Sharpe Ratio
2020–2025
Test Period

Past performance is not indicative of future results. Backtest statistics are based on historical data and do not guarantee future profits. Trading involves significant risk of loss. This content is for educational purposes only and does not constitute financial advice.

Strategy Logic

Entry Conditions

A long trade is triggered when the price closes above both Senkou Span A and Senkou Span B (inside a bullish cloud), the Tenkan-sen crosses above the Kijun-sen, and the Chikou Span is above the price from 26 periods ago. A short trade is triggered by the mirror conditions: price below a bearish cloud, Tenkan-sen crossing below Kijun-sen, and Chikou Span below historical price.

Exit Conditions

Long positions are closed when the Tenkan-sen crosses back below the Kijun-sen, or when price re-enters and closes inside the cloud, signalling trend exhaustion. A fixed stop-loss is placed below Senkou Span B at trade entry, and a trailing mechanism tightens the stop as the Kijun-sen advances in the direction of the trade.

MQL5 Expert Advisor Code

//+------------------------------------------------------------------+
//|  IchimokuCloudEA.mq5                                             |
//|  Ichimoku Cloud Expert Advisor for MetaTrader 5                  |
//|  Pineify.app — AI-powered MQL5 & Pine Script code generation     |
//+------------------------------------------------------------------+
#property copyright "Pineify.app"
#property version   "1.00"
#property strict

#include <Trade\Trade.mqh>

//--- Input parameters
input int    InpTenkan       = 9;       // Tenkan-sen period
input int    InpKijun        = 26;      // Kijun-sen period
input int    InpSenkouB      = 52;      // Senkou Span B period
input double InpLotSize      = 0.1;     // Trade lot size
input int    InpMagicNumber  = 202600;  // Magic number
input int    InpSlippage     = 10;      // Max slippage (points)
input bool   InpUseTrailing  = true;    // Enable Kijun trailing stop

//--- Global handles and objects
int    g_ichiHandle  = INVALID_HANDLE;
CTrade g_trade;

//+------------------------------------------------------------------+
//| Expert initialisation                                            |
//+------------------------------------------------------------------+
int OnInit()
  {
   g_ichiHandle = iIchimoku(_Symbol, PERIOD_CURRENT,
                             InpTenkan, InpKijun, InpSenkouB);
   if(g_ichiHandle == INVALID_HANDLE)
     {
      Print("ERROR: Failed to create Ichimoku handle — ", GetLastError());
      return INIT_FAILED;
     }

   g_trade.SetExpertMagicNumber(InpMagicNumber);
   g_trade.SetDeviationInPoints(InpSlippage);
   g_trade.SetTypeFilling(ORDER_FILLING_FOK);

   Print("IchimokuCloudEA initialised on ", _Symbol,
         " [Tenkan=", InpTenkan,
         " Kijun=", InpKijun,
         " SenkouB=", InpSenkouB, "]");
   return INIT_SUCCEEDED;
  }

//+------------------------------------------------------------------+
//| Expert tick handler                                              |
//+------------------------------------------------------------------+
void OnTick()
  {
   //--- Only act on a new completed bar
   static datetime s_lastBar = 0;
   datetime currentBar = (datetime)SeriesInfoInteger(_Symbol, PERIOD_CURRENT,
                                                     SERIES_LASTBAR_DATE);
   if(currentBar == s_lastBar)
      return;
   s_lastBar = currentBar;

   //--- Fetch Ichimoku buffers (index 1 = previous closed bar)
   double tenkan[3], kijun[3], spanA[3], spanB[3], chikou[3];

   if(CopyBuffer(g_ichiHandle, 0, 1, 3, tenkan)  < 3) return;
   if(CopyBuffer(g_ichiHandle, 1, 1, 3, kijun)   < 3) return;
   if(CopyBuffer(g_ichiHandle, 2, 1, 3, spanA)   < 3) return;
   if(CopyBuffer(g_ichiHandle, 3, 1, 3, spanB)   < 3) return;
   if(CopyBuffer(g_ichiHandle, 4, 1, 3, chikou)  < 3) return;

   double closePrice[1];
   if(CopyClose(_Symbol, PERIOD_CURRENT, 1, 1, closePrice) < 1) return;

   double close       = closePrice[0];
   double cloudTop    = MathMax(spanA[0], spanB[0]);
   double cloudBottom = MathMin(spanA[0], spanB[0]);

   //--- Signal detection (index 0 = bar-1, index 1 = bar-2 for crossover)
   bool tkCrossUp   = tenkan[0] > kijun[0] && tenkan[1] <= kijun[1];
   bool tkCrossDown = tenkan[0] < kijun[0] && tenkan[1] >= kijun[1];
   bool aboveCloud  = close > cloudTop;
   bool belowCloud  = close < cloudBottom;
   bool chikouBull  = chikou[0] > close;   // simplified: chikou vs current
   bool chikouBear  = chikou[0] < close;

   bool longSignal  = tkCrossUp   && aboveCloud && chikouBull;
   bool shortSignal = tkCrossDown && belowCloud  && chikouBear;

   //--- Manage trailing stop on existing positions
   if(InpUseTrailing)
      ManageTrailing(kijun[0]);

   //--- Check existing positions before opening new ones
   if(HasPosition(POSITION_TYPE_BUY) || HasPosition(POSITION_TYPE_SELL))
     {
      CheckExit(tenkan[0], kijun[0], cloudTop, cloudBottom, close);
      return;
     }

   //--- Open new positions
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double pt  = SymbolInfoDouble(_Symbol, SYMBOL_POINT);

   if(longSignal)
     {
      double sl = cloudBottom - 5 * pt;
      g_trade.Buy(InpLotSize, _Symbol, ask, sl, 0,
                  "Ichimoku Long");
      PrintFormat("LONG opened | Close=%.5f CloudBot=%.5f SL=%.5f",
                  close, cloudBottom, sl);
     }
   else if(shortSignal)
     {
      double sl = cloudTop + 5 * pt;
      g_trade.Sell(InpLotSize, _Symbol, bid, sl, 0,
                   "Ichimoku Short");
      PrintFormat("SHORT opened | Close=%.5f CloudTop=%.5f SL=%.5f",
                  close, cloudTop, sl);
     }
  }

//+------------------------------------------------------------------+
//| Check exit conditions for open positions                         |
//+------------------------------------------------------------------+
void CheckExit(double tenkan, double kijun,
               double cloudTop, double cloudBottom, double close)
  {
   for(int i = PositionsTotal() - 1; i >= 0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(ticket == 0) continue;
      if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
      if(PositionGetInteger(POSITION_MAGIC)  != InpMagicNumber) continue;

      ENUM_POSITION_TYPE type =
         (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);

      bool exitLong  = (type == POSITION_TYPE_BUY)  &&
                       (tenkan < kijun ||
                        (close < cloudTop && close > cloudBottom));
      bool exitShort = (type == POSITION_TYPE_SELL) &&
                       (tenkan > kijun ||
                        (close > cloudBottom && close < cloudTop));

      if(exitLong || exitShort)
        {
         g_trade.PositionClose(ticket);
         PrintFormat("Position %d closed — exit signal", (int)ticket);
        }
     }
  }

//+------------------------------------------------------------------+
//| Trailing stop along Kijun-sen                                    |
//+------------------------------------------------------------------+
void ManageTrailing(double kijun)
  {
   double pt = SymbolInfoDouble(_Symbol, SYMBOL_POINT);

   for(int i = PositionsTotal() - 1; i >= 0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(ticket == 0) continue;
      if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
      if(PositionGetInteger(POSITION_MAGIC)  != InpMagicNumber) continue;

      ENUM_POSITION_TYPE type =
         (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
      double currentSL = PositionGetDouble(POSITION_SL);

      if(type == POSITION_TYPE_BUY)
        {
         double newSL = kijun - 5 * pt;
         if(newSL > currentSL)
            g_trade.PositionModify(ticket, newSL,
                                   PositionGetDouble(POSITION_TP));
        }
      else if(type == POSITION_TYPE_SELL)
        {
         double newSL = kijun + 5 * pt;
         if(newSL < currentSL || currentSL == 0)
            g_trade.PositionModify(ticket, newSL,
                                   PositionGetDouble(POSITION_TP));
        }
     }
  }

//+------------------------------------------------------------------+
//| Check whether a position of given type is open                   |
//+------------------------------------------------------------------+
bool HasPosition(ENUM_POSITION_TYPE posType)
  {
   for(int i = 0; i < PositionsTotal(); i++)
     {
      ulong ticket = PositionGetTicket(i);
      if(ticket == 0) continue;
      if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
      if(PositionGetInteger(POSITION_MAGIC)  != InpMagicNumber) continue;
      if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == posType)
         return true;
     }
   return false;
  }

//+------------------------------------------------------------------+
//| Expert deinitialization                                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(g_ichiHandle != INVALID_HANDLE)
      IndicatorRelease(g_ichiHandle);
   PrintFormat("IchimokuCloudEA deinitialized — reason %d", reason);
  }
//+------------------------------------------------------------------+

Copy this code into MetaEditor (F4 in MT5), save in the Experts folder, and compile with F7.

Generate a Custom Multi-pair Trend EA →

Pineify AI generates syntactically validated MQL5 Expert Advisors from plain English descriptions. Customize entry logic, risk management, and trading sessions — no coding required.

Pine Script vs MQL5: Same Strategy, Different Platforms

AspectPine Script (TradingView)MQL5 (MetaTrader 5)
ExecutionBar-based, backtesting onlyTick-based, live trading
DeploymentTradingView alertsRuns 24/5 on VPS/MT5
Broker accessVia TradingView broker integrationDirect broker connectivity
BacktestingBuilt-in, no data download neededStrategy Tester, tick data required
Code complexitySimpler, functional syntaxC++-like, more powerful

Pineify supports both platforms. Prototype your strategy visually in TradingView Pine Script, then generate the equivalent MQL5 EA for live MT5 trading.

Frequently Asked Questions

Related MQL5 Expert Advisors