--- id: "ET-ML-006" title: "Enhanced Range Predictor" type: "Especificacion Tecnica" epic: "OQI-006" project: "trading-platform" priority: "P0" status: "Implementado" created_date: "2026-01-05" updated_date: "2026-01-05" author: "ML-Specialist + Trading-Strategist" --- # ET-ML-006: Enhanced Range Predictor ## Resumen Ejecutivo Sistema mejorado de prediccion de rangos de precio que utiliza: - Factor de volatilidad como unidad base de prediccion - Atencion diferenciada por sesion de trading y volatilidad - Ensemble dual con modelo largo plazo (5 anos) y corto plazo (3 meses) - Filtrado por ratio R:R minimo 2:1 --- ## Arquitectura ### Diagrama de Componentes ``` +------------------+ | OHLCV Data | +--------+---------+ | +--------------+--------------+ | | +---------v---------+ +----------v----------+ | CorrectedTargets | | FeatureGenerator | | (corrected_ | | (generate_ | | targets.py) | | features) | +---------+---------+ +----------+----------+ | | +-------------+---------------+ | +-------------v--------------+ | Sample Weighting | | +----------------------+ | | | SampleWeighter | | | | (movement magnitude) | | | +----------------------+ | | | SessionVolatility | | | | Weighter (session + | | | | ATR weights) | | | +----------------------+ | +-------------+--------------+ | +-------------v--------------+ | DualHorizonEnsemble | | +----------------------+ | | | Long-term (5 years) | | | | - XGBoost High | | | | - XGBoost Low | | | +----------------------+ | | | Short-term (3 months)| | | | - XGBoost High | | | | - XGBoost Low | | | +----------------------+ | | | Dynamic Weights | | | | (performance-based) | | | +----------------------+ | +-------------+--------------+ | +-------------v--------------+ | EnhancedRangePredictor | | - predict_single() | | - predict_batch() | | - get_trading_signal() | +----------------------------+ ``` --- ## Modulos Implementados ### 1. corrected_targets.py **Ubicacion:** `apps/ml-engine/src/data/corrected_targets.py` **Proposito:** Calcular targets de prediccion con formula corregida. **Formula:** ``` target_high = MAX(high[t+1], high[t+2], ..., high[t+H]) - close[t] target_low = close[t] - MIN(low[t+1], low[t+2], ..., low[t+H]) ``` Donde H = horizon_bars (default: 3) **Clases principales:** | Clase | Proposito | |-------|-----------| | `CorrectedTargetConfig` | Configuracion de horizonte, umbrales, factor base | | `CorrectedTargetBuilder` | Constructor de targets | | `TargetResult` | Resultado con arrays de targets y metricas | **Configuracion:** ```python CorrectedTargetConfig( horizon_bars=3, # Horizonte en barras start_offset=1, # Offset desde barra actual min_movement_usd=5.0, # Movimiento minimo para validez normalize_by_atr=True, # Normalizar por ATR min_rr_ratio=2.0, # R:R minimo base_factor=5.0 # Factor base en USD ) ``` **Outputs:** - `target_high_usd`: Target alto en USD - `target_low_usd`: Target bajo en USD - `target_high_mult`: Target alto en multiplos del factor - `target_low_mult`: Target bajo en multiplos del factor - `rr_long`, `rr_short`, `rr_best`: Ratios R:R - `direction`: 1 (LONG), -1 (SHORT), 0 (NEUTRAL) - `is_valid`: Mascara de muestras validas --- ### 2. sample_weighting.py **Ubicacion:** `apps/ml-engine/src/training/sample_weighting.py` **Proposito:** Ponderar muestras por magnitud de movimiento. **Clases principales:** | Clase | Proposito | |-------|-----------| | `SampleWeightConfig` | Configuracion de pesos | | `SampleWeighter` | Calculador de pesos por movimiento | **Configuracion:** ```python SampleWeightConfig( min_movement_threshold=5.0, # Umbral en USD large_movement_weight=3.0, # Peso para movimientos grandes small_movement_weight=0.3, # Peso para movimientos pequenos use_continuous_weighting=True,# Ponderacion continua weight_exponent=1.5, # Exponente para peso continuo min_rr_ratio=2.0, # R:R minimo min_weight=0.1, # Peso minimo max_weight=10.0 # Peso maximo ) ``` **Estrategia de ponderacion continua:** ``` weight = (movement / threshold) ^ exponent ``` --- ### 3. session_volatility_weighting.py **Ubicacion:** `apps/ml-engine/src/training/session_volatility_weighting.py` **Proposito:** Ponderar muestras por sesion de trading y volatilidad. **Sesiones de trading (UTC):** | Sesion | Horas UTC | Peso | |--------|-----------|------| | London/NY Overlap | 13:00-16:00 | 2.0 | | London | 08:00-16:00 | 1.5 | | New York | 13:00-21:00 | 1.3 | | Tokyo/Asian | 00:00-08:00 | 0.7 | | Off-hours | Resto | 0.3 | **Ponderacion por ATR:** | Condicion | Peso | |-----------|------| | ATR > Percentil 75 (alta volatilidad) | 1.5 | | ATR < Percentil 25 (lateral/consolidacion) | 0.3 | | Normal | 1.0 | **Features de sesion generadas:** - `is_london_session`, `is_ny_session`, `is_tokyo_session`, `is_overlap_session` - `hour_sin`, `hour_cos` (encoding ciclico) - `dow_sin`, `dow_cos` (dia de semana ciclico) - `london_progress`, `ny_progress` (progreso dentro de sesion) - `is_midweek`, `is_monday`, `is_friday` --- ### 4. dual_horizon_ensemble.py **Ubicacion:** `apps/ml-engine/src/models/dual_horizon_ensemble.py` **Proposito:** Ensemble de dos modelos con diferentes horizontes temporales. **Arquitectura:** | Modelo | Datos | Patrones | Parametros XGBoost | |--------|-------|----------|-------------------| | Largo plazo | 5 anos | Estructurales, estacionalidad | depth=8, n_estimators=300, lr=0.05 | | Corto plazo | 3 meses | Regimen actual, adaptacion | depth=5, n_estimators=150, lr=0.08 | **Pesos dinamicos:** - Inicial: 60% largo plazo, 40% corto plazo - Se ajustan basado en MAE reciente - Rango: [0.2, 0.8] para cada modelo **Reentrenamiento:** - Modelo corto plazo: cada 7 dias (configurable) - Modelo largo plazo: manual/periodico **Configuracion:** ```python DualHorizonConfig( long_term_years=5.0, short_term_months=3.0, initial_long_weight=0.6, initial_short_weight=0.4, use_dynamic_weights=True, weight_adjustment_lookback=100, weight_adjustment_rate=0.1, min_weight=0.2, max_weight=0.8, retrain_frequency_days=7 ) ``` --- ### 5. enhanced_range_predictor.py **Ubicacion:** `apps/ml-engine/src/models/enhanced_range_predictor.py` **Proposito:** Integrador principal que combina todos los componentes. **Pipeline:** ``` OHLCV -> CorrectedTargets -> FeatureGeneration -> -> CombinedWeights -> DualHorizonEnsemble -> Prediction ``` **Metodos principales:** | Metodo | Proposito | |--------|-----------| | `fit(df_ohlcv, df_features)` | Entrenar modelo completo | | `predict_single(features)` | Prediccion individual | | `predict_batch(features)` | Predicciones en lote | | `get_trading_signal(features, price)` | Senal con entry/TP/SL | | `update_with_result()` | Actualizar tracking de performance | | `retrain_short_term()` | Reentrenar modelo corto plazo | **Output de `get_trading_signal()`:** ```python { 'action': 'LONG' | 'SHORT' | 'WAIT', 'entry': 2650.00, 'take_profit': 2660.00, 'stop_loss': 2645.00, 'rr_ratio': 2.5, 'confidence': 0.75, 'pred_high_usd': 10.0, 'pred_low_usd': 5.0, 'model_weights': {'long_term': 0.6, 'short_term': 0.4} } ``` --- ### 6. train_enhanced_model.py **Ubicacion:** `apps/ml-engine/scripts/train_enhanced_model.py` **Proposito:** Script CLI para entrenamiento y validacion. **Uso:** ```bash # Entrenamiento basico python train_enhanced_model.py \ --symbol XAUUSD \ --timeframe 15m \ --data-path data/ \ --base-factor 5.0 \ --horizon-bars 3 # Con validacion walk-forward python train_enhanced_model.py \ --symbol XAUUSD \ --timeframe 15m \ --validate \ --n-splits 5 # Ver ayuda python train_enhanced_model.py --help ``` **Argumentos:** | Argumento | Default | Descripcion | |-----------|---------|-------------| | `--symbol` | XAUUSD | Simbolo de trading | | `--timeframe` | 15m | Timeframe de entrada | | `--data-path` | data/ | Directorio de datos | | `--output-path` | models/ | Directorio de salida | | `--base-factor` | 5.0 | Factor de volatilidad en USD | | `--horizon-bars` | 3 | Barras de horizonte | | `--min-rr` | 2.0 | R:R minimo | | `--validate` | False | Ejecutar validacion walk-forward | | `--n-splits` | 5 | Numero de splits para validacion | **Outputs:** - Modelo serializado en `{output-path}/{symbol}_{timeframe}_enhanced/` - Reporte Markdown en `{output-path}/training_report_{timestamp}.md` - Logs en `{output-path}/logs/` --- ## Features Generadas El script genera ~40 features automaticamente: ### Retornos - `returns_1`, `returns_5`, `returns_15` ### Volatilidad - `volatility_5`, `volatility_20` - `atr_14`, `atr_ratio` - `range`, `range_pct`, `range_ma_5`, `range_ma_20`, `range_ratio` ### Medias Moviles - `price_vs_sma5`, `price_vs_sma20`, `sma5_vs_sma20` ### Indicadores Tecnicos - `rsi_14` - `macd`, `macd_signal`, `macd_hist` - `bb_width`, `bb_position` - `momentum_5`, `momentum_10`, `momentum_20` ### Patrones de Vela - `body`, `body_pct` - `upper_shadow`, `lower_shadow` ### Volumen (si disponible) - `volume_ratio` ### Posicion Relativa - `close_vs_high5` - `adx_proxy` ### Features de Sesion - `is_london_session`, `is_ny_session`, `is_tokyo_session`, `is_overlap_session` - `hour_sin`, `hour_cos`, `dow_sin`, `dow_cos` - `london_progress`, `ny_progress` - `is_midweek`, `is_monday`, `is_friday` --- ## Validacion Walk-Forward El sistema incluye validacion walk-forward para evaluar robustez: ``` |--- Train 1 ---|--- Test 1 ---| |--- Train 2 ---|--- Test 2 ---| |--- Train 3 ---|--- Test 3 ---| ... ``` **Metricas evaluadas:** - Numero de senales LONG/SHORT generadas - Confianza promedio - R:R ratio promedio - Precision por split --- ## Integracion ### Con LLM Agent (OQI-007) ```python from models.enhanced_range_predictor import EnhancedRangePredictor predictor = EnhancedRangePredictor.load('models/XAUUSD_15m_enhanced') signal = predictor.get_trading_signal(features, current_price) if signal['action'] != 'WAIT' and signal['confidence'] > 0.7: llm_context = f""" Senal ML: {signal['action']} Entry: {signal['entry']}, TP: {signal['take_profit']}, SL: {signal['stop_loss']} R:R: {signal['rr_ratio']:.1f}, Confianza: {signal['confidence']:.0%} """ ``` ### Con Trading Agents ```python # En Atlas/Orion/Nova agent signal = predictor.get_trading_signal(features, current_price) if signal['action'] == 'LONG' and signal['rr_ratio'] >= 2.0: open_position( type='BUY', entry=signal['entry'], take_profit=signal['take_profit'], stop_loss=signal['stop_loss'] ) ``` --- ## Requisitos ### Dependencias Python ``` xgboost>=2.0.0 pandas>=2.0.0 numpy>=1.24.0 scikit-learn>=1.3.0 loguru>=0.7.0 joblib>=1.3.0 ``` ### Datos Requeridos - Minimo 3 meses de datos OHLCV para modelo corto plazo - Idealmente 5 anos para modelo largo plazo completo - Formato: Parquet o CSV con columnas: open, high, low, close, volume --- ## Metricas Esperadas | Metrica | Objetivo | Notas | |---------|----------|-------| | MAE High | < 0.5 mult | En multiplos del factor | | MAE Low | < 0.5 mult | En multiplos del factor | | Win Rate | > 55% | Con filtro R:R >= 2:1 | | Senales validas | > 20% | Del total de muestras | --- ## Mejoras Futuras 1. **Mas horizontes temporales**: Scalping (6 candles), Swing (36 candles) 2. **Features adicionales**: Order flow, sentiment, correlaciones 3. **Modelos alternativos**: LightGBM, CatBoost para ensemble mas diverso 4. **Autotuning**: Optimizacion automatica de hiperparametros --- ## Referencias - [RF-ML-001](../requerimientos/RF-ML-001-predicciones.md) - Prediccion de precios - [RF-ML-004](../requerimientos/RF-ML-004-entrenamiento.md) - Pipeline de entrenamiento - [ET-ML-002](./ET-ML-002-modelos.md) - Modelos XGBoost - [ET-ML-003](./ET-ML-003-features.md) - Feature engineering - [PLAN](../implementacion/PLAN-ENHANCED-RANGE-PREDICTOR.md) - Plan de ejecucion --- **Version:** 1.0.0 **Estado:** Implementado **Ultima actualizacion:** 2026-01-05