MT5 Depth of Market Setup & MQL5 Code for Algo Traders

Learn to enable MT5 Depth of Market, customize DOM settings, and write MQL5 code to read order book data for algorithmic trading strategies.

mt5-depth-of-market-setup-mql5-code-for-algo

Why the Depth of Market Matters for Algorithmic Traders

Most retail traders never open the Depth of Market (DOM) window in MetaTrader 5. That's a mistake if you're building automated strategies. The DOM shows you the live order book — the actual pending buy and sell limit orders sitting at each price level, not just the last traded price. For algorithmic trading, this data lets you gauge liquidity, detect support and resistance zones before price hits them, and even build strategies that react to order book imbalance.

MT5 is unique among retail platforms because it exposes the full order book via MQL5 functions. You can't get this in MT4 — it simply doesn't have the infrastructure. If you're serious about algo trading, learning to read and code market depth in MT5 gives you an edge that most retail traders skip. This guide walks you through enabling the DOM visually, then writing MQL5 code to pull that data into your Expert Advisors and indicators.

I've been using DOM-based strategies for about three years now. The first time I saw the order book for EURUSD during a London open, I realized how much information I'd been missing. The bid-ask walls at key levels often form before price even moves — you can see accumulation or distribution happening in real time. That's not something you get from a simple moving average crossover. I've caught several false breakouts just by watching the order book thin out at a resistance level — price never had the fuel to push through.

Prerequisites

Before you start, make sure you have these three things in order:

  • MetaTrader 5 build 2000 or newer — older builds have limited DOM functionality. Check your build under Help > About. I've seen traders on build 1800 wondering why MarketBookAdd returns false every time. Update your terminal from your broker's website or the official MetaQuotes site.
  • A broker that provides depth of market data — not all brokers do. Most ECN/STP brokers offer it for forex majors, indices, and commodities. If your broker's symbol list shows a "Depth" column in Market Watch, you're good. Demo accounts from brokers like IC Markets, Pepperstone, or FXTM typically include DOM data. I've tested with IC Markets and Pepperstone — both work fine for majors like EURUSD and GBPUSD. Some market makers hide depth data intentionally because their order flow isn't transparent.
  • MQL5 development environment — that's the MetaEditor built into MT5. You already have it if MT5 is installed. Press F4 to open it.

One quick check: open the Market Watch panel (Ctrl+M), right-click any symbol, and select Symbols. In the Properties window, go to the Depth of Market tab. If you see "Depth of Market" enabled with a number like 10 or 20 in the "Depth" field, your broker supports it. If it's grayed out or set to 0, call your broker's support — they may need to enable it server-side. Some brokers hide this behind a checkbox labeled "Show Depth" in the symbol configuration. I've also seen cases where the demo account has depth but the live account doesn't — always verify both.

Step-by-Step: Enabling and Configuring MT5 Depth of Market

Step 1: Open the Depth of Market Window

In MT5, there are three ways to open the DOM:

  • Right-click a symbol in Market Watch and select Depth of Market.
  • Click View > Depth of Market from the top menu.
  • Press Ctrl+B on your keyboard.

The DOM window opens as a floating panel. By default it shows two columns: Bid (buy orders) on the left and Ask (sell orders) on the right. Each row is a price level, with the current spread highlighted. You'll see numbers like "1.12345" on the left and "1.12355" on the right — those are the best bid and ask prices. Below them, deeper levels show where other limit orders sit. The volume at each level is shown in lots or contracts depending on your broker's settings.

One thing that tripped me up early on: the DOM window doesn't update in real time by default if you minimize it. Keep it visible on your second monitor, or at least not minimized, or the data may freeze. That's an MT5 quirk. If you notice the DOM frozen during heavy news events, try resizing the window slightly — that often forces a refresh.

Step 2: Customize the DOM Display

Right-click inside the DOM window and select Properties. You'll see the following settings:

SettingOptionsRecommendation
Show Depth5, 10, 20, 50 levels10 for forex (more than that is usually noise)
Show VolumeTotal volume or lotsTotal volume (shows contract count)
Sort OrderBy price or by volumeBy price (default)
Show CumulativeOn/OffOff (keeps the view clean)
Color SchemeDefault, Dark, CustomDark (easier on the eyes for long sessions)

I prefer keeping Show Depth at 10 levels for forex pairs. Beyond that, you're often seeing stale limit orders that may never fill. For futures or indices, 20 levels can be useful because those markets tend to have thicker books. The Show Cumulative option adds up volume from the top down — I leave it off because it clutters the view, but some traders use it to spot large iceberg orders. If you're trading gold (XAUUSD) during Asian session, you might find only 3–5 meaningful levels anyway.

Step 3: Place Orders Directly from the DOM

Once the DOM is open, you can click any price level to place a pending order. A dialog appears where you set the volume, stop loss, and take profit. This is handy for manual scalping, but for algorithmic purposes, you'll want to read the order book programmatically, which we cover next. One caveat: clicking a price level in the DOM places a limit order at that exact price, not a market order. If you want a market order, you still need to use the standard trade dialog or right-click the chart. Also, be careful with the volume — the DOM dialog defaults to 0.01 lots, but if you're trading indices, that might be 1 contract instead. Always check the symbol specifications first.

MQL5 Code: Reading Market Depth Programmatically

MT5 provides three key functions for accessing the order book in MQL5: MarketBookAdd(), MarketBookGet(), and MarketBookRelease(). The workflow is simple: subscribe to a symbol's market depth, then poll or react to updates. Let me show you a complete example that you can drop into an Expert Advisor or indicator. I'll also cover a common pitfall — the order book data structure isn't always intuitive for beginners.

Subscribe to Market Depth

Call MarketBookAdd() once, typically in OnInit(). This tells the terminal to start streaming DOM data for that symbol. If the symbol doesn't support depth, the function returns false and you'll see error 4806 in the Experts log. You can also get error 4805 if the terminal is busy — in that case, retry after a short delay.

//+------------------------------------------------------------------+
//| Subscribe to market depth for EURUSD                            |
//+------------------------------------------------------------------+
bool SubscribeToDepth(string symbol)
  {
   if(!MarketBookAdd(symbol))
     {
      Print("Failed to subscribe to ", symbol, ". Error: ", GetLastError());
      return false;
     }
   Print("Subscribed to depth for ", symbol);
   return true;
  }

Notice I'm printing the error code. Error 4806 means "Market depth is not supported for the symbol." That's the most common failure. If you get error 4805, it means the terminal is busy — try again in the next tick. I've also seen error 4804 when the symbol is not selected in Market Watch — make sure you've added the symbol to your watchlist first.

Read Depth Data with MarketBookGet

The MarketBookGet() function fills an array of MqlBookInfo structures. Each structure contains:

  • price — the price level (double)
  • volume — total volume at that level (long)
  • type — BOOK_TYPE_BUY (bid) or BOOK_TYPE_SELL (ask) (enum)

Here's a function that prints the top 5 bid and ask levels to the Experts tab:

//+------------------------------------------------------------------+
//| Read and print market depth                                     |
//+------------------------------------------------------------------+
void ReadDepth(string symbol)
  {
   MqlBookInfo book[];
   if(!MarketBookGet(symbol, book))
     {
      Print("Failed to get depth for ", symbol, ". Error: ", GetLastError());
      return;
     }

   int total = ArraySize(book);
   Print("Depth levels for ", symbol, ": ", total);

   // Separate bid and ask
   for(int i = 0; i < total; i++)
     {
      string side = (book[i].type == BOOK_TYPE_BUY) ? "Bid" : "Ask";
      Print(side, " Price: ", DoubleToString(book[i].price, _Digits),
            " Volume: ", book[i].volume);
     }
  }

One thing I've noticed: the array returned by MarketBookGet() is not sorted by price in any guaranteed order. It's typically sorted by proximity to the current price — closest levels first — but don't rely on that. If you need to process levels in price order, sort the array yourself using ArraySort() with a custom comparator. Here's a quick sort by price for bids (descending) and asks (ascending):

//+------------------------------------------------------------------+
//| Sort book info by price (bids descending, asks ascending)       |
//+------------------------------------------------------------------+
void SortBookByPrice(MqlBookInfo &book[])
  {
   int total = ArraySize(book);
   for(int i = 0; i < total - 1; i++)
     {
      for(int j = i + 1; j < total; j++)
        {
         // For bids: higher price first
         if(book[i].type == BOOK_TYPE_BUY && book[j].type == BOOK_TYPE_BUY && book[i].price < book[j].price)
           {
            MqlBookInfo temp = book[i];
            book[i] = book[j];
            book[j] = temp;
           }
         // For asks: lower price first
         else if(book[i].type == BOOK_TYPE_SELL && book[j].type == BOOK_TYPE_SELL && book[i].price > book[j].price)
           {
            MqlBookInfo temp = book[i];
            book[i] = book[j];
            book[j] = temp;
           }
        }
     }
  }

React to Depth Updates with OnBookEvent

For real-time strategies, don't poll — use OnBookEvent(). This handler fires automatically whenever the order book changes. Here's a complete Expert Advisor skeleton:

//+------------------------------------------------------------------+
//|                                            MarketDepthReader.mq5 |
//|                                    Copyright 2024, YourNameHere |
//+------------------------------------------------------------------+
#property copyright "YourNameHere"
#property link      "https://tradingbotmaker.com"
#property version   "1.00"

input string InpSymbol = "EURUSD";        // Symbol to monitor
input int    InpDepthLevels = 10;         // Levels to analyze

int OnInit()
  {
   if(!MarketBookAdd(InpSymbol))
     {
      Print("MarketBookAdd failed for ", InpSymbol, ". Error: ", GetLastError());
      return(INIT_FAILED);
     }
   Print("Depth monitoring started for ", InpSymbol);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   MarketBookRelease(InpSymbol);
   Print("Depth monitoring released for ", InpSymbol);
  }

void OnTick()
  {
   // OnTick runs every tick, but depth updates are handled in OnBookEvent
  }

void OnBookEvent(const string &symbol)
  {
   if(symbol != InpSymbol) return;

   MqlBookInfo book[];
   if(!MarketBookGet(symbol, book)) return;

   int total = ArraySize(book);
   if(total == 0) return;

   // Calculate bid/ask imbalance ratio
   double bidVolume = 0, askVolume = 0;
   for(int i = 0; i < total &amp

Community

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

0 claps0 comments

Related articles