✅ MT5Service - Symbol Methods (Mid-Level API)¶
Important: Read This First¶
MT5Service is an architectural layer between high-level (Sugar) and low-level (Account) APIs.
Understanding the 13 Methods:¶
| Method | Direct Use Value | Architectural Role |
|---|---|---|
get_symbol_params_many() |
VERY HIGH - Aggregates 17 fields + unpacks protobuf list | Used by Sugar |
get_symbol_tick() |
HIGH - Unix timestamp datetime + unpacks 8 fields | Used by Sugar |
get_symbol_session_quote() |
HIGH - 2x protobuf Timestamp datetime | Used by Sugar |
get_symbol_session_trade() |
HIGH - 2x protobuf Timestamp datetime | Used by Sugar |
get_symbol_margin_rate() |
MEDIUM - Unpacks protobuf + creates dataclass | Used by Sugar |
get_symbols_total() |
LOW - Unpacks data.total from protobuf |
Used by Sugar |
symbol_exist() |
LOW - Unpacks (data.exists, data.is_custom) |
Used by Sugar |
get_symbol_name() |
LOW - Unpacks data.name from protobuf |
Used by Sugar |
symbol_select() |
LOW - Unpacks data.success from protobuf |
Used by Sugar |
is_symbol_synchronized() |
LOW - Unpacks data.synchronized from protobuf |
Used by Sugar |
get_symbol_double() |
LOW - Unpacks data.value from protobuf |
Used by Sugar |
get_symbol_integer() |
LOW - Unpacks data.value from protobuf |
Used by Sugar |
get_symbol_string() |
LOW - Unpacks data.value from protobuf |
Used by Sugar |
What This Means:¶
🏗️ Architecture (3 layers):
MT5Sugar (HIGH) service.get_symbol_tick() Sugar uses Service methods
MT5Service (MID) account.symbol_info_tick() Service unpacks protobuf + converts datetime
MT5Account (LOW) gRPC call protobuf Data
Key difference from Account methods:
- ALL symbol methods have value - MT5Account returns protobuf Data objects that need unpacking
- Protobuf unpacking - Service extracts values from
data.value,data.total, etc. - Datetime conversion - 3 methods convert timestamps/protobuf Timestamps to Python datetime
- Dataclass creation - Cleaner API with typed dataclasses instead of protobuf messages
For direct MT5Service usage:
- Use all methods - they all add value through protobuf unpacking
- High-value methods -
get_symbol_params_many(),get_symbol_tick(), session methods - Low-value methods - simple unpacking, but still saves you from manual
data.valueextraction
For MT5Sugar users:
- All methods work perfectly - the layer serves its architectural purpose
API Layer: MID-LEVEL - wrappers over MT5Account with Python native types
Implementation:
These methods are implemented in src/pymt5/mt5_service.py, which wraps package/MetaRpcMT5/helpers/mt5_account.py low-level API with convenient dataclasses and automatic type conversion.
Example files:
examples/2_service/04_service_demo.py- comprehensive demo of all MT5Service methods including symbol information
Why These Methods Exist¶
Real Value: Protobuf Unpacking + Datetime Conversion¶
Unlike Account methods, Symbol methods in MT5Service all add real value because MT5Account returns protobuf Data objects:
Problem with MT5Account (Low-level):
# MT5Account returns protobuf Data objects - need manual unpacking
data = await account.symbol_info_double(
symbol="EURUSD",
property=market_info_pb2.SYMBOL_BID
)
bid = data.value # Manual extraction from protobuf wrapper
# Tick time is Unix timestamp - need manual conversion
tick_data = await account.symbol_info_tick("EURUSD")
tick_time = datetime.fromtimestamp(tick_data.time) # Manual datetime conversion
Solution with MT5Service (Mid-level):
# Service unpacks protobuf automatically - returns native types
bid = await service.get_symbol_double(
symbol="EURUSD",
property=market_info_pb2.SYMBOL_BID
) # Already float, not protobuf Data!
# Tick with datetime already converted
tick = await service.get_symbol_tick("EURUSD")
print(tick.time) # Already datetime object!
What MT5Service provides:
-
Protobuf unpacking (all 13 methods):
-
MT5Account:
return res.data(protobuf object) -
MT5Service:
return data.value(native Python type) -
Datetime conversion (3 methods):
-
get_symbol_tick(): Unix timestampdatetime.fromtimestamp() get_symbol_session_quote(): protobuf TimestampToDatetime()x2-
get_symbol_session_trade(): protobuf TimestampToDatetime()x2 -
Data aggregation (1 method):
-
get_symbol_params_many(): 17 fields in one call instead of 17 separate calls -
Clean dataclasses:
-
SymbolTick,SymbolParams,SessionTime,SymbolMarginRateinstead of protobuf messages
Architectural purpose:
- MT5Sugar uses these methods to maintain layered architecture (Sugar Service Account)
- Direct users also benefit - all methods add value through unpacking and conversion
All 13 Methods¶
| Method | Returns | Description |
|---|---|---|
get_symbols_total() |
int |
Get count of available symbols |
symbol_exist() |
Tuple[bool, bool] |
Check if symbol exists (exists, is_custom) |
get_symbol_name() |
str |
Get symbol name by index |
symbol_select() |
bool |
Add/remove symbol from Market Watch |
is_symbol_synchronized() |
bool |
Check if symbol data is synchronized |
get_symbol_double() |
float |
Get double property (Bid, Ask, Point, etc.) |
get_symbol_integer() |
int |
Get integer property (Digits, Spread, etc.) |
get_symbol_string() |
str |
Get string property (Description, Currency, etc.) |
get_symbol_margin_rate() |
SymbolMarginRate |
Get margin rates for order type |
get_symbol_tick() |
SymbolTick |
Get current tick (time auto-converted to datetime) |
get_symbol_session_quote() |
SessionTime |
Get quote session times (as datetime) |
get_symbol_session_trade() |
SessionTime |
Get trading session times (as datetime) |
get_symbol_params_many() |
Tuple[List[SymbolParams], int] |
Get comprehensive data for multiple symbols |
➕ Dataclasses (DTOs)¶
SymbolTick¶
@dataclass
class SymbolTick:
"""
Current tick information for a symbol.
ADVANTAGE: Time is already converted from Unix timestamp to datetime.
"""
time: datetime # Tick time (converted from Unix timestamp)
bid: float # Current Bid price
ask: float # Current Ask price
last: float # Last deal price
volume: int # Tick volume
time_ms: int # Tick time in milliseconds
flags: int # Tick flags
volume_real: float # Tick volume with decimal precision
SymbolMarginRate¶
@dataclass
class SymbolMarginRate:
"""Margin rate information for a symbol."""
initial_margin_rate: float # Initial margin rate
maintenance_margin_rate: float # Maintenance margin requirement
SessionTime¶
@dataclass
class SessionTime:
"""Trading session time range."""
from_time: datetime # Session start time (already datetime)
to_time: datetime # Session end time (already datetime)
SymbolParams¶
@dataclass
class SymbolParams:
"""
Comprehensive symbol information.
ADVANTAGE: All 17 important symbol parameters in one structure.
Much more convenient than making multiple calls to SymbolInfoDouble/Integer/String.
"""
name: str # Symbol name
bid: float # Current Bid price
ask: float # Current Ask price
last: float # Last deal price
point: float # Point size (minimal price change)
digits: int # Number of decimal places
spread: int # Current spread in points
volume_min: float # Minimum volume for trading
volume_max: float # Maximum volume for trading
volume_step: float # Volume step
trade_tick_size: float # Trade tick size
trade_tick_value: float # Trade tick value
trade_contract_size: float # Contract size
swap_long: float # Swap for long positions
swap_short: float # Swap for short positions
margin_initial: float # Initial margin requirement
margin_maintenance: float # Maintenance margin requirement
Method Signatures¶
1) get_symbols_total¶
async def get_symbols_total(
self,
selected_only: bool,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> int
Get count of available symbols.
Args:
- selected_only: True to count only Market Watch symbols, False for all
Returns: int count directly (no Data struct)
Technical: Low-level returns SymbolsTotalData with data.total wrapper. This auto-extracts the count.
2) symbol_exist¶
async def symbol_exist(
self,
symbol: str,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> Tuple[bool, bool]
Check if symbol exists in terminal.
Args:
- symbol: Symbol name to check
Returns: Tuple[exists, is_custom]
- exists: True if symbol exists
- is_custom: True if custom symbol
3) get_symbol_name¶
async def get_symbol_name(
self,
index: int,
selected_only: bool,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> str
Get symbol name by index position.
Args:
- index: Symbol index (starting at 0)
- selected_only: True to use only Market Watch symbols
Returns: Symbol name string directly
Usage: Iterate through all symbols with range(get_symbols_total()).
4) symbol_select¶
async def symbol_select(
self,
symbol: str,
select: bool,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> bool
Add/remove symbol from Market Watch.
Args:
- symbol: Symbol name
- select: True to add, False to remove
Returns: Success status
5) is_symbol_synchronized¶
async def is_symbol_synchronized(
self,
symbol: str,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> bool
Check if symbol data is synchronized with broker server.
Args:
- symbol: Symbol name to check
Returns: True if synchronized, False otherwise
Usage: Check before requesting tick data to ensure it's up-to-date.
6) get_symbol_double¶
async def get_symbol_double(
self,
symbol: str,
property: market_info_pb2.SymbolInfoDoubleProperty,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> float
Get individual symbol double property.
Available properties:
from MetaRpcMT5 import mt5_term_api_market_info_pb2 as market_info_pb2
# Price properties:
SYMBOL_BID # Current Bid price
SYMBOL_ASK # Current Ask price
SYMBOL_LAST # Last deal price
# Size properties:
SYMBOL_POINT # Point size (0.00001 for EURUSD)
SYMBOL_TRADE_TICK_VALUE # Tick value in deposit currency
SYMBOL_TRADE_TICK_SIZE # Tick size in points
SYMBOL_TRADE_CONTRACT_SIZE # Contract size (100000 for forex)
# Volume properties:
SYMBOL_VOLUME_MIN # Minimum volume
SYMBOL_VOLUME_MAX # Maximum volume
SYMBOL_VOLUME_STEP # Volume step
# Swap properties:
SYMBOL_SWAP_LONG # Swap for long positions
SYMBOL_SWAP_SHORT # Swap for short positions
# Margin properties:
SYMBOL_MARGIN_INITIAL # Initial margin
SYMBOL_MARGIN_MAINTENANCE # Maintenance margin
Returns: float value directly
Technical: Low-level returns SymbolInfoDoubleResponse with data.value. This extracts the float.
7) get_symbol_integer¶
async def get_symbol_integer(
self,
symbol: str,
property: market_info_pb2.SymbolInfoIntegerProperty,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> int
Get individual symbol integer property.
Available properties:
SYMBOL_DIGITS # Number of decimal places (5 for EURUSD)
SYMBOL_SPREAD # Current spread in points
SYMBOL_TRADE_MODE # Trade mode (0=disabled, 4=full)
SYMBOL_TRADE_EXEMODE # Execution mode (instant/market/exchange)
SYMBOL_START_TIME # Symbol start time (Unix timestamp)
SYMBOL_EXPIRATION_TIME # Symbol expiration time (Unix timestamp)
SYMBOL_FILLING_MODE # Filling mode flags
SYMBOL_ORDER_MODE # Allowed order types flags
Returns: int value directly
8) get_symbol_string¶
async def get_symbol_string(
self,
symbol: str,
property: market_info_pb2.SymbolInfoStringProperty,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> str
Get individual symbol string property.
Available properties:
SYMBOL_DESCRIPTION # Symbol description ("Euro vs US Dollar")
SYMBOL_CURRENCY_BASE # Base currency ("EUR" for EURUSD)
SYMBOL_CURRENCY_PROFIT # Profit currency ("USD" for EURUSD)
SYMBOL_CURRENCY_MARGIN # Margin currency
SYMBOL_BANK # Source of quotes
SYMBOL_ISIN # ISIN code
SYMBOL_CATEGORY # Symbol category (Forex, Stocks, etc.)
SYMBOL_PATH # Path in symbol tree
Returns: str value directly
9) get_symbol_margin_rate¶
async def get_symbol_margin_rate(
self,
symbol: str,
order_type: market_info_pb2.ENUM_ORDER_TYPE,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> SymbolMarginRate
Get margin rates for a symbol and order type.
Args:
- symbol: Symbol name
- order_type: Order type (BUY, SELL, etc.)
Returns: SymbolMarginRate dataclass with initial and maintenance rates
10) get_symbol_tick¶
async def get_symbol_tick(
self,
symbol: str,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> SymbolTick
Get current market prices for a symbol.
Returns: SymbolTick dataclass with time already converted to datetime
Technical: Low-level returns SymbolInfoTickData with Unix timestamp (data.time). This wrapper converts time field from Unix seconds to Python datetime via fromtimestamp().
Advantage: No manual timestamp conversion needed - just use tick.time as datetime object!
11) get_symbol_session_quote¶
async def get_symbol_session_quote(
self,
symbol: str,
day_of_week: market_info_pb2.DayOfWeek,
session_index: int,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> SessionTime
Get quote session times.
Args:
- symbol: Symbol name
- day_of_week: Day of the week (MONDAY, TUESDAY, etc.)
- session_index: Session index (starting at 0, most symbols have 1 session)
Returns: SessionTime with start/end times as datetime
Technical: Low-level returns protobuf Timestamps. This wrapper converts both to Python datetimes via ToDatetime().
12) get_symbol_session_trade¶
async def get_symbol_session_trade(
self,
symbol: str,
day_of_week: market_info_pb2.DayOfWeek,
session_index: int,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> SessionTime
Get trading session times.
Args:
- symbol: Symbol name
- day_of_week: Day of the week
- session_index: Session index (starting at 0)
Returns: SessionTime with start/end times as datetime
Usage: Shows when you can trade the symbol (different from quote session which shows when prices are updated).
13) get_symbol_params_many¶
async def get_symbol_params_many(
self,
name_filter: Optional[str] = None,
sort_mode: Optional[int] = None,
page_number: Optional[int] = None,
items_per_page: Optional[int] = None,
deadline: Optional[datetime] = None,
cancellation_event: Optional[Any] = None,
) -> Tuple[List[SymbolParams], int]
Get parameters of multiple symbols at once.
Args:
- name_filter: Optional symbol name filter (e.g., "EUR*" for all EUR pairs)
- sort_mode: Optional sort mode
- page_number: Optional page number for pagination
- items_per_page: Optional items per page
Returns: Tuple[List[SymbolParams], total_count]
Technical: Low-level returns protobuf repeated field. This wrapper unpacks each SymbolInfo into SymbolParams dataclass with 17 fields.
Advantage: Much faster than 17 separate SymbolInfoDouble/Integer/String calls per symbol!
🔗 Usage Examples¶
Example 1: Getting Symbol Tick with Auto-Converted Time¶
async def monitor_tick(service: MT5Service, symbol: str):
# Get tick - time is already datetime!
tick = await service.get_symbol_tick(symbol)
print(f"Symbol: {symbol}")
print(f"Time: {tick.time.strftime('%Y-%m-%d %H:%M:%S')}") # Already datetime
print(f"Bid: {tick.bid:.5f}")
print(f"Ask: {tick.ask:.5f}")
print(f"Last: {tick.last:.5f}")
print(f"Volume: {tick.volume}")
# No manual timestamp conversion needed!
Example 2: Checking Symbol Availability¶
async def check_symbol(service: MT5Service, symbol: str):
exists, is_custom = await service.symbol_exist(symbol)
if not exists:
print(f"Symbol {symbol} does not exist")
return False
if is_custom:
print(f"{symbol} is a custom symbol")
# Check if synchronized
synced = await service.is_symbol_synchronized(symbol)
if not synced:
print(f"WARNING: {symbol} data is not synchronized")
return False
print(f"{symbol} is available and synchronized")
return True
Example 3: Getting Trading Session Times¶
from MetaRpcMT5 import mt5_term_api_market_info_pb2 as market_info_pb2
async def check_trading_hours(service: MT5Service, symbol: str):
"""Check if symbol is currently in trading session."""
from datetime import datetime
now = datetime.now()
day_of_week = market_info_pb2.DayOfWeek.Value(
f"DAY_{now.strftime('%A').upper()}"
)
try:
# Get trading session for today (session_index=0 for main session)
session = await service.get_symbol_session_trade(
symbol=symbol,
day_of_week=day_of_week,
session_index=0
)
print(f"Trading session for {symbol} today:")
print(f" From: {session.from_time.strftime('%H:%M:%S')}")
print(f" To: {session.to_time.strftime('%H:%M:%S')}")
# Times are already datetime objects!
if session.from_time <= now <= session.to_time:
print(" Status: OPEN")
else:
print(" Status: CLOSED")
except Exception as e:
print(f"No trading session for {symbol} today: {e}")
Example 4: Bulk Symbol Data Retrieval (get_symbol_params_many)¶
async def get_all_eur_symbols(service: MT5Service):
"""Get comprehensive data for all EUR symbols efficiently."""
# Get all symbols starting with "EUR" in one call
symbols, total = await service.get_symbol_params_many(
name_filter="EUR*",
items_per_page=100
)
print(f"Found {total} EUR symbols\n")
for sym in symbols:
print(f"{sym.name}:")
print(f" Bid: {sym.bid:.5f}, Ask: {sym.ask:.5f}")
print(f" Spread: {sym.spread} points")
print(f" Digits: {sym.digits}")
print(f" Volume: {sym.volume_min} - {sym.volume_max} (step: {sym.volume_step})")
print(f" Contract size: {sym.trade_contract_size}")
print(f" Swap long/short: {sym.swap_long}/{sym.swap_short}")
print()
# This is MUCH faster than calling get_symbol_double/integer/string
# 17 times for each symbol!
When to Use Which Method¶
Use get_symbol_tick()¶
Use when: - You need current Bid/Ask prices with timestamp - Want complete tick data in one call - Need time as datetime (auto-converted)
Example:
Use get_symbol_double/integer/string()¶
Use when: - You need ONE specific property - Writing validation checks - Performance matters (single property faster than tick)
Example:
Use get_symbol_params_many()¶
Use when: - You need data for MULTIPLE symbols - Building symbol scanner/screener - Need comprehensive symbol info (17 fields) - Want to minimize API calls
Example:
# Get all forex symbols at once
symbols, _ = await service.get_symbol_params_many(name_filter="*USD")
Advantage: 100x faster than individual calls for each symbol!
Recommendations¶
- For current prices + time - use
get_symbol_tick()(Bid/Ask + datetime in one call, no manual unpacking) - For multiple symbols - use
get_symbol_params_many()(17 fields per symbol in one call - 100x faster!) - For single property - use
get_symbol_double/integer/string()(unpacks protobufdata.valuefor you) - For session times - use
get_symbol_session_quote/trade()(datetime conversion included) - Before trading - always check with
symbol_exist()andis_symbol_synchronized()(cleaner than manual protobuf)
Bottom line: Use MT5Service for all symbol operations - it unpacks protobuf Data objects and converts datetime automatically.
📚 Related Sections¶
- MT5Service Overview - mid-level API overview
- Account Methods (Mid-Level) - account information methods
- Trading Methods (Mid-Level) - trading methods
- Streaming Methods (Mid-Level) - real-time tick streaming
- Symbol Information (Low-Level) - low-level symbol API
- MT5Service API Reference - complete mid-level API reference
Summary¶
Real value for end users:
- ALL 13 methods add value - MT5Account returns protobuf Data objects that need unpacking
- get_symbol_params_many() - Aggregates 17 fields in one call (100x faster for multiple symbols)
- get_symbol_tick() - Unix timestamp datetime + unpacks 8 fields
- get_symbol_session_quote/trade() - Protobuf Timestamps datetime x2
- Other 9 methods - Protobuf unpacking (data.value native type)
Architectural layer (for MT5Sugar):
- All methods used by MT5Sugar to maintain layered architecture (Sugar Service Account)
- Provides unified interface with consistent naming (get_* prefix)
Key difference from Account methods: - Account methods: MT5Account already returns native types Service adds no value (just pass-through) - Symbol methods: MT5Account returns protobuf Data Service unpacks + converts real value
Recommendation:
- Using MT5Sugar? These methods work seamlessly through the architecture
- Using MT5Service directly? All methods add value - use them all!
- High priority: get_symbol_params_many(), get_symbol_tick(), session methods
- Medium priority: Other methods save you from manual protobuf unpacking