# download_data.py """ Script para descargar datos históricos de múltiples símbolos y timeframes """ import os from dotenv import load_dotenv from datetime import datetime from pathlib import Path from src.monitoring.logger import log from src.data.fetcher import DataFetcher from src.data.processor import DataProcessor from src.data.storage import StorageManager def setup_environment(): """Carga variables de entorno""" env_path = Path(__file__).parent / 'config' / 'secrets.env' load_dotenv(dotenv_path=env_path) log.success("✓ Variables de entorno cargadas") def download_multiple_symbols(): """ Descarga datos históricos para múltiples símbolos y timeframes """ log.info("="*70) log.info("📥 DESCARGA MASIVA DE DATOS HISTÓRICOS") log.info("="*70) # Configuración setup_environment() exchange_name = os.getenv('EXCHANGE_NAME', 'binance') # Símbolos a descargar (puedes añadir más) symbols = [ 'BTC/USDT', 'ETH/USDT', 'BNB/USDT', 'SOL/USDT', 'XRP/USDT', ] # Timeframes a descargar timeframes = [ '1h', # 1 hora '4h', # 4 horas '1d', # 1 día ] # Días históricos days_back = 120 # 4 meses log.info(f"\n📊 Configuración:") log.info(f" Exchange: {exchange_name}") log.info(f" Símbolos: {len(symbols)} → {symbols}") log.info(f" Timeframes: {timeframes}") log.info(f" Días históricos: {days_back}") log.info(f" Total descargas: {len(symbols) * len(timeframes)}") # Confirmar print("\n" + "="*70) response = input("¿Continuar con la descarga? (s/n): ").lower() if response != 's': log.warning("Descarga cancelada por el usuario") return # Inicializar componentes log.info("\n🔧 Inicializando componentes...") fetcher = DataFetcher( exchange_name=exchange_name, api_key=os.getenv('API_KEY') if os.getenv('API_KEY') else None, api_secret=os.getenv('API_SECRET') if os.getenv('API_SECRET') else None ) processor = DataProcessor() storage = StorageManager( db_host=os.getenv('DB_HOST'), db_port=int(os.getenv('DB_PORT', 5432)), db_name=os.getenv('DB_NAME'), db_user=os.getenv('DB_USER'), db_password=os.getenv('DB_PASSWORD'), redis_host=os.getenv('REDIS_HOST', 'localhost'), redis_port=int(os.getenv('REDIS_PORT', 6379)) ) # Estadísticas total_downloads = len(symbols) * len(timeframes) current_download = 0 successful = 0 failed = 0 total_records = 0 # Descargar datos log.info("\n" + "="*70) log.info("🚀 INICIANDO DESCARGAS...") log.info("="*70 + "\n") for symbol in symbols: for timeframe in timeframes: current_download += 1 log.info(f"\n{'='*70}") log.info(f"📥 [{current_download}/{total_downloads}] {symbol} @ {timeframe}") log.info(f"{'='*70}") try: # Verificar si ya existen datos last_timestamp = storage.get_latest_timestamp(symbol, timeframe) if last_timestamp: log.info(f"⚠️ Ya existen datos hasta: {last_timestamp}") log.info(f" Se descargarán solo datos nuevos...") # Descargar datos df = fetcher.fetch_historical( symbol=symbol, timeframe=timeframe, days=days_back ) if df.empty: log.warning(f"❌ No se obtuvieron datos para {symbol} @ {timeframe}") failed += 1 continue # Procesar log.info(f"🧹 Procesando datos...") df_clean = processor.clean_data(df) df_clean = processor.calculate_returns(df_clean) # Guardar log.info(f"💾 Guardando en base de datos...") records_saved = storage.save_ohlcv(df_clean) total_records += records_saved successful += 1 log.success(f"✅ {symbol} @ {timeframe} → {records_saved} registros guardados") except Exception as e: log.error(f"❌ Error descargando {symbol} @ {timeframe}: {e}") failed += 1 continue # Resumen final log.info("\n" + "="*70) log.info("📊 RESUMEN DE DESCARGA") log.info("="*70) log.info(f"✅ Exitosas: {successful}/{total_downloads}") log.info(f"❌ Fallidas: {failed}/{total_downloads}") log.info(f"📦 Total registros guardados: {total_records:,}") # Ver datos disponibles log.info("\n📋 Datos disponibles en base de datos:") available_data = storage.get_available_data() print(available_data.to_string(index=False)) # Cleanup storage.close() log.info("\n" + "="*70) log.success("✅ DESCARGA COMPLETADA") log.info("="*70) if __name__ == "__main__": try: download_multiple_symbols() except KeyboardInterrupt: log.warning("\n⚠️ Descarga interrumpida por el usuario") except Exception as e: log.error(f"\n❌ Error fatal: {e}") raise