✅ Check if Symbol Data is Synchronized¶
Request: verify if symbol data in terminal is synchronized with trade server. Ensures you're working with up-to-date market information.
API Information:
- SDK wrapper:
MT5Account.symbolIsSynchronized(...)(from packageio.metarpc.mt5) - gRPC service:
mt5_term_api.MarketInfo - Proto definition:
SymbolIsSynchronized(defined inmt5-term-api-market-info.proto)
RPC¶
- Service:
mt5_term_api.MarketInfo - Method:
SymbolIsSynchronized(SymbolIsSynchronizedRequest) → SymbolIsSynchronizedReply - Low‑level client (generated):
MarketInfoGrpc.MarketInfoBlockingStub.symbolIsSynchronized(request) - SDK wrapper (high-level):
package io.metarpc.mt5;
public class MT5Account {
/**
* Checks if symbol data in the terminal is synchronized with the trade server.
* Returns true if data is synchronized and up-to-date, false otherwise.
*
* @param symbol Symbol name to check (e.g., "EURUSD")
* @return Synchronization status
* @throws ApiExceptionMT5 if the call fails or connection is lost
*/
public Mt5TermApiMarketInfo.SymbolIsSynchronizedReply symbolIsSynchronized(String symbol) throws ApiExceptionMT5;
}
Request message: SymbolIsSynchronizedRequest { symbol: string }
Reply message: SymbolIsSynchronizedReply { data: SymbolIsSynchronizedData } or { error: Error }
🔽 Input¶
| Parameter | Type | Required | Description |
|---|---|---|---|
symbol |
String |
✅ | Symbol name (e.g., "EURUSD", "XAUUSD") |
⬆️ Output - SymbolIsSynchronizedData¶
| Field | Type | Description |
|---|---|---|
synchronized |
boolean |
true if data is synchronized, false if outdated |
Access using reply.getData().getSynchronized().
💬 Just the essentials¶
- What it is. RPC to check if terminal has up-to-date symbol data from server.
- Why you need it. Ensure prices and symbol properties are current before trading.
- When false. Data may be outdated due to connection issues or terminal startup.
- Performance. Quick validation call before critical trading operations.
🎯 Purpose¶
Use this method when you need to:
- Verify data freshness before placing orders.
- Check if terminal finished loading symbol data after connection.
- Diagnose why quotes appear stale or frozen.
- Validate data quality for trading algorithms.
- Ensure accurate price data for backtesting or analysis.
🧩 Notes & Tips¶
- Symbol must be selected in MarketWatch for this check.
- Returns
falseduring terminal startup while data is loading. - Check this after connection before getting critical market data.
- The method uses automatic reconnection via
executeWithReconnect(). - If
false, wait a moment and retry - synchronization may be in progress.
🔗 Usage Examples¶
1) Basic synchronization check¶
import io.metarpc.mt5.MT5Account;
import io.metarpc.mt5.exceptions.ApiExceptionMT5;
import mt5_term_api.Mt5TermApiMarketInfo;
public class Example {
public static void main(String[] args) {
MT5Account account = new MT5Account(12345678, "password");
try {
account.connect("demo.mt5server.com", 443, "EURUSD");
// Check synchronization
Mt5TermApiMarketInfo.SymbolIsSynchronizedReply reply =
account.symbolIsSynchronized("EURUSD");
boolean synced = reply.getData().getSynchronized();
if (synced) {
System.out.println("✅ EURUSD data is synchronized");
} else {
System.out.println("⚠️ EURUSD data is NOT synchronized");
}
} catch (ApiExceptionMT5 e) {
System.err.println("Error: " + e.getMessage());
} finally {
account.close();
}
}
}
2) Wait for synchronization¶
public class SyncWaiter {
/**
* Wait for symbol to synchronize (with timeout)
*/
public static boolean waitForSync(
MT5Account account,
String symbol,
int timeoutSeconds) throws ApiExceptionMT5, InterruptedException {
System.out.printf("Waiting for %s to synchronize...%n", symbol);
long startTime = System.currentTimeMillis();
long timeoutMillis = timeoutSeconds * 1000L;
while (System.currentTimeMillis() - startTime < timeoutMillis) {
var reply = account.symbolIsSynchronized(symbol);
if (reply.getData().getSynchronized()) {
System.out.println("✅ Synchronized");
return true;
}
System.out.print(".");
Thread.sleep(500); // Wait 500ms before retry
}
System.out.println("\n⚠️ Timeout - not synchronized");
return false;
}
}
// Usage
if (SyncWaiter.waitForSync(account, "EURUSD", 10)) {
// Safe to proceed
var tick = account.quote("EURUSD");
System.out.printf("Bid: %.5f%n", tick.getData().getBid());
}
3) Pre-trade validation¶
public class TradeValidator {
/**
* Validate symbol before trading
*/
public static boolean validateSymbol(
MT5Account account,
String symbol) throws ApiExceptionMT5 {
System.out.printf("Validating %s...%n", symbol);
// Check existence
var existReply = account.symbolExist(symbol);
if (!existReply.getData().getExists()) {
System.out.println("❌ Symbol does not exist");
return false;
}
System.out.println("✅ Symbol exists");
// Select symbol
var selectReply = account.symbolSelect(symbol, true);
if (!selectReply.getData().getSuccess()) {
System.out.println("❌ Failed to select symbol");
return false;
}
System.out.println("✅ Symbol selected");
// Check synchronization
var syncReply = account.symbolIsSynchronized(symbol);
if (!syncReply.getData().getSynchronized()) {
System.out.println("⚠️ Symbol not synchronized - data may be outdated");
return false;
}
System.out.println("✅ Symbol synchronized");
return true;
}
}
// Usage
if (TradeValidator.validateSymbol(account, "GBPUSD")) {
System.out.println("Ready to trade GBPUSD");
// Place order
}
4) Check multiple symbols¶
public class MultiSymbolSync {
public record SyncStatus(
String symbol,
boolean synchronized,
String message
) {}
/**
* Check sync status for multiple symbols
*/
public static java.util.List<SyncStatus> checkMultiple(
MT5Account account,
String... symbols) {
java.util.List<SyncStatus> results = new java.util.ArrayList<>();
for (String symbol : symbols) {
try {
var reply = account.symbolIsSynchronized(symbol);
boolean synced = reply.getData().getSynchronized();
results.add(new SyncStatus(
symbol,
synced,
synced ? "Synchronized" : "Not synchronized"
));
} catch (ApiExceptionMT5 e) {
results.add(new SyncStatus(
symbol,
false,
"Error: " + e.getMessage()
));
}
}
return results;
}
/**
* Print sync status report
*/
public static void printReport(java.util.List<SyncStatus> results) {
System.out.println("\n╔═════════════════════════════════════╗");
System.out.println("║ SYMBOL SYNCHRONIZATION STATUS ║");
System.out.println("╠═════════════════════════════════════╣");
for (var status : results) {
String icon = status.synchronized() ? "✅" : "⚠️";
System.out.printf("║ %s %-10s %-20s ║%n",
icon,
status.symbol(),
status.message()
);
}
long syncedCount = results.stream()
.filter(SyncStatus::synchronized)
.count();
System.out.println("╠═════════════════════════════════════╣");
System.out.printf("║ Synchronized: %d/%d ║%n",
syncedCount, results.size());
System.out.println("╚═════════════════════════════════════╝");
}
}
// Usage
var statuses = MultiSymbolSync.checkMultiple(account,
"EURUSD", "GBPUSD", "USDJPY", "XAUUSD"
);
MultiSymbolSync.printReport(statuses);
5) Retry with exponential backoff¶
public class SyncRetry {
/**
* Wait for sync with exponential backoff
*/
public static boolean waitWithBackoff(
MT5Account account,
String symbol,
int maxRetries) throws ApiExceptionMT5 {
int retryDelay = 100; // Start with 100ms
for (int retry = 0; retry < maxRetries; retry++) {
var reply = account.symbolIsSynchronized(symbol);
if (reply.getData().getSynchronized()) {
System.out.printf("✅ %s synchronized (attempt %d/%d)%n",
symbol, retry + 1, maxRetries);
return true;
}
System.out.printf("⏳ Attempt %d/%d - waiting %dms...%n",
retry + 1, maxRetries, retryDelay);
try {
Thread.sleep(retryDelay);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
// Exponential backoff: 100ms, 200ms, 400ms, 800ms, ...
retryDelay = Math.min(retryDelay * 2, 5000); // Cap at 5 seconds
}
System.out.printf("❌ %s failed to synchronize after %d attempts%n",
symbol, maxRetries);
return false;
}
}
// Usage
if (SyncRetry.waitWithBackoff(account, "EURUSD", 5)) {
// Proceed with trading
}
6) Connection health check¶
public class ConnectionHealth {
/**
* Check overall connection health via symbol sync
*/
public static boolean isConnectionHealthy(
MT5Account account,
String... testSymbols) throws ApiExceptionMT5 {
if (testSymbols.length == 0) {
testSymbols = new String[]{"EURUSD"};
}
int syncedCount = 0;
for (String symbol : testSymbols) {
var reply = account.symbolIsSynchronized(symbol);
if (reply.getData().getSynchronized()) {
syncedCount++;
}
}
double syncRate = (double) syncedCount / testSymbols.length;
boolean healthy = syncRate >= 0.8; // 80% threshold
System.out.printf("Connection health: %.0f%% (%d/%d symbols synced)%n",
syncRate * 100, syncedCount, testSymbols.length);
if (!healthy) {
System.out.println("⚠️ Connection may be unstable");
}
return healthy;
}
}
// Usage - check major pairs
boolean healthy = ConnectionHealth.isConnectionHealthy(account,
"EURUSD", "GBPUSD", "USDJPY", "USDCHF"
);
7) Symbol readiness validator¶
public class SymbolReadiness {
public enum Status {
READY,
NOT_SELECTED,
NOT_SYNCHRONIZED,
ERROR
}
public record ReadinessResult(
String symbol,
Status status,
String message
) {
public boolean isReady() {
return status == Status.READY;
}
}
/**
* Check if symbol is ready for trading
*/
public static ReadinessResult checkReadiness(
MT5Account account,
String symbol) {
try {
// Check if selected
var intReply = account.symbolInfoInteger(
symbol,
Mt5TermApiMarketInfo.SymbolInfoIntegerProperty.SYMBOL_SELECT
);
if (intReply.getData().getValue() == 0) {
return new ReadinessResult(
symbol,
Status.NOT_SELECTED,
"Symbol not in MarketWatch"
);
}
// Check synchronization
var syncReply = account.symbolIsSynchronized(symbol);
if (!syncReply.getData().getSynchronized()) {
return new ReadinessResult(
symbol,
Status.NOT_SYNCHRONIZED,
"Symbol data not synchronized"
);
}
return new ReadinessResult(
symbol,
Status.READY,
"Symbol ready for trading"
);
} catch (ApiExceptionMT5 e) {
return new ReadinessResult(
symbol,
Status.ERROR,
"Error: " + e.getMessage()
);
}
}
/**
* Ensure symbol is ready (auto-fix if possible)
*/
public static boolean ensureReady(
MT5Account account,
String symbol) throws ApiExceptionMT5, InterruptedException {
var readiness = checkReadiness(account, symbol);
switch (readiness.status()) {
case READY:
System.out.printf("✅ %s is ready%n", symbol);
return true;
case NOT_SELECTED:
System.out.printf("⚙️ Selecting %s...%n", symbol);
account.symbolSelect(symbol, true);
Thread.sleep(500);
return ensureReady(account, symbol); // Retry
case NOT_SYNCHRONIZED:
System.out.printf("⏳ Waiting for %s to synchronize...%n", symbol);
return SyncWaiter.waitForSync(account, symbol, 10);
case ERROR:
System.out.printf("❌ %s: %s%n", symbol, readiness.message());
return false;
default:
return false;
}
}
}
// Usage
if (SymbolReadiness.ensureReady(account, "XAUUSD")) {
System.out.println("Ready to trade gold");
}
8) Data quality monitor¶
public class DataQualityMonitor {
/**
* Monitor data quality in real-time
*/
public static void monitor(
MT5Account account,
String symbol,
int durationSeconds) throws InterruptedException {
System.out.printf("Monitoring %s data quality for %d seconds...%n",
symbol, durationSeconds);
System.out.println("═".repeat(50));
long startTime = System.currentTimeMillis();
long endTime = startTime + (durationSeconds * 1000L);
int checkCount = 0;
int syncedCount = 0;
while (System.currentTimeMillis() < endTime) {
try {
var reply = account.symbolIsSynchronized(symbol);
boolean synced = reply.getData().getSynchronized();
checkCount++;
if (synced) syncedCount++;
String status = synced ? "✅ SYNCED" : "⚠️ NOT SYNCED";
System.out.printf("[%s] Check %d: %s%n",
java.time.LocalTime.now(),
checkCount,
status
);
Thread.sleep(1000); // Check every second
} catch (ApiExceptionMT5 e) {
System.out.printf("❌ Error: %s%n", e.getMessage());
}
}
double reliability = (syncedCount * 100.0) / checkCount;
System.out.println("═".repeat(50));
System.out.printf("Reliability: %.1f%% (%d/%d checks synced)%n",
reliability, syncedCount, checkCount);
}
}
// Usage
DataQualityMonitor.monitor(account, "EURUSD", 30);
🔄 Low-level gRPC call (for reference)¶
import io.grpc.*;
import mt5_term_api.*;
// Create request
Mt5TermApiMarketInfo.SymbolIsSynchronizedRequest request =
Mt5TermApiMarketInfo.SymbolIsSynchronizedRequest.newBuilder()
.setSymbol("EURUSD")
.build();
// Add metadata headers
Metadata headers = new Metadata();
Metadata.Key<String> idKey = Metadata.Key.of("id", Metadata.ASCII_STRING_MARSHALLER);
headers.put(idKey, instanceId.toString());
// Call service
Mt5TermApiMarketInfo.SymbolIsSynchronizedReply reply = marketInfoClient
.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(headers))
.symbolIsSynchronized(request);
// Check for errors
if (reply.hasError()) {
throw new ApiExceptionMT5(reply.getError());
}
// Use data
boolean synchronized = reply.getData().getSynchronized();