import yfinance as yf from datetime import datetime, timedelta import logging class ForexDataHandler: def __init__(self): """ Инициализация обработчика валютных данных """ self.logger = logging.getLogger(__name__) # logging.basicConfig(level=logging.INFO) self.logger = logging.getLogger(__name__) # logging.basicConfig(level=logging.INFO) # Словари с тикерами self.russian_indices = { 'IMOEX': 'IMOEX.ME', # Индекс МосБиржи 'RTSI': 'RTSI.ME', # Индекс РТС 'MOEXBC': 'MOEXBC.ME' # Индекс голубых фишек } self.russian_sectors = { 'oil_gas': 'MOEXOG.ME', # Нефть и газ 'finance': 'MOEXFN.ME', # Финансы 'telecom': 'MOEXTL.ME', # Телекоммуникации 'metals': 'MOEXMM.ME', # Металлы и добыча 'consumer': 'MOEXCN.ME', # Потребительский сектор 'transport': 'MOEXTN.ME' # Транспорт } self.russian_stocks = { 'Gazprom': 'GAZP.ME', 'Sberbank': 'SBER.ME', 'Lukoil': 'LKOH.ME', 'Rosneft': 'ROSN.ME', 'VTB': 'VTBR.ME' } def get_forex_rate(self, from_currency: str, to_currency: str) -> dict: """ Получает текущий курс валют с Yahoo Finance Args: from_currency: исходная валюта (например, 'USD') to_currency: целевая валюта (например, 'RUB') Returns: dict: Словарь с данными о курсе валют """ try: # Формируем тикер для валютной пары ticker = f"{from_currency}{to_currency}=X" self.logger.info(f"Получение данных для пары {ticker}") currency_pair = yf.Ticker(ticker) # Получаем данные за последний день end_date = datetime.now() start_date = end_date - timedelta(days=1) hist = currency_pair.history(start=start_date, end=end_date) if hist.empty: raise ValueError(f"Данные не получены для пары {ticker}") latest_data = hist.iloc[-1] return { 'close': float(latest_data['Close']), 'timestamp': latest_data.name.strftime('%Y-%m-%d %H:%M:%S'), 'open': float(latest_data['Open']), 'high': float(latest_data['High']), 'low': float(latest_data['Low']), 'volume': float(latest_data['Volume']) if 'Volume' in latest_data else None } except Exception as e: self.logger.error(f"Ошибка при получении данных для пары {from_currency}/{to_currency}: {e}") raise def get_market_data(self, ticker: str, period: str = "1d") -> dict: """ Получает данные по указанному тикеру Args: ticker: тикер инструмента period: период данных ("1d", "5d", "1mo", "3mo", "6mo", "1y", "2y", "5y", "10y", "ytd", "max") """ try: stock = yf.Ticker(ticker) info = stock.info hist = stock.history(period=period) if hist.empty: raise ValueError(f"Данные не получены для {ticker}") latest_data = hist.iloc[-1] return { 'close': float(latest_data['Close']), 'open': float(latest_data['Open']), 'high': float(latest_data['High']), 'low': float(latest_data['Low']), 'volume': float(latest_data['Volume']) if 'Volume' in latest_data else None, 'timestamp': latest_data.name.strftime('%Y-%m-%d %H:%M:%S'), 'name': info.get('longName', None), 'sector': info.get('sector', None), 'market_cap': info.get('marketCap', None), 'pe_ratio': info.get('trailingPE', None), 'dividend_yield': info.get('dividendYield', None), 'currency': info.get('currency', None) } except Exception as e: self.logger.error(f"Ошибка при получении данных для {ticker}: {e}") raise def get_sector_performance(self, sector: str) -> dict: """ Получает данные по определенному сектору Args: sector: ключ сектора из словаря russian_sectors """ if sector not in self.russian_sectors: raise ValueError(f"Неизвестный сектор: {sector}") return self.get_market_data(self.russian_sectors[sector]) def get_index_data(self, index: str) -> dict: """ Получает данные по индексу Args: index: ключ индекса из словаря russian_indices """ if index not in self.russian_indices: raise ValueError(f"Неизвестный индекс: {index}") return self.get_market_data(self.russian_indices[index])