diff --git a/mt5bridge_ccxt/symbol.py b/mt5bridge_ccxt/symbol.py new file mode 100644 index 0000000..b4ec4bc --- /dev/null +++ b/mt5bridge_ccxt/symbol.py @@ -0,0 +1,64 @@ +"""Symbol conversion utilities. + +CCXT uses 'BASE/QUOTE' format (e.g. "XAU/USD"). +MT5 uses broker-specific names (e.g. "XAUUSD", "XAUUSDc", "XAUUSD.i"). + +The wrapper supports two strategies: +1. User-provided symbol_map in config (recommended, explicit) +2. Default: strip the "/" and concatenate (works for plain symbols) +""" + +# Common quote currencies in forex/metals +COMMON_QUOTES = [ + "USD", "EUR", "GBP", "JPY", "CHF", "CAD", "AUD", "NZD", + "CNY", "HKD", "SGD", "XAU", "XAG", "XPT", "XPD", +] + + +def to_mt5_symbol(symbol, default_suffix=""): + """Convert CCXT symbol (XAU/USD) to MT5 format (XAUUSD). + + Args: + symbol: CCXT-format symbol (e.g. "XAU/USD" or "XAUUSDc") + default_suffix: suffix to append when no symbol_map is provided + (e.g. "c" for ECN, ".i" for CFD indices) + + Returns: + str: MT5-format symbol + """ + # Already in MT5 format (no slash) + if "/" not in symbol: + return symbol + + base, quote = symbol.split("/", 1) + return f"{base}{quote}{default_suffix}" + + +def to_ccxt_symbol(symbol, quote=None): + """Best-effort conversion from MT5 symbol to CCXT format. + + Args: + symbol: MT5 symbol (e.g. "XAUUSDc") + quote: Optional explicit quote currency to split on + + Returns: + str: CCXT symbol (e.g. "XAU/USD" or original if cannot split) + """ + # Strip common suffixes + cleaned = symbol + for suffix in ("c", ".i", ".m", ".pro", ".ecn", ".raw", ".std"): + if cleaned.endswith(suffix): + cleaned = cleaned[: -len(suffix)] + break + + # Try explicit quote first + if quote and cleaned.endswith(quote) and len(cleaned) > len(quote): + return f"{cleaned[: -len(quote)]}/{quote}" + + # Try common quotes + for q in COMMON_QUOTES: + if cleaned.endswith(q) and len(cleaned) > len(q): + return f"{cleaned[: -len(q)]}/{q}" + + # Cannot split reliably + return symbol