copper-mind / app /instruments.py
ifieryarrows's picture
Sync from GitHub (tests passed)
964ddf9 verified
"""Canonical instrument identifiers used across API, training and UI metadata."""
TARGET_SYMBOL = "HG=F"
TARGET_DISPLAY_NAME = "COMEX Copper Futures"
TARGET_PROVIDER = "yfinance"
TARGET_TRADINGVIEW_SYMBOL = "COMEX:HG1!"
TARGET_TRADINGVIEW_EXCHANGE = "COMEX"
TARGET_TRADINGVIEW_TICKER = "HG1!"
TARGET_YAHOO_STREAM_SYMBOL = TARGET_SYMBOL
SPOT_COPPER_SYMBOLS = {"XCU/USD", "XCUUSD", "XCU=X"}
SPOT_COPPER_DISPLAY_NAME = "Copper spot (XCU/USD)"
PROVIDER_SYMBOLS = {
"canonical": TARGET_SYMBOL,
"yahoo": TARGET_YAHOO_STREAM_SYMBOL,
"yfinance": TARGET_YAHOO_STREAM_SYMBOL,
"yahoo_websocket": TARGET_YAHOO_STREAM_SYMBOL,
"tradingview": TARGET_TRADINGVIEW_SYMBOL,
"tradingview_ws": TARGET_TRADINGVIEW_SYMBOL,
"tradingview_exchange": TARGET_TRADINGVIEW_EXCHANGE,
"tradingview_ticker": TARGET_TRADINGVIEW_TICKER,
}
_COPPER_ALIASES = {
TARGET_SYMBOL.upper(): TARGET_SYMBOL,
TARGET_TRADINGVIEW_SYMBOL.upper(): TARGET_SYMBOL,
TARGET_TRADINGVIEW_TICKER.upper(): TARGET_SYMBOL,
}
def canonicalize_instrument_symbol(symbol: str | None) -> str:
"""Normalize known copper aliases to the project canonical symbol."""
if not symbol:
return TARGET_SYMBOL
return _COPPER_ALIASES.get(symbol.strip().upper(), symbol.strip())
def resolve_provider_symbol(symbol: str | None, provider: str) -> str:
"""Resolve the requested instrument into the provider-specific symbol format."""
canonical = canonicalize_instrument_symbol(symbol)
if canonical == TARGET_SYMBOL:
return PROVIDER_SYMBOLS.get(provider.lower(), TARGET_SYMBOL)
return canonical