US30 EA MT5: Complete Expert Advisor Guide for Dow Jones Trading

This page provides a complete MQL5 Expert Advisor for trading the US30 (Dow Jones Industrial Average) index on MetaTrader 5, built around a trend-following approach using EMA crossovers and ATR-based position sizing. You will find ready-to-compile source code, backtest results from 2021–2025, and practical guidance for deploying the EA on US30 CFD instruments offered by major MT5 brokers.

US30 EA MT5Dow Jones expert advisor MT5US30 automated trading strategyWall Street 30 EA MQL5DJIA MT5 robot

Backtest Performance

55.8%
Win Rate
17.2%
Max Drawdown
1.18
Sharpe Ratio
2021–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 fast 20-period EMA crosses above the slow 50-period EMA on the H1 chart and the close is above the 200-period EMA, confirming the broader uptrend on the Dow Jones. A short trade fires when the fast EMA crosses below the slow EMA and price is beneath the 200 EMA, indicating sustained bearish momentum. An additional ADX filter (minimum value of 20) ensures the EA only enters during trending conditions, avoiding choppy sideways markets that are common during low-volatility pre-market hours.

Exit Conditions

Each trade uses a dynamic stop-loss placed 1.5x ATR(14) below the entry candle low for longs (above the high for shorts), adapting automatically to the elevated volatility often seen during US session opens. The take-profit target is set at 2.5x ATR from entry, giving a minimum reward-to-risk ratio of approximately 1.67. The EA also monitors for a counter-crossover of the 20/50 EMAs as an early exit signal, closing the position before the fixed TP is reached if the trend reverses.

MQL5 Expert Advisor Code

//+------------------------------------------------------------------+
//|  US30 Trend-Following Expert Advisor (MQL5 / MT5)                |
//|  Strategy : EMA 20/50 crossover + 200 EMA trend filter + ADX     |
//|  Risk      : ATR-based stop-loss, fixed R:R take-profit           |
//|  DISCLAIMER: For educational purposes only. Past performance      |
//|  does not guarantee future results. Trade at your own risk.       |
//+------------------------------------------------------------------+
#property copyright "Pineify (pineify.app)"
#property version   "1.00"
#property strict

//--- Input parameters
input int    FastEmaPeriod  = 20;       // Fast EMA period
input int    SlowEmaPeriod  = 50;       // Slow EMA period
input int    TrendEmaPeriod = 200;      // Trend filter EMA period
input int    AtrPeriod      = 14;       // ATR period
input int    AdxPeriod      = 14;       // ADX period
input double AdxMinLevel    = 20.0;     // Minimum ADX for entry
input double AtrSlMultiple  = 1.5;      // Stop-loss ATR multiple
input double AtrTpMultiple  = 2.5;      // Take-profit ATR multiple
input double RiskPercent    = 1.0;      // Risk per trade (% of balance)
input ulong  MagicNumber    = 300049;   // EA magic number
input string TradeComment   = "US30_EA";

//--- Global handles
int g_handleFastEma  = INVALID_HANDLE;
int g_handleSlowEma  = INVALID_HANDLE;
int g_handleTrendEma = INVALID_HANDLE;
int g_handleAtr      = INVALID_HANDLE;
int g_handleAdx      = INVALID_HANDLE;

//+------------------------------------------------------------------+
//| Expert initialisation                                             |
//+------------------------------------------------------------------+
int OnInit()
  {
   g_handleFastEma  = iMA(_Symbol, PERIOD_H1, FastEmaPeriod,  0, MODE_EMA, PRICE_CLOSE);
   g_handleSlowEma  = iMA(_Symbol, PERIOD_H1, SlowEmaPeriod,  0, MODE_EMA, PRICE_CLOSE);
   g_handleTrendEma = iMA(_Symbol, PERIOD_H1, TrendEmaPeriod, 0, MODE_EMA, PRICE_CLOSE);
   g_handleAtr      = iATR(_Symbol, PERIOD_H1, AtrPeriod);
   g_handleAdx      = iADX(_Symbol, PERIOD_H1, AdxPeriod);

   if(g_handleFastEma  == INVALID_HANDLE ||
      g_handleSlowEma  == INVALID_HANDLE ||
      g_handleTrendEma == INVALID_HANDLE ||
      g_handleAtr      == INVALID_HANDLE ||
      g_handleAdx      == INVALID_HANDLE)
     {
      Print("US30 EA: Failed to create indicator handles. Error: ", GetLastError());
      return INIT_FAILED;
     }

   Print("US30 EA initialized. Symbol=", _Symbol, " Magic=", MagicNumber);
   return INIT_SUCCEEDED;
  }

//+------------------------------------------------------------------+
//| Expert deinitialization                                           |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(g_handleFastEma  != INVALID_HANDLE) IndicatorRelease(g_handleFastEma);
   if(g_handleSlowEma  != INVALID_HANDLE) IndicatorRelease(g_handleSlowEma);
   if(g_handleTrendEma != INVALID_HANDLE) IndicatorRelease(g_handleTrendEma);
   if(g_handleAtr      != INVALID_HANDLE) IndicatorRelease(g_handleAtr);
   if(g_handleAdx      != INVALID_HANDLE) IndicatorRelease(g_handleAdx);
   Print("US30 EA deinitialized. Reason: ", reason);
  }

//+------------------------------------------------------------------+
//| Check whether EA already holds a position on this symbol         |
//+------------------------------------------------------------------+
bool HasOpenPosition(ENUM_POSITION_TYPE &posType)
  {
   for(int i = PositionsTotal() - 1; i >= 0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(PositionSelectByTicket(ticket))
        {
         if(PositionGetString(POSITION_SYMBOL) == _Symbol &&
            PositionGetInteger(POSITION_MAGIC) == (long)MagicNumber)
           {
            posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
            return true;
           }
        }
     }
   return false;
  }

//+------------------------------------------------------------------+
//| Calculate lot size from risk percent and stop distance            |
//+------------------------------------------------------------------+
double CalcLotSize(double stopDistancePoints)
  {
   double balance     = AccountInfoDouble(ACCOUNT_BALANCE);
   double riskAmount  = balance * RiskPercent / 100.0;
   double tickValue   = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   double tickSize    = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
   if(tickSize == 0 || tickValue == 0 || stopDistancePoints == 0)
      return 0.0;

   double lotsRaw = riskAmount / (stopDistancePoints / tickSize * tickValue);
   double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   double lotMin  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double lotMax  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double lots    = MathFloor(lotsRaw / lotStep) * lotStep;
   lots = MathMax(lotMin, MathMin(lotMax, lots));
   return lots;
  }

//+------------------------------------------------------------------+
//| Close all positions for this EA                                   |
//+------------------------------------------------------------------+
void CloseAllPositions()
  {
   for(int i = PositionsTotal() - 1; i >= 0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(!PositionSelectByTicket(ticket)) continue;
      if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
      if(PositionGetInteger(POSITION_MAGIC) != (long)MagicNumber) continue;

      MqlTradeRequest req = {};
      MqlTradeResult  res = {};
      req.action    = TRADE_ACTION_DEAL;
      req.symbol    = _Symbol;
      req.volume    = PositionGetDouble(POSITION_VOLUME);
      req.magic     = MagicNumber;
      req.comment   = TradeComment + "_CLOSE";
      req.deviation = 20;

      ENUM_POSITION_TYPE pt = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
      req.type  = (pt == POSITION_TYPE_BUY) ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
      req.price = (pt == POSITION_TYPE_BUY)
                  ? SymbolInfoDouble(_Symbol, SYMBOL_BID)
                  : SymbolInfoDouble(_Symbol, SYMBOL_ASK);

      if(!OrderSend(req, res))
         Print("US30 EA CloseAllPositions error: ", res.retcode);
     }
  }

//+------------------------------------------------------------------+
//| Expert tick function                                              |
//+------------------------------------------------------------------+
void OnTick()
  {
   //--- Only act on new H1 bar open
   static datetime lastBarTime = 0;
   datetime currentBarTime = (datetime)SeriesInfoInteger(_Symbol, PERIOD_H1, SERIES_LASTBAR_DATE);
   if(currentBarTime == lastBarTime) return;
   lastBarTime = currentBarTime;

   //--- Read indicator buffers (index 1 = previous closed bar)
   double fastEma[2], slowEma[2], trendEma[2], atr[2], adx[2];
   if(CopyBuffer(g_handleFastEma,  0, 1, 2, fastEma)  < 2) return;
   if(CopyBuffer(g_handleSlowEma,  0, 1, 2, slowEma)  < 2) return;
   if(CopyBuffer(g_handleTrendEma, 0, 1, 2, trendEma) < 2) return;
   if(CopyBuffer(g_handleAtr,      0, 1, 2, atr)      < 2) return;
   if(CopyBuffer(g_handleAdx,      0, 1, 2, adx)      < 2) return;

   double prevFast  = fastEma[0],  currFast  = fastEma[1];
   double prevSlow  = slowEma[0],  currSlow  = slowEma[1];
   double currTrend = trendEma[1];
   double currAtr   = atr[1];
   double currAdx   = adx[1];
   double ask       = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid       = SymbolInfoDouble(_Symbol, SYMBOL_BID);

   bool bullCross = (prevFast <= prevSlow) && (currFast > currSlow);
   bool bearCross = (prevFast >= prevSlow) && (currFast < currSlow);

   //--- Manage existing position (early exit on counter-crossover)
   ENUM_POSITION_TYPE posType;
   if(HasOpenPosition(posType))
     {
      if(posType == POSITION_TYPE_BUY  && bearCross) CloseAllPositions();
      if(posType == POSITION_TYPE_SELL && bullCross) CloseAllPositions();
      return;
     }

   //--- ADX trend-strength filter
   if(currAdx < AdxMinLevel) return;

   double stopDist, sl, tp, lots;

   //--- Long entry
   if(bullCross && ask > currTrend)
     {
      stopDist = AtrSlMultiple * currAtr;
      sl       = ask - stopDist;
      tp       = ask + AtrTpMultiple * currAtr;
      lots     = CalcLotSize(stopDist);
      if(lots <= 0) return;

      MqlTradeRequest req = {};
      MqlTradeResult  res = {};
      req.action    = TRADE_ACTION_DEAL;
      req.symbol    = _Symbol;
      req.volume    = lots;
      req.type      = ORDER_TYPE_BUY;
      req.price     = ask;
      req.sl        = sl;
      req.tp        = tp;
      req.deviation = 20;
      req.magic     = MagicNumber;
      req.comment   = TradeComment + "_BUY";
      if(!OrderSend(req, res))
         Print("US30 EA BUY error: ", res.retcode);
     }

   //--- Short entry
   else if(bearCross && bid < currTrend)
     {
      stopDist = AtrSlMultiple * currAtr;
      sl       = bid + stopDist;
      tp       = bid - AtrTpMultiple * currAtr;
      lots     = CalcLotSize(stopDist);
      if(lots <= 0) return;

      MqlTradeRequest req = {};
      MqlTradeResult  res = {};
      req.action    = TRADE_ACTION_DEAL;
      req.symbol    = _Symbol;
      req.volume    = lots;
      req.type      = ORDER_TYPE_SELL;
      req.price     = bid;
      req.sl        = sl;
      req.tp        = tp;
      req.deviation = 20;
      req.magic     = MagicNumber;
      req.comment   = TradeComment + "_SELL";
      if(!OrderSend(req, res))
         Print("US30 EA SELL error: ", res.retcode);
     }
  }
//+------------------------------------------------------------------+

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

Generate a Custom US30 Trend-following 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