🚀 AI One-Click Generation of mql4 Strategy Code

Building a Momentum Crossover Trading EA in Mql4

mql4 | Published on: 2025/12/10
The following content is generated by EasyQuant .

Problem Description

Can you help me code a trading strategy that uses the Momentum indicator?

Solution

Here is a complete, robust, and well-commented MQL4 trading strategy based on the Momentum Indicator.

Strategy Logic

This Expert Advisor (EA) uses a classic Momentum crossover strategy filtered by a Moving Average to determine the trend direction.

  1. Indicator 1 (Signal): Momentum (Period 14).
    • Buy Signal: Momentum line crosses above the 100 level.
    • Sell Signal: Momentum line crosses below the 100 level.
  2. Indicator 2 (Trend Filter): Simple Moving Average (SMA 50).
    • We only Buy if the price is above the SMA.
    • We only Sell if the price is below the SMA.
  3. Risk Management:
    • Fixed Stop Loss and Take Profit.
    • Dynamic Trailing Stop to lock in profits.

MQL4 Code

//+------------------------------------------------------------------+
//|                                             MomentumStrategy.mq4 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative AI"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//--- Input Parameters
input string   StrategySettings = "--- Strategy Settings ---";
input double   LotSize          = 0.1;      // Fixed Lot Size
input int      MomentumPeriod   = 14;       // Period for Momentum Indicator
input int      MAPeriod         = 50;       // Period for Trend Filter (SMA)
input int      StopLoss         = 50;       // Stop Loss in pips
input int      TakeProfit       = 100;      // Take Profit in pips
input int      TrailingStop     = 30;       // Trailing Stop in pips (0 to disable)
input int      MagicNumber      = 123456;   // Unique ID for this EA
input int      Slippage         = 3;        // Max slippage allowed

//--- Global Variables
double pPoint; // Adjusted point value for 3/5 digit brokers

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Adjust point for 5-digit brokers (0.00001) vs 4-digit (0.0001)
   if(Digits == 3 || Digits == 5) pPoint = Point * 10;
   else pPoint = Point;

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // 1. Check for Open Orders and Manage Trailing Stop
   if(OrdersTotal() > 0) 
   {
      ManageTrailingStop();
   }

   // 2. Check if we already have a position open for this symbol/magic number
   if(CountTrades() > 0) return; // We only allow one trade at a time per chart

   // 3. Define Indicator Values
   // We use shift 1 (previous closed bar) and shift 2 to detect the crossover
   // This prevents "repainting" issues on the current forming bar
   
   // Momentum Values
   double momCurrent  = iMomentum(NULL, 0, MomentumPeriod, PRICE_CLOSE, 1);
   double momPrevious = iMomentum(NULL, 0, MomentumPeriod, PRICE_CLOSE, 2);
   
   // Moving Average Value (Trend Filter)
   double maValue     = iMA(NULL, 0, MAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
   
   // Previous Close Price (to compare with MA)
   double closePrice  = iClose(NULL, 0, 1);

   // 4. Trading Logic
   
   // --- BUY SIGNAL ---
   // Momentum crosses UP over 100 AND Price is ABOVE Moving Average
   if(momPrevious < 100 && momCurrent > 100 && closePrice > maValue)
   {
      double sl = Ask - (StopLoss * pPoint);
      double tp = Ask + (TakeProfit * pPoint);
      
      // Send Order
      int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, sl, tp, "MomBuy", MagicNumber, 0, clrGreen);
      
      if(ticket < 0) Print("OrderSend failed with error #", GetLastError());
   }

   // --- SELL SIGNAL ---
   // Momentum crosses DOWN under 100 AND Price is BELOW Moving Average
   if(momPrevious > 100 && momCurrent < 100 && closePrice < maValue)
   {
      double sl = Bid + (StopLoss * pPoint);
      double tp = Bid - (TakeProfit * pPoint);
      
      // Send Order
      int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, sl, tp, "MomSell", MagicNumber, 0, clrRed);
      
      if(ticket < 0) Print("OrderSend failed with error #", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Helper: Count open trades for this EA                            |
//+------------------------------------------------------------------+
int CountTrades()
{
   int count = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            if(OrderType() == OP_BUY || OrderType() == OP_SELL)
               count++;
         }
      }
   }
   return(count);
}

//+------------------------------------------------------------------+
//| Helper: Manage Trailing Stop                                     |
//+------------------------------------------------------------------+
void ManageTrailingStop()
{
   if(TrailingStop == 0) return; // Exit if disabled

   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            // Logic for BUY orders
            if(OrderType() == OP_BUY)
            {
               // If price has moved in our favor by TrailingStop amount
               if(Bid - OrderOpenPrice() > TrailingStop * pPoint)
               {
                  // If current SL is lower than (Bid - TrailingStop), move it up
                  if(OrderStopLoss() < Bid - (TrailingStop * pPoint))
                  {
                     if(!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - (TrailingStop * pPoint), OrderTakeProfit(), 0, clrBlue))
                        Print("Error modifying Buy Trailing Stop: ", GetLastError());
                  }
               }
            }
            
            // Logic for SELL orders
            if(OrderType() == OP_SELL)
            {
               // If price has moved in our favor by TrailingStop amount
               if(OrderOpenPrice() - Ask > TrailingStop * pPoint)
               {
                  // If current SL is higher than (Ask + TrailingStop) or is 0, move it down
                  if(OrderStopLoss() > Ask + (TrailingStop * pPoint) || OrderStopLoss() == 0)
                  {
                     if(!OrderModify(OrderTicket(), OrderOpenPrice(), Ask + (TrailingStop * pPoint), OrderTakeProfit(), 0, clrBlue))
                        Print("Error modifying Sell Trailing Stop: ", GetLastError());
                  }
               }
            }
         }
      }
   }
}

How to Install and Run

  1. Open MetaTrader 4.
  2. Press F4 to open the MetaEditor.
  3. In MetaEditor, click New -> Expert Advisor (template) -> Next.
  4. Name it MomentumStrategy and click Next/Finish.
  5. Delete everything in the new file and paste the code provided above.
  6. Press F7 or click Compile. Ensure there are no errors in the "Errors" tab at the bottom.
  7. Go back to the main MetaTrader 4 window.
  8. Find MomentumStrategy in the Navigator panel under "Expert Advisors".
  9. Drag it onto a chart (e.g., EURUSD H1).
  10. Ensure the "AutoTrading" button at the top is Green and check "Allow live trading" in the EA inputs tab.

Key Features of This Code

  • Point Adjustment: The code automatically detects if your broker uses 5-digit pricing (e.g., EURUSD 1.12345) or 4-digit pricing and adjusts the Pips calculation accordingly.
  • Trend Filter: It uses a 50-period Simple Moving Average (iMA) to ensure you aren't buying into a downtrend or selling into an uptrend.
  • Crossover Logic: It compares the Momentum value of the previous bar (shift 1) against the bar before that (shift 2). This ensures the signal is confirmed by a closed candle, preventing the signal from flickering (repainting).
  • Trailing Stop: A built-in function moves your Stop Loss automatically as the price moves in your favor, securing profits.

Q&A: Momentum Strategy in MQL4

Q: Why do we use shift 1 and shift 2 instead of shift 0?
A: shift 0 refers to the current candle, which is still forming. The Momentum value can jump above and below 100 multiple times before the candle closes. Using shift 1 ensures we only trade based on confirmed, closed candles.

Q: What is the standard level for the Momentum indicator?
A: The standard centerline for Momentum in MetaTrader 4 is 100. Values above 100 indicate price is higher than it was n periods ago (uptrend momentum), and values below 100 indicate the opposite.

Q: Can I optimize the parameters?
A: Yes. Because we defined the variables (like MomentumPeriod, StopLoss, MAPeriod) as input, you can use the MT4 Strategy Tester to run optimizations and find the best settings for specific currency pairs.

Q: How does the Trailing Stop work in this code?
A: The trailing stop activates immediately. If you set it to 30 pips, once the price moves 31 pips in profit, the Stop Loss will move to +1 pip profit. It will continue to follow the price at a distance of 30 pips.