diegobeyl/backtesting
2
1#!/usr/bin/env python32"""Aplica patch a backtesting_app/core/data_loader.py eliminando tickers marcados como no válidos3 4Uso: python scripts/apply_validation_patch.py scripts/validation_all.json5El script crea una copia de seguridad `backtesting_app/core/data_loader.py.bak` antes de sobrescribir.6"""7import sys8import os9import re10import json11 12if len(sys.argv) < 2:13 print('Usage: python scripts/apply_validation_patch.py <validation_json_path>')14 raise SystemExit(1)15 16json_path = sys.argv[1]17with open(json_path, 'r') as f:18 data = json.load(f)19 20results = data.get('results', {})21remove_set = {t for t, v in results.items() if (v.get('status') is not None) or ('meets_threshold' in v and not v.get('meets_threshold')) or v.get('error')}22if not remove_set:23 print('No tickers to remove according to', json_path)24 raise SystemExit(0)25 26dl_path = os.path.join('backtesting_app', 'core', 'data_loader.py')27bak_path = dl_path + '.bak'28os.rename(dl_path, bak_path)29print('Backup created:', bak_path)30 31with open(bak_path, 'r') as f:32 src = f.read()33 34# Localizar bloque AVAILABLE_SYMBOLS35start_pat = re.compile(r"AVAILABLE_SYMBOLS\s*[:=].*?=\s*{", re.S)36m = start_pat.search(src)37if not m:38 print('No se encontró AVAILABLE_SYMBOLS en el archivo')39 # revertir40 os.rename(bak_path, dl_path)41 raise SystemExit(1)42 43start_idx = m.end() - 144 45# Encontrar el cierre correspondiente balanceando llaves46i = start_idx47depth = 148while i < len(src):49 i += 150 c = src[i] if i < len(src) else ''51 if c == '{':52 depth += 153 elif c == '}':54 depth -= 155 if depth == 0:56 end_idx = i+157 break58else:59 print('No se pudo localizar el final de AVAILABLE_SYMBOLS')60 os.rename(bak_path, dl_path)61 raise SystemExit(1)62 63block = src[start_idx:end_idx]64 65# Para cada ticker a eliminar, eliminar su entrada textual dentro del bloque66for t in sorted(remove_set, key=len, reverse=True):67 # forma común: 'TICK': 'Name', (posible comilla doble/espacios)68 pattern = re.compile(r"[\'\"]" + re.escape(t) + r"[\'\"]\s*:\s*[^,\n]+,?\n")69 block, n = pattern.subn('', block)70 if n:71 print('Removed', t)72 73# Reconstruir fuente y escribir de nuevo74new_src = src[:start_idx] + block + src[end_idx:]75with open(dl_path, 'w') as f:76 f.write(new_src)77 78print('Applied patch to', dl_path)79print('Tickers removed:', len(remove_set))80 