# main.py """ Punto de entrada principal del bot de trading Demo para Semanas 1-2: Data Pipeline + Storage """ import os from pathlib import Path from dotenv import load_dotenv from datetime import datetime, timedelta 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 desde config/secrets.env """ # Cargar desde config/secrets.env project_root = Path(__file__).parent env_path = project_root / 'config' / 'secrets.env' if not env_path.exists(): log.error(f"No se encuentra el archivo: {env_path}") raise FileNotFoundError(f"Archivo de configuración no encontrado: {env_path}") load_dotenv(env_path) log.info(f"Cargando configuración desde: {env_path}") # Verificar variables requeridas required_vars = ['EXCHANGE_NAME', 'DB_HOST', 'DB_NAME', 'DB_USER', 'DB_PASSWORD'] missing_vars = [var for var in required_vars if not os.getenv(var)] if missing_vars: log.error(f"Faltan variables de entorno: {missing_vars}") raise EnvironmentError(f"Variables faltantes: {missing_vars}") log.success("✓ Variables de entorno cargadas correctamente") def demo_data_pipeline(): """ Demo completo del pipeline de datos """ log.info("="*60) log.info("DEMO: Data Pipeline + Storage") log.info("="*60) # 1. Setup setup_environment() # Configuración exchange_name = os.getenv('EXCHANGE_NAME', 'binance') symbol = 'BTC/USDT' timeframe = '1h' days_back = 7 # 2. Inicializar componentes log.info("\n[1/5] Inicializando componentes...") fetcher = DataFetcher( exchange_name=exchange_name, api_key=os.getenv('API_KEY'), api_secret=os.getenv('API_SECRET') ) 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)) ) # 3. Obtener datos log.info(f"\n[2/5] Obteniendo datos históricos de {symbol}...") df = fetcher.fetch_historical( symbol=symbol, timeframe=timeframe, days=days_back ) log.info(f"Datos obtenidos: {len(df)} velas") log.info(f"Rango: {df.index[0]} a {df.index[-1]}") log.info(f"\nPrimeras filas:\n{df.head()}") # 4. Procesar datos log.info("\n[3/5] Procesando datos...") # Validar is_valid = processor.validate_ohlcv(df) log.info(f"Datos válidos: {is_valid}") # Limpiar df_clean = processor.clean_data(df) # Detectar gaps gaps = processor.detect_gaps(df_clean, timeframe) if not gaps.empty: log.warning(f"Gaps detectados:\n{gaps}") # Calcular retornos df_clean = processor.calculate_returns(df_clean) log.info(f"\nEstadísticas de retornos:") log.info(f"Retorno medio: {df_clean['returns'].mean():.4%}") log.info(f"Volatilidad: {df_clean['returns'].std():.4%}") log.info(f"Retorno total: {df_clean['returns'].sum():.4%}") # 5. Guardar en base de datos log.info("\n[4/5] Guardando en base de datos...") records_saved = storage.save_ohlcv(df_clean) log.success(f"Guardados {records_saved} registros") # 6. Verificar almacenamiento log.info("\n[5/5] Verificando almacenamiento...") # Obtener último timestamp last_timestamp = storage.get_latest_timestamp(symbol, timeframe) log.info(f"Último timestamp en DB: {last_timestamp}") # Cargar datos de vuelta df_loaded = storage.load_ohlcv( symbol=symbol, timeframe=timeframe, start_date=datetime.now() - timedelta(days=2) ) log.info(f"Datos cargados de DB: {len(df_loaded)} registros") # Resumen de datos disponibles available_data = storage.get_available_data() log.info(f"\nDatos disponibles en base de datos:\n{available_data}") # 7. Demo adicional: resampleo log.info("\n[EXTRA] Demo de resampleo de timeframe...") df_4h = processor.resample_timeframe(df_clean, '4h') log.info(f"Datos resampled a 4h: {len(df_4h)} velas") log.info(f"\nPrimeras filas 4h:\n{df_4h.head()}") # Guardar también el timeframe de 4h storage.save_ohlcv(df_4h) # 8. Obtener precio actual log.info("\n[EXTRA] Obteniendo precio actual...") ticker = fetcher.fetch_ticker(symbol) log.info(f"Precio actual de {symbol}: ${ticker['last']:,.2f}") log.info(f"24h High: ${ticker['high']:,.2f}") log.info(f"24h Low: ${ticker['low']:,.2f}") log.info(f"24h Volume: {ticker['baseVolume']:,.2f}") # 9. Cleanup storage.close() log.info("\n" + "="*60) log.success("DEMO COMPLETADO EXITOSAMENTE") log.info("="*60) return df_clean if __name__ == "__main__": try: df = demo_data_pipeline() except Exception as e: log.error(f"Error en demo: {e}") raise