Unsubscribe from Market Depth¶
Request: Unsubscribe from Depth of Market (order book) updates for a symbol.
API Information:
- Python API:
MT5Account.market_book_release(...)(defined inpackage/MetaRpcMT5/helpers/mt5_account.py) - gRPC service:
mt5_term_api.MarketInfo - Proto definition:
MarketBookRelease(defined inmt5-term-api-market-info.proto) - Enums in this method: 0 enums (simple boolean result)
RPC¶
- Service:
mt5_term_api.MarketInfo - Method:
MarketBookRelease(MarketBookReleaseRequest) -> MarketBookReleaseReply - Low-level client (generated):
MarketInfoStub.MarketBookRelease(request, metadata)
from MetaRpcMT5 import MT5Account
class MT5Account:
# ...
async def market_book_release(
self,
symbol: str,
deadline: Optional[datetime] = None,
cancellation_event: Optional[asyncio.Event] = None,
) -> market_info_pb2.MarketBookReleaseData:
"""
Closes the Depth of Market (DOM) for a symbol and unsubscribes from updates.
Returns:
MarketBookReleaseData: Unsubscription 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 MarketBookReleaseData object.
MarketBookReleaseData fields:
| Field | Type | Description |
|---|---|---|
closed_successfully |
bool |
True if unsubscription was successful |
💬 Just the essentials¶
- What it is. Unsubscribes from Level 2 market data (order book) for a symbol.
- Why you need it. Clean up resources and stop receiving DOM updates when no longer needed.
- Best practice. Always call when done monitoring DOM to free resources.
🎯 Purpose¶
Use it to:
- Unsubscribe from DOM updates
- Free system resources
- Clean up after DOM analysis
- Stop market depth monitoring
- Manage subscription lifecycle
- Reduce bandwidth usage
📚 Tutorial¶
For a detailed line-by-line explanation with examples, see: MarketBookRelease - How it works
🧩 Notes & Tips¶
- Automatic reconnection: All
MT5Accountmethods have built-in protection against transient gRPC errors with automatic reconnection viaexecute_with_reconnect. - Resource cleanup: Always call this when done with DOM monitoring.
- No error if not subscribed: Safe to call even if not currently subscribed.
- Per-symbol basis: Each symbol must be released separately.
- Paired with add: Every
market_book_addshould have a matchingmarket_book_release. - Session cleanup: Subscriptions persist until explicitly released or session ends.
- Check success: Always verify
closed_successfully == True.
🔗 Usage Examples¶
1) Basic unsubscribe¶
import asyncio
from MetaRpcMT5 import MT5Account
async def unsubscribe_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:
symbol = "EURUSD"
# Subscribe to DOM
add_result = await account.market_book_add(symbol)
if add_result.opened_successfully:
print(f"[SUBSCRIBED] {symbol} DOM")
# Do some analysis...
dom_data = await account.market_book_get(symbol)
print(f"[ANALYSIS] {len(dom_data.mql_book_infos)} DOM levels")
# Unsubscribe when done
release_result = await account.market_book_release(symbol)
if release_result.closed_successfully:
print(f"[UNSUBSCRIBED] {symbol} DOM released")
finally:
await account.channel.close()
asyncio.run(unsubscribe_dom())
2) Context manager pattern¶
import asyncio
from MetaRpcMT5 import MT5Account
from contextlib import asynccontextmanager
@asynccontextmanager
async def dom_subscription(account, symbol):
"""Context manager for automatic DOM subscription cleanup"""
try:
# Subscribe
result = await account.market_book_add(symbol)
if not result.opened_successfully:
raise Exception(f"Failed to subscribe to {symbol} DOM")
print(f"[SUBSCRIBED] {symbol} DOM")
yield
finally:
# Always release on exit
await account.market_book_release(symbol)
print(f"[RELEASED] {symbol} DOM")
async def main():
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:
async with dom_subscription(account, "EURUSD"):
# DOM is active here
dom_data = await account.market_book_get("EURUSD")
print(f"[ANALYSIS] {len(dom_data.mql_book_infos)} DOM levels")
# DOM automatically released here
finally:
await account.channel.close()
asyncio.run(main())
3) Release multiple symbols¶
import asyncio
from MetaRpcMT5 import MT5Account
async def release_multiple_symbols():
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:
# Subscribe to multiple symbols
print("[SUBSCRIBING] To multiple symbols...")
for symbol in symbols:
result = await account.market_book_add(symbol)
if result.opened_successfully:
print(f" [OK] {symbol} subscribed")
# Do analysis...
await asyncio.sleep(5)
# Release all symbols
print("\n[RELEASING] All subscriptions...")
for symbol in symbols:
result = await account.market_book_release(symbol)
if result.closed_successfully:
print(f" [OK] {symbol} released")
finally:
await account.channel.close()
asyncio.run(release_multiple_symbols())
4) Error handling and cleanup¶
import asyncio
from MetaRpcMT5 import MT5Account, ApiExceptionMT5
async def safe_dom_usage():
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"
subscribed = False
try:
# Subscribe
add_result = await account.market_book_add(symbol)
if not add_result.opened_successfully:
print(f"[ERROR] Failed to subscribe to {symbol}")
return
subscribed = True
print(f"[SUBSCRIBED] {symbol} DOM")
# Perform analysis
dom_data = await account.market_book_get(symbol)
print(f"[ANALYSIS] {len(dom_data.mql_book_infos)} levels")
except ApiExceptionMT5 as e:
print(f"[API ERROR] {e}")
except Exception as e:
print(f"[ERROR] Unexpected error: {e}")
finally:
# Always clean up if subscribed
if subscribed:
try:
release_result = await account.market_book_release(symbol)
if release_result.closed_successfully:
print(f"[CLEANUP] {symbol} DOM released successfully")
else:
print(f"[WARNING] Failed to release {symbol} DOM")
except Exception as e:
print(f"[CLEANUP ERROR] {e}")
await account.channel.close()
asyncio.run(safe_dom_usage())
5) Subscription manager class¶
import asyncio
from MetaRpcMT5 import MT5Account
class DOMSubscriptionManager:
def __init__(self, account):
self.account = account
self.active_subscriptions = set()
async def subscribe(self, symbol: str):
"""Subscribe to DOM with tracking"""
result = await self.account.market_book_add(symbol)
if result.opened_successfully:
self.active_subscriptions.add(symbol)
print(f"[SUBSCRIBED] {symbol} (Total: {len(self.active_subscriptions)})")
return True
else:
print(f"[FAILED] Could not subscribe to {symbol}")
return False
async def unsubscribe(self, symbol: str):
"""Unsubscribe from DOM"""
if symbol not in self.active_subscriptions:
print(f"[WARNING] {symbol} not in active subscriptions")
return False
result = await self.account.market_book_release(symbol)
if result.closed_successfully:
self.active_subscriptions.remove(symbol)
print(f"[UNSUBSCRIBED] {symbol} (Remaining: {len(self.active_subscriptions)})")
return True
else:
print(f"[FAILED] Could not unsubscribe from {symbol}")
return False
async def release_all(self):
"""Release all active subscriptions"""
print(f"[RELEASING] All {len(self.active_subscriptions)} subscriptions...")
for symbol in list(self.active_subscriptions):
await self.unsubscribe(symbol)
print(f"[DONE] All subscriptions released")
def list_active(self):
"""List all active subscriptions"""
return list(self.active_subscriptions)
async def main():
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"
)
manager = DOMSubscriptionManager(account)
try:
# Subscribe to multiple symbols
await manager.subscribe("EURUSD")
await manager.subscribe("GBPUSD")
await manager.subscribe("USDJPY")
print(f"\n[ACTIVE] Subscriptions: {manager.list_active()}")
# Do analysis...
await asyncio.sleep(5)
# Release specific symbol
await manager.unsubscribe("GBPUSD")
# Release all remaining
await manager.release_all()
finally:
await account.channel.close()
asyncio.run(main())
6) Temporary DOM snapshot helper¶
import asyncio
from MetaRpcMT5 import MT5Account
async def get_dom_snapshot(account, symbol: str):
"""
Helper function to get a quick DOM snapshot with automatic cleanup.
Subscribe -> Get data -> Release
"""
try:
# Subscribe
add_result = await account.market_book_add(symbol)
if not add_result.opened_successfully:
print(f"[ERROR] Failed to subscribe to {symbol}")
return None
# Get DOM data
dom_data = await account.market_book_get(symbol)
return dom_data
finally:
# Always release
try:
await account.market_book_release(symbol)
except Exception as e:
print(f"[WARNING] Cleanup error: {e}")
async def main():
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:
symbols = ["EURUSD", "GBPUSD", "USDJPY"]
for symbol in symbols:
print(f"\n[SNAPSHOT] Getting {symbol} DOM...")
dom_data = await get_dom_snapshot(account, symbol)
if dom_data:
sell_volume = sum(e.volume_real for e in dom_data.mql_book_infos if e.type in [0, 2])
buy_volume = sum(e.volume_real for e in dom_data.mql_book_infos if e.type in [1, 3])
print(f" Levels: {len(dom_data.mql_book_infos)}")
print(f" BUY volume: {buy_volume:.2f} lots")
print(f" SELL volume: {sell_volume:.2f} lots")
await asyncio.sleep(1) # Brief pause between snapshots
finally:
await account.channel.close()
asyncio.run(main())
📚 See also¶
- MarketBookAdd - Subscribe to DOM updates
- MarketBookGet - Get DOM data
- SymbolSelect - Manage Market Watch symbols