Subscribe to Market Depth (DOM)¶
Request: Subscribe to Depth of Market (order book) updates for a symbol.
API Information:
- Python API:
MT5Account.market_book_add(...)(defined inpackage/MetaRpcMT5/helpers/mt5_account.py) - gRPC service:
mt5_term_api.MarketInfo - Proto definition:
MarketBookAdd(defined inmt5-term-api-market-info.proto) - Enums in this method: 0 enums (simple boolean result)
RPC¶
- Service:
mt5_term_api.MarketInfo - Method:
MarketBookAdd(MarketBookAddRequest) -> MarketBookAddReply - Low-level client (generated):
MarketInfoStub.MarketBookAdd(request, metadata)
from MetaRpcMT5 import MT5Account
class MT5Account:
# ...
async def market_book_add(
self,
symbol: str,
deadline: Optional[datetime] = None,
cancellation_event: Optional[asyncio.Event] = None,
) -> market_info_pb2.MarketBookAddData:
"""
Opens the Depth of Market (DOM) for a symbol and subscribes to updates.
Returns:
MarketBookAddData: Subscription result.
"""
Request message:
🔽 Input¶
| Parameter | Type | Description |
|---|---|---|
symbol |
str |
Symbol name (e.g., "EURUSD") |
deadline |
Optional[datetime] |
Deadline for the operation (optional) |
cancellation_event |
Optional[asyncio.Event] |
Event to cancel the request (optional) |
⬆️ Output¶
Returns MarketBookAddData object.
MarketBookAddData fields:
| Field | Type | Description |
|---|---|---|
opened_successfully |
bool |
True if subscription was successful |
💬 Just the essentials¶
- What it is. Subscribes to Level 2 market data (order book) for a symbol.
- Why you need it. Required before you can call
market_book_getto retrieve DOM data. - One-time subscription. Call once per symbol, then use
market_book_getto fetch data.
🎯 Purpose¶
Use it to:
- Subscribe to market depth (DOM) updates
- Enable Level 2 data access for a symbol
- Prepare for order book analysis
- Monitor bid/ask liquidity levels
- Analyze market microstructure
📚 Tutorial¶
For a detailed line-by-line explanation with examples, see: market_book_add - How it works
🧩 Notes & Tips¶
- Automatic reconnection: All
MT5Accountmethods have built-in protection against transient gRPC errors with automatic reconnection viaexecute_with_reconnect. - Subscription required: Must call this before
market_book_get. - Symbol must be selected: Ensure symbol is in Market Watch before subscribing.
- Broker support: Not all brokers provide DOM data.
- Resource cleanup: Call
market_book_releasewhen done to unsubscribe. - One subscription: You only need to subscribe once per symbol.
- Check success: Always verify
opened_successfully == True.
🔗 Usage Examples¶
1) Subscribe to DOM for EURUSD¶
import asyncio
from MetaRpcMT5 import MT5Account
async def subscribe_dom():
account = MT5Account(
user=12345,
password="password",
grpc_server="mt5.mrpc.pro:443"
)
await account.connect_by_server_name(
server_name="YourBroker-Demo",
base_chart_symbol="EURUSD"
)
try:
# Subscribe to DOM
result = await account.market_book_add("EURUSD")
if result.opened_successfully:
print(f"[SUCCESS] Subscribed to EURUSD DOM")
else:
print(f"[FAILED] Could not subscribe to DOM")
finally:
await account.channel.close()
asyncio.run(subscribe_dom())
2) Subscribe and verify¶
import asyncio
from MetaRpcMT5 import MT5Account
async def subscribe_and_verify():
account = MT5Account(
user=12345,
password="password",
grpc_server="mt5.mrpc.pro:443"
)
await account.connect_by_server_name(
server_name="YourBroker-Demo",
base_chart_symbol="EURUSD"
)
try:
symbol = "EURUSD"
# First, ensure symbol is selected in Market Watch
await account.symbol_select(symbol=symbol, select=True)
print(f"[1] Symbol {symbol} selected in Market Watch")
# Now subscribe to DOM
result = await account.market_book_add(symbol)
if result.opened_successfully:
print(f"[2] Successfully subscribed to {symbol} DOM")
# Verify by getting DOM data
dom_data = await account.market_book_get(symbol)
print(f"[3] DOM has {len(dom_data.mql_book_infos)} levels")
else:
print(f"[2] Failed to subscribe to DOM")
finally:
await account.channel.close()
asyncio.run(subscribe_and_verify())
3) Subscribe to multiple symbols¶
import asyncio
from MetaRpcMT5 import MT5Account
async def subscribe_multiple():
account = MT5Account(
user=12345,
password="password",
grpc_server="mt5.mrpc.pro:443"
)
await account.connect_by_server_name(
server_name="YourBroker-Demo",
base_chart_symbol="EURUSD"
)
symbols = ["EURUSD", "GBPUSD", "USDJPY"]
try:
for symbol in symbols:
result = await account.market_book_add(symbol)
if result.opened_successfully:
print(f"[OK] {symbol} - DOM subscribed")
else:
print(f"[FAIL] {symbol} - Could not subscribe")
finally:
await account.channel.close()
asyncio.run(subscribe_multiple())
4) Subscribe with error handling¶
import asyncio
from MetaRpcMT5 import MT5Account, ApiExceptionMT5
async def subscribe_with_error_handling():
account = MT5Account(
user=12345,
password="password",
grpc_server="mt5.mrpc.pro:443"
)
await account.connect_by_server_name(
server_name="YourBroker-Demo",
base_chart_symbol="EURUSD"
)
symbol = "EURUSD"
try:
# Subscribe to DOM
result = await account.market_book_add(symbol)
if result.opened_successfully:
print(f"[SUCCESS] Subscribed to {symbol} DOM")
return True
else:
print(f"[WARNING] Subscription returned false")
return False
except ApiExceptionMT5 as e:
print(f"[API ERROR] {e}")
return False
except Exception as e:
print(f"[ERROR] Unexpected error: {e}")
return False
finally:
await account.channel.close()
asyncio.run(subscribe_with_error_handling())
5) Check broker DOM support¶
import asyncio
from MetaRpcMT5 import MT5Account
async def check_dom_support():
account = MT5Account(
user=12345,
password="password",
grpc_server="mt5.mrpc.pro:443"
)
await account.connect_by_server_name(
server_name="YourBroker-Demo",
base_chart_symbol="EURUSD"
)
test_symbols = ["EURUSD", "GBPUSD", "USDJPY", "XAUUSD"]
try:
print("Checking DOM support for symbols:\n")
print(f"{'Symbol':<10} {'DOM Support':<15}")
print("-" * 30)
for symbol in test_symbols:
try:
result = await account.market_book_add(symbol)
if result.opened_successfully:
# Try to get DOM data
dom_data = await account.market_book_get(symbol)
if len(dom_data.mql_book_infos) > 0:
print(f"{symbol:<10} {'YES ('+str(len(dom_data.mql_book_infos))+' levels)':<15}")
else:
print(f"{symbol:<10} {'NO DATA':<15}")
# Clean up
await account.market_book_release(symbol)
else:
print(f"{symbol:<10} {'NOT SUPPORTED':<15}")
except Exception as e:
print(f"{symbol:<10} {'ERROR':<15}")
finally:
await account.channel.close()
asyncio.run(check_dom_support())
6) Subscribe and monitor DOM¶
import asyncio
from MetaRpcMT5 import MT5Account
async def monitor_dom(symbol: str, duration: int = 10):
"""Subscribe and monitor DOM for specified duration"""
account = MT5Account(
user=12345,
password="password",
grpc_server="mt5.mrpc.pro:443"
)
await account.connect_by_server_name(
server_name="YourBroker-Demo",
base_chart_symbol="EURUSD"
)
try:
# Subscribe to DOM
result = await account.market_book_add(symbol)
if not result.opened_successfully:
print(f"[FAILED] Could not subscribe to {symbol} DOM")
return
print(f"[SUBSCRIBED] Monitoring {symbol} DOM for {duration} seconds\n")
start_time = asyncio.get_event_loop().time()
while (asyncio.get_event_loop().time() - start_time) < duration:
# Get current DOM state
dom_data = await account.market_book_get(symbol)
# Clear screen
print("\033[2J\033[H")
print(f"=== {symbol} Market Depth ===")
print(f"Total levels: {len(dom_data.mql_book_infos)}\n")
print(f"{'Type':<10} {'Price':<15} {'Volume':<15}")
print("-" * 45)
for book_entry in dom_data.mql_book_infos[:10]: # Show first 10 levels
entry_type = "BUY" if book_entry.type in [1, 3] else "SELL"
print(f"{entry_type:<10} {book_entry.price:<15.5f} {book_entry.volume_real:<15.2f}")
await asyncio.sleep(1) # Update every second
# Unsubscribe when done
await account.market_book_release(symbol)
print(f"\n[UNSUBSCRIBED] Stopped monitoring {symbol} DOM")
finally:
await account.channel.close()
asyncio.run(monitor_dom("EURUSD", duration=10))
📚 See also¶
- MarketBookGet - Get current DOM data
- MarketBookRelease - Unsubscribe from DOM
- SymbolSelect - Add symbol to Market Watch