|
|
import os |
|
|
import logging |
|
|
import ccxt |
|
|
from logging.handlers import RotatingFileHandler |
|
|
from datetime import datetime |
|
|
import json |
|
|
from typing import List, Dict, Any |
|
|
|
|
|
def setup_logger(): |
|
|
"""Configure and set up the logger""" |
|
|
|
|
|
os.makedirs("logs", exist_ok=True) |
|
|
|
|
|
|
|
|
logger = logging.getLogger("crypto_data_source") |
|
|
logger.setLevel(logging.INFO) |
|
|
|
|
|
|
|
|
console_handler = logging.StreamHandler() |
|
|
console_handler.setLevel(logging.INFO) |
|
|
|
|
|
|
|
|
log_file = f"logs/crypto_data_source_{datetime.now().strftime('%Y%m%d')}.log" |
|
|
file_handler = RotatingFileHandler( |
|
|
log_file, maxBytes=10*1024*1024, backupCount=5 |
|
|
) |
|
|
file_handler.setLevel(logging.INFO) |
|
|
|
|
|
|
|
|
formatter = logging.Formatter( |
|
|
'%(asctime)s - %(name)s - %(levelname)s - %(message)s' |
|
|
) |
|
|
|
|
|
|
|
|
console_handler.setFormatter(formatter) |
|
|
file_handler.setFormatter(formatter) |
|
|
|
|
|
|
|
|
logger.addHandler(console_handler) |
|
|
logger.addHandler(file_handler) |
|
|
|
|
|
return logger |
|
|
|
|
|
def get_available_exchanges() -> List[str]: |
|
|
"""Get list of available exchanges with OHLCV support""" |
|
|
exchanges = [] |
|
|
|
|
|
|
|
|
preferred_exchanges = [ |
|
|
'binance', 'kucoin', 'coinbase', 'kraken', 'okx', 'bybit' |
|
|
] |
|
|
|
|
|
for exchange_id in preferred_exchanges: |
|
|
try: |
|
|
exchange_class = getattr(ccxt, exchange_id) |
|
|
exchange = exchange_class() |
|
|
|
|
|
|
|
|
if exchange.has['fetchOHLCV']: |
|
|
exchanges.append(exchange_id) |
|
|
except: |
|
|
|
|
|
continue |
|
|
|
|
|
return exchanges |
|
|
|
|
|
def format_timestamp(timestamp_ms: int) -> str: |
|
|
"""Format timestamp to ISO string""" |
|
|
return datetime.fromtimestamp(timestamp_ms / 1000).isoformat() |
|
|
|
|
|
def safe_json_serialize(obj): |
|
|
"""Custom JSON serializer for handling non-serializable types""" |
|
|
if isinstance(obj, (datetime)): |
|
|
return obj.isoformat() |
|
|
raise TypeError(f"Type {type(obj)} not serializable") |
|
|
|