init
This commit is contained in:
commit
74d4e14476
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
venv/
|
||||||
136
classes/exchange.py
Normal file
136
classes/exchange.py
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
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])
|
||||||
54
get/currency.py
Normal file
54
get/currency.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import sqlite3
|
||||||
|
from exchange import ForexDataHandler
|
||||||
|
|
||||||
|
# Создаем или подключаемся к базе данных
|
||||||
|
conn = sqlite3.connect('currency_rates.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Создаем таблицу, если она не существует
|
||||||
|
cursor.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS currency_rates (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
base_currency TEXT NOT NULL,
|
||||||
|
quote_currency TEXT NOT NULL,
|
||||||
|
rate REAL NOT NULL,
|
||||||
|
timestamp TEXT NOT NULL
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
|
||||||
|
forex_handler = ForexDataHandler()
|
||||||
|
currency_pairs = [
|
||||||
|
('CNY', 'RUB'), # Китайский юань
|
||||||
|
('USD', 'RUB'), # Доллар США
|
||||||
|
('EUR', 'RUB'), # Евро
|
||||||
|
('GBP', 'RUB'), # Фунт стерлингов
|
||||||
|
('JPY', 'RUB'), # Японская йена
|
||||||
|
('KZT', 'RUB'), # Казахстанский тенге
|
||||||
|
('UAH', 'RUB'), # Украинская гривна
|
||||||
|
('BYN', 'RUB'), # Белорусский рубль
|
||||||
|
]
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("\nТекущие курсы валют:")
|
||||||
|
for base_currency, quote_currency in currency_pairs:
|
||||||
|
try:
|
||||||
|
rate = forex_handler.get_forex_rate(base_currency, quote_currency)
|
||||||
|
print(f"\nКурс {base_currency}/{quote_currency}:")
|
||||||
|
print(f"Текущий: {rate['close']:.4f}")
|
||||||
|
print(f"Дата: {rate['timestamp']}")
|
||||||
|
|
||||||
|
# Вставляем данные в базу данных
|
||||||
|
cursor.execute('''
|
||||||
|
INSERT INTO currency_rates (base_currency, quote_currency, rate, timestamp)
|
||||||
|
VALUES (?, ?, ?, ?)
|
||||||
|
''', (base_currency, quote_currency, rate['close'], rate['timestamp']))
|
||||||
|
|
||||||
|
except Exception as pair_error:
|
||||||
|
print(f"Ошибка при получении курса {base_currency}/{quote_currency}: {pair_error}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Произошла ошибка: {e}")
|
||||||
|
|
||||||
|
# Сохраняем изменения и закрываем соединение
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
18
requirements.txt
Normal file
18
requirements.txt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
pandas
|
||||||
|
plotly
|
||||||
|
requests
|
||||||
|
apimoex
|
||||||
|
aiohttp
|
||||||
|
requests
|
||||||
|
httpx
|
||||||
|
pybit
|
||||||
|
aiohttp
|
||||||
|
altair
|
||||||
|
pymc
|
||||||
|
scikit-learn
|
||||||
|
numpy
|
||||||
|
seaborn
|
||||||
|
statsmodels
|
||||||
|
xgboost
|
||||||
|
lightgbm
|
||||||
|
groq
|
||||||
Loading…
Reference in New Issue
Block a user