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