Edgoro
Trade server return code 10018 · MQL5

MT5 error 10018 Market closed: causes and fix

Why an MT5 EA gets retcode 10018 (market closed) and how to check the symbol's trading sessions in server time with SymbolInfoSessionTrade() in MQL5.

Trade server return code · MqlTradeResult.retcode
10018 TRADE_RETCODE_MARKET_CLOSED
“Market is closed”
Experts tab · line printed by CTrade (example values)
CTrade::OrderSend: market buy 0.10 EURUSD [market closed]

What it means

The symbol isn't open for trading at the moment the request arrives. The account, the volume and the levels may all be fine; the server simply doesn't accept orders for this symbol now.

Usual causes

  • Outside the trading session. Weekends, the hours a market is shut, and the daily breaks some CFDs have. Sessions are defined in the broker's server time.
  • Local time instead of server time. An EA that starts trading at "08:00" read from TimeLocal() trades at the wrong hour whenever your computer's clock and the server's differ.
  • Quotes don't mean trading. A symbol can have a quote session that differs from its trade session, so a chart that still moves isn't proof that orders are accepted.
  • Holidays. On public holidays a broker can close or shorten a session. If the session table says open and you still get 10018, check the broker's holiday notices.

How to detect it

  • result.retcode (or trade.ResultRetcode()) is 10018; the Experts tab shows [market closed] after the request.
  • SymbolInfoSessionTrade() returns the trading sessions of a symbol for each day of the week, and TimeTradeServer() the current server time to compare them with. The symbol's specification window in the terminal shows the same sessions.

Broken code

This EA compiles. It sends orders by the computer's clock, including on weekends and during the symbol's breaks, and gets 10018.

MQL5
#include <Trade/Trade.mqh>

input int InpStartHour = 8; // Start trading at this hour

CTrade trade;

void OnTick()
  {
   if(PositionSelect(_Symbol))
      return;
   MqlDateTime now;
   TimeToStruct(TimeLocal(), now);   // the computer's clock, not the server's
   if(now.hour >= InpStartHour)
      trade.Buy(0.10);
  }

Fixed code

The same program with the check that prevents the error. It compiles in MetaEditor with 0 errors and 0 warnings.

MQL5
#include <Trade/Trade.mqh>

input int InpStartHour = 8; // Start trading at this hour, server time

CTrade trade;

// True if the server time is inside one of today's trading sessions for the symbol
bool InTradeSession(const string symbol)
  {
   MqlDateTime now;
   TimeToStruct(TimeTradeServer(), now);
   long secs = now.hour * 3600 + now.min * 60 + now.sec;
   datetime from, to;
   for(uint i = 0; SymbolInfoSessionTrade(symbol, (ENUM_DAY_OF_WEEK)now.day_of_week, i, from, to); i++)
     {
      // Seconds since midnight; a session that ends at 24:00 comes back as 0
      long f = (long)from % 86400;
      long t = (long)to % 86400;
      if(t <= f)
         t += 86400;
      if(secs >= f && secs < t)
         return true;
     }
   return false;
  }

void OnTick()
  {
   if(PositionSelect(_Symbol))
      return;
   MqlDateTime now;
   TimeToStruct(TimeTradeServer(), now);
   if(now.hour < InpStartHour || !InTradeSession(_Symbol))
      return;
   if(!trade.Buy(0.10))
      PrintFormat("Buy failed: retcode %u (%s)", trade.ResultRetcode(), trade.ResultRetcodeDescription());
  }

Why the fix works

The hour filter now uses TimeTradeServer(), the server's clock, which is the one sessions are defined in. Before sending, InTradeSession() walks through today's trading sessions of the symbol and only lets the order through inside one of them. Session times come back as seconds since midnight (the date part must be ignored), which is why the code keeps only the remainder of a division by 86,400.

The session table describes a normal week. Keep logging the retcode: a 10018 inside a listed session usually means a holiday or a broker-side closure.

Questions

Why do I get market closed when the chart is still moving?

Quotes and trading can follow different sessions. SymbolInfoSessionQuote() and SymbolInfoSessionTrade() return them separately, and only the trade session decides whether orders are accepted.

How do I find a symbol's trading hours in MT5?

Open the symbol's specification from the Market Watch, or read them in code with SymbolInfoSessionTrade() for each day of the week. Both are in the broker's server time.

Is MT5 error 10018 the same as MT4 error 132?

Yes. MQL4's error 132 (ERR_MARKET_CLOSED) is trade server return code 10018 in MQL5.

The programs on this page are minimal examples written to show the error and its fix, not trading systems. Some of them send orders when they run: try them on a demo account. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.

Working code that avoids it

All MQL5 examples

Rather not write the error handling yourself?

Edgoro's MT5 EA generator writes complete MQL5 Expert Advisors from plain English and compiles each one in MetaEditor before you get it. A clean build proves the code compiles, not that a strategy works: test it on a demo account.