"""Data Collector Service entry point.""" import asyncio from shared.broker import RedisBroker from shared.db import Database from shared.healthcheck import HealthCheckServer from shared.logging import setup_logging from shared.metrics import ServiceMetrics from shared.notifier import TelegramNotifier from data_collector.binance_ws import BinanceWebSocket from data_collector.config import CollectorConfig from data_collector.storage import CandleStorage async def run() -> None: """Initialise all components and start the WebSocket collector.""" config = CollectorConfig() log = setup_logging("data-collector", config.log_level, config.log_format) metrics = ServiceMetrics("data_collector") notifier = TelegramNotifier( bot_token=config.telegram_bot_token, chat_id=config.telegram_chat_id ) db = Database(config.database_url) await db.connect() await db.init_tables() broker = RedisBroker(config.redis_url) storage = CandleStorage(db=db, broker=broker) async def on_candle(candle): log.info( "candle_received", symbol=candle.symbol, timeframe=candle.timeframe, open_time=str(candle.open_time), ) await storage.store(candle) metrics.events_processed.labels(service="data-collector", event_type="candle").inc() # Use the first configured timeframe for the WebSocket subscription. timeframe = config.timeframes[0] if config.timeframes else "1m" ws = BinanceWebSocket( symbols=config.symbols, timeframe=timeframe, on_candle=on_candle, ) health = HealthCheckServer("data-collector", port=config.health_port) health.register_check("redis", broker.ping) await health.start() metrics.service_up.labels(service="data-collector").set(1) log.info( "service_started", symbols=config.symbols, timeframe=timeframe, ) try: await ws.start() except Exception as exc: log.error("fatal_error", error=str(exc)) await notifier.send_error(str(exc), "data-collector") raise finally: metrics.service_up.labels(service="data-collector").set(0) await notifier.close() await broker.close() await db.close() def main() -> None: asyncio.run(run()) if __name__ == "__main__": main()