|
@@ -6,6 +6,7 @@ from datetime import datetime, timezone
|
|
|
from argus_mcp.config import ArgusConfig, load_config
|
|
from argus_mcp.config import ArgusConfig, load_config
|
|
|
from argus_mcp.models import MarketQuote, RegimeSnapshot
|
|
from argus_mcp.models import MarketQuote, RegimeSnapshot
|
|
|
from argus_mcp.providers.finnhub import FinnhubProvider
|
|
from argus_mcp.providers.finnhub import FinnhubProvider
|
|
|
|
|
+from argus_mcp.providers.metals_mcp import MetalsMcpProvider
|
|
|
from argus_mcp.providers.twelve_data import TwelveDataProvider
|
|
from argus_mcp.providers.twelve_data import TwelveDataProvider
|
|
|
from argus_mcp.regime import build_regime_snapshot
|
|
from argus_mcp.regime import build_regime_snapshot
|
|
|
from argus_mcp.storage import SnapshotStore
|
|
from argus_mcp.storage import SnapshotStore
|
|
@@ -16,6 +17,7 @@ from argus_mcp.symbols import get_symbol_spec
|
|
|
class ArgusService:
|
|
class ArgusService:
|
|
|
config: ArgusConfig
|
|
config: ArgusConfig
|
|
|
store: SnapshotStore
|
|
store: SnapshotStore
|
|
|
|
|
+ metals: MetalsMcpProvider
|
|
|
finnhub: FinnhubProvider
|
|
finnhub: FinnhubProvider
|
|
|
twelve_data: TwelveDataProvider
|
|
twelve_data: TwelveDataProvider
|
|
|
_last_source_status: dict[str, str] = field(default_factory=dict, init=False, repr=False)
|
|
_last_source_status: dict[str, str] = field(default_factory=dict, init=False, repr=False)
|
|
@@ -26,12 +28,14 @@ class ArgusService:
|
|
|
return cls(
|
|
return cls(
|
|
|
config=cfg,
|
|
config=cfg,
|
|
|
store=SnapshotStore(cfg.sqlite_path),
|
|
store=SnapshotStore(cfg.sqlite_path),
|
|
|
|
|
+ metals=MetalsMcpProvider(cfg.metals_mcp_url),
|
|
|
finnhub=FinnhubProvider(cfg.finnhub_token),
|
|
finnhub=FinnhubProvider(cfg.finnhub_token),
|
|
|
twelve_data=TwelveDataProvider(cfg.twelve_data_key),
|
|
twelve_data=TwelveDataProvider(cfg.twelve_data_key),
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
def provider_summary(self) -> dict[str, bool]:
|
|
def provider_summary(self) -> dict[str, bool]:
|
|
|
return {
|
|
return {
|
|
|
|
|
+ "metals_mcp": self.metals.enabled,
|
|
|
"finnhub": self.finnhub.enabled,
|
|
"finnhub": self.finnhub.enabled,
|
|
|
"twelve_data": self.twelve_data.enabled,
|
|
"twelve_data": self.twelve_data.enabled,
|
|
|
}
|
|
}
|
|
@@ -73,10 +77,23 @@ class ArgusService:
|
|
|
async def fetch_quotes(self) -> list[MarketQuote]:
|
|
async def fetch_quotes(self) -> list[MarketQuote]:
|
|
|
quotes: list[MarketQuote] = []
|
|
quotes: list[MarketQuote] = []
|
|
|
source_status: dict[str, str] = {}
|
|
source_status: dict[str, str] = {}
|
|
|
|
|
+ metals_specs = [get_symbol_spec(symbol) for symbol in self.config.symbols if get_symbol_spec(symbol).metals_mcp]
|
|
|
|
|
+ metals_results: dict[str, MarketQuote | None] = {}
|
|
|
|
|
+ if metals_specs and self.metals.enabled:
|
|
|
|
|
+ requested = [spec.metals_mcp or spec.canonical for spec in metals_specs]
|
|
|
|
|
+ metals_results = await self.metals.fetch_quotes(requested)
|
|
|
for symbol in self.config.symbols:
|
|
for symbol in self.config.symbols:
|
|
|
spec = get_symbol_spec(symbol)
|
|
spec = get_symbol_spec(symbol)
|
|
|
quote = None
|
|
quote = None
|
|
|
|
|
|
|
|
|
|
+ if spec.metals_mcp:
|
|
|
|
|
+ quote = metals_results.get(spec.metals_mcp or spec.canonical)
|
|
|
|
|
+ source_status[f"{spec.canonical}:metals_mcp"] = "fetched:metals_mcp" if quote is not None else "missing:metals_mcp"
|
|
|
|
|
+ if quote is not None:
|
|
|
|
|
+ quote.symbol = spec.canonical
|
|
|
|
|
+ quotes.append(quote)
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
if spec.finnhub:
|
|
if spec.finnhub:
|
|
|
quote, status = await self._fetch_or_cache(
|
|
quote, status = await self._fetch_or_cache(
|
|
|
spec.canonical,
|
|
spec.canonical,
|