🚀 AI One-Click Generation of mql4 Strategy Code

Automating the DeMarker Oscillator Strategy in an Mql4 Expert Advisor

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

Problem Description

Can you write a trading strategy that buys when the DeMarker indicator is oversold and sells when it is overbought?

Solution

Here is a complete, fully functional MQL4 Expert Advisor (EA) based on the DeMarker indicator.

Strategy Logic

This strategy uses a crossover approach rather than simply checking if the value is currently in the zone. This prevents the EA from opening multiple trades continuously while the market remains overbought or oversold.

  1. Buy Signal: The DeMarker line was below the Oversold Level (0.3) and crosses back above it.
  2. Sell Signal: The DeMarker line was above the Overbought Level (0.7) and crosses back below it.
  3. Trade Management: When a signal occurs, the EA will close any opposite positions (e.g., close Sells before Buying) and open a new trade with Stop Loss and Take Profit.

MQL4 Code

//+------------------------------------------------------------------+
//|                                             DeMarkerStrategy.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 int      DeMarkerPeriod   = 14;       // DeMarker Period
input double   OverboughtLevel  = 0.7;      // Overbought Level (Sell Zone)
input double   OversoldLevel    = 0.3;      // Oversold Level (Buy Zone)
input double   LotSize          = 0.1;      // Fixed Lot Size
input int      StopLoss         = 50;       // Stop Loss in points (0 = none)
input int      TakeProfit       = 100;      // Take Profit in points (0 = none)
input int      MagicNumber      = 123456;   // Unique Identifier for this EA
input int      Slippage         = 3;        // Max Slippage in points

//--- Global Variables
double pipMultiplier;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Adjust points for 3 and 5 digit brokers (Jpy pairs vs others)
   if(Digits == 3 || Digits == 5)
      pipMultiplier = 10;
   else
      pipMultiplier = 1;

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Clean up if necessary
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Check for a new bar to avoid calculating on every tick (optional, but efficient)
   // For this strategy, we check every tick but look at closed bars (index 1 and 2)
   // to ensure the signal is confirmed and doesn't repaint.

   // 1. Get DeMarker values
   // Index 1 is the previous closed bar. Index 2 is the bar before that.
   double deM_1 = iDeMarker(NULL, 0, DeMarkerPeriod, 1);
   double deM_2 = iDeMarker(NULL, 0, DeMarkerPeriod, 2);

   // 2. Check for Buy Signal (Cross from below 0.3 to above 0.3)
   if(deM_2 < OversoldLevel && deM_1 > OversoldLevel)
   {
      // Close existing Sell positions first
      ClosePositions(OP_SELL);
      
      // Check if we already have a Buy position
      if(CountPositions(OP_BUY) == 0)
      {
         OpenTrade(OP_BUY);
      }
   }

   // 3. Check for Sell Signal (Cross from above 0.7 to below 0.7)
   if(deM_2 > OverboughtLevel && deM_1 < OverboughtLevel)
   {
      // Close existing Buy positions first
      ClosePositions(OP_BUY);
      
      // Check if we already have a Sell position
      if(CountPositions(OP_SELL) == 0)
      {
         OpenTrade(OP_SELL);
      }
   }
}

//+------------------------------------------------------------------+
//| Helper: Open a Trade                                             |
//+------------------------------------------------------------------+
void OpenTrade(int type)
{
   double sl = 0, tp = 0;
   double price = 0;
   color cmdColor = clrNONE;

   if(type == OP_BUY)
   {
      price = Ask;
      if(StopLoss > 0)     sl = price - (StopLoss * Point * pipMultiplier);
      if(TakeProfit > 0)   tp = price + (TakeProfit * Point * pipMultiplier);
      cmdColor = clrBlue;
   }
   else if(type == OP_SELL)
   {
      price = Bid;
      if(StopLoss > 0)     sl = price + (StopLoss * Point * pipMultiplier);
      if(TakeProfit > 0)   tp = price - (TakeProfit * Point * pipMultiplier);
      cmdColor = clrRed;
   }

   // Normalize prices
   sl = NormalizeDouble(sl, Digits);
   tp = NormalizeDouble(tp, Digits);

   // Send Order
   int ticket = OrderSend(Symbol(), type, LotSize, price, Slippage, sl, tp, "DeMarker EA", MagicNumber, 0, cmdColor);
   
   if(ticket < 0)
   {
      Print("OrderSend failed with error #", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Helper: Close Positions of a specific type                       |
//+------------------------------------------------------------------+
void ClosePositions(int type)
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            if(OrderType() == type)
            {
               bool result = false;
               if(type == OP_BUY)
                  result = OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrRed);
               else if(type == OP_SELL)
                  result = OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrBlue);
                  
               if(!result) Print("OrderClose failed: ", GetLastError());
            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| Helper: Count Open Positions of a specific type                  |
//+------------------------------------------------------------------+
int CountPositions(int type)
{
   int count = 0;
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == type)
         {
            count++;
         }
      }
   }
   return count;
}
//+------------------------------------------------------------------+

How to Install and Use

  1. Open MetaTrader 4.
  2. Press F4 to open the MetaEditor.
  3. Click New -> Expert Advisor (template) -> Name it "DeMarkerStrategy".
  4. Delete everything in the new file and paste the code above.
  5. Press F7 or click Compile. Ensure there are no errors.
  6. Go back to the main MT4 window.
  7. Find "DeMarkerStrategy" in the Navigator panel under Expert Advisors.
  8. Drag it onto a chart (e.g., EURUSD H1).
  9. Ensure the "AutoTrading" button at the top of MT4 is green.

Key Features of This Code

  • 5-Digit Broker Support: Automatically adjusts Stop Loss and Take Profit calculations for brokers using 5 decimal places (points vs pips).
  • Signal Confirmation: It uses iDeMarker(..., 1) and iDeMarker(..., 2). This means it looks at the previous closed bar and the bar before that. This ensures the signal is "locked in" and won't disappear (repaint) while the current candle is still moving.
  • Risk Management: Includes inputs for Stop Loss and Take Profit.
  • Magic Number: Uses a unique ID so this EA won't accidentally close trades opened by you manually or by other EAs.

Q&A

Q: How can I make the strategy more aggressive?
A: You can change the OverboughtLevel to 0.6 and OversoldLevel to 0.4 in the input settings. This will generate signals closer to the center line, resulting in more trades but potentially more false signals.

Q: Why does the EA close opposite trades?
A: This is a reversal strategy. If the indicator says the market is oversold (Buy), it implies the previous downward trend (Sell) is ending. Therefore, it is logical to close any open Sell positions before opening a Buy.

Q: Can I use this on any timeframe?
A: Yes, the code uses 0 in the iDeMarker function, which represents the PERIOD_CURRENT. It will adapt to whatever timeframe (M15, H1, D1) the chart is set to.