diegobeyl/backtesting
2
1#!/usr/bin/env python32"""3Comparación Yahoo vs Binance - STANDALONE sin Streamlit4"""5 6import pandas as pd7import yfinance as yf8from datetime import datetime, timedelta9import ccxt10import time11 12end_date = datetime.now()13start_date = end_date - timedelta(days=365*10)14 15print(f"\n{'='*70}")16print(f"📊 BTC-USD: YAHOO vs BINANCE (10 AÑOS)")17print(f"{'='*70}\n")18 19# YAHOO FINANCE20print("📥 Yahoo Finance...")21t0 = time.time()22try:23 print(" Descargando 120 velas mensuales...")24 t_dl = time.time()25 yf_data = yf.download('BTC-USD', start=start_date, end=end_date, interval='1mo', progress=False)26 dl_time = time.time() - t_dl27 print(f" Descarga: {dl_time:.2f}s")28 29 t_proc = time.time()30 yf_data = yf_data.rename(columns={'Open': 'open', 'High': 'high', 'Low': 'low', 'Close': 'close', 'Volume': 'volume'})31 if hasattr(yf_data.index, 'tz') and yf_data.index.tz is not None:32 yf_data.index = yf_data.index.tz_localize(None)33 proc_time = time.time() - t_proc34 print(f" Procesamiento: {proc_time:.2f}s")35 36 yf_time = time.time() - t037 print(f"✅ {len(yf_data)} velas en {yf_time:.1f}s\n")38except Exception as e:39 print(f"❌ Error: {e}\n")40 import traceback41 traceback.print_exc()42 exit(1)43 44# BINANCE45print("📥 Binance (descargando datos diarios)...")46t0 = time.time()47try:48 binance = ccxt.binance({'enableRateLimit': True})49 since = int(start_date.timestamp() * 1000)50 ohlcv = []51 batch_count = 052 53 print(" Descargando en lotes de 1000...")54 while True:55 t_batch = time.time()56 batch = binance.fetch_ohlcv('BTC/USDT', '1d', since=since, limit=1000)57 batch_time = time.time() - t_batch58 59 if not batch or len(batch) == 0:60 print(f" ✓ Descarga completada ({batch_count} lotes)")61 break62 63 ohlcv.extend(batch)64 batch_count += 165 since = batch[-1][0] + 166 67 print(f" Lote {batch_count}: {len(batch)} registros en {batch_time:.2f}s ({len(ohlcv)} totales)")68 69 if len(batch) < 1000:70 print(f" ✓ Último lote (< 1000 registros)")71 break72 73 time.sleep(0.02)74 75 print(f" Total descargado: {len(ohlcv)} registros")76 77 # Crear DataFrame y resamplear78 print(" Procesando datos...")79 t_proc = time.time()80 bn_daily = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])81 bn_daily['timestamp'] = pd.to_datetime(bn_daily['timestamp'], unit='ms')82 bn_daily.set_index('timestamp', inplace=True)83 84 print(" Resampleando a mensuales...")85 bn_data = bn_daily.resample('ME').agg({86 'open': 'first', 'high': 'max', 'low': 'min', 'close': 'last', 'volume': 'sum'87 })88 89 proc_time = time.time() - t_proc90 bn_time = time.time() - t091 print(f"✅ {len(bn_data)} velas en {bn_time:.1f}s (descarga: {bn_time - proc_time:.1f}s + procesamiento: {proc_time:.1f}s)\n")92except Exception as e:93 print(f"❌ Error: {e}\n")94 import traceback95 traceback.print_exc()96 exit(1)97 98# COMPARACIÓN99print(f"{'='*70}")100print(f"🔍 RESULTADOS")101print(f"{'='*70}\n")102 103print(f"Yahoo: {len(yf_data)} velas ({yf_data.index[0].date()} a {yf_data.index[-1].date()})")104print(f"Binance: {len(bn_data)} velas ({bn_data.index[0].date()} a {bn_data.index[-1].date()})")105print(f"\nDiferencia: {len(yf_data) - len(bn_data)} velas")106 107common = yf_data.index.intersection(bn_data.index)108if len(common) > 0:109 yf_a = yf_data.loc[common]110 bn_a = bn_data.loc[common]111 diff = ((yf_a['close'] - bn_a['close']) / bn_a['close'] * 100)112 113 print(f"\nVelas comunes: {len(common)}")114 print(f"Diferencia media en Close: {diff.mean():.6f}%")115 print(f"Diferencia max en Close: {diff.abs().max():.6f}%")116 117print(f"\n{'='*70}\n")118 