--- id: "ET-ML-011" title: "MRD (Momentum Regime Detection) Strategy" type: "Technical Specification" status: "Approved" priority: "Alta" epic: "OQI-006" project: "trading-platform" version: "1.0.0" created_date: "2026-01-25" updated_date: "2026-01-25" task_reference: "TASK-2026-01-25-ML-TRAINING-ENHANCEMENT" --- # ET-ML-011: MRD (Momentum Regime Detection) Strategy ## Metadata | Campo | Valor | |-------|-------| | **ID** | ET-ML-011 | | **Epica** | OQI-006 - Senales ML | | **Tipo** | Especificacion Tecnica | | **Version** | 1.0.0 | | **Estado** | Aprobado | | **Ultima actualizacion** | 2026-01-25 | | **Tarea Referencia** | TASK-2026-01-25-ML-TRAINING-ENHANCEMENT | --- ## Resumen La estrategia MRD (Momentum Regime Detection) detecta regimenes de mercado (tendencia alcista, rango, tendencia bajista) usando un **Hidden Markov Model (HMM)** con 3 estados, complementado por **LSTM** para secuencias y **XGBoost** para predicciones. ### Caracteristicas Clave - **HMM de 3 Estados**: Detecta regimenes Trend Up, Range, Trend Down - **Features de Momentum**: RSI, MACD, ROC, ADX, EMA crossovers - **Transiciones de Regimen**: Probabilidades de cambio de estado - **Prediccion de Direccion**: Basada en regimen actual + momentum --- ## Arquitectura ### Diagrama de Alto Nivel ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ MRD MODEL │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ Input: OHLCV Data │ │ └── Momentum indicators (RSI, MACD, ROC, ADX) │ │ │ │ │ ┌─────────────┴─────────────┐ │ │ ▼ ▼ │ │ ┌──────────────────────┐ ┌──────────────────────┐ │ │ │ HMM REGIME │ │ LSTM ENCODER │ │ │ │ DETECTOR │ │ │ │ │ │ │ │ ┌─────────────────┐ │ │ │ │ States: │ │ │ BiLSTM Layers │ │ │ │ │ 0 = TREND_UP │ │ │ (2 layers) │ │ │ │ │ 1 = RANGE │ │ └─────────────────┘ │ │ │ │ 2 = TREND_DOWN │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ Outputs: │ │ ┌─────────────────┐ │ │ │ │ - current_regime │ │ │ Attention Pool │ │ │ │ │ - regime_probs │ │ └─────────────────┘ │ │ │ │ - transition_probs │ └──────────────────────┘ │ │ └──────────────────────┘ │ │ │ │ │ │ │ └───────────┬───────────────┘ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ XGBOOST PREDICTOR │ │ │ │ │ │ │ │ Features: [regime_encoded, regime_probs, lstm_features, │ │ │ │ momentum_features, transition_probs] │ │ │ │ │ │ │ │ Outputs: │ │ │ │ - direction: bullish/bearish/neutral │ │ │ │ - regime_continuation_prob │ │ │ │ - expected_regime_duration │ │ │ └───────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ Output: MRDPrediction │ │ - current_regime: 'TREND_UP' | 'RANGE' | 'TREND_DOWN' │ │ - direction: float │ │ - regime_confidence: float │ │ - next_regime_probs: Dict │ └─────────────────────────────────────────────────────────────────────────┘ ``` ### Componentes HMM ```python HMMConfig: n_states: 3 # Trend Up, Range, Trend Down n_iter: 100 # EM iterations covariance_type: 'full' random_state: 42 ``` | Estado | Caracteristicas | Probabilidad Tipica | |--------|-----------------|---------------------| | **TREND_UP** | RSI > 50, MACD > 0, ADX > 25 | ~30% | | **RANGE** | RSI ~50, ADX < 20 | ~40% | | **TREND_DOWN** | RSI < 50, MACD < 0, ADX > 25 | ~30% | ### Componentes LSTM | Componente | Configuracion | |------------|---------------| | **Layers** | 2 BiLSTM layers | | **hidden_size** | 128 | | **dropout** | 0.2 | | **sequence_length** | 50 | | **output_dim** | 64 (latent features) | --- ## Feature Engineering ### Momentum Features #### 1. RSI (Relative Strength Index) ```python RSI Features: rsi_14: RSI period 14 rsi_7: RSI period 7 rsi_28: RSI period 28 rsi_divergence: price_trend - rsi_trend rsi_zone: oversold (-1) / neutral (0) / overbought (1) ``` | Feature | Formula | Interpretacion | |---------|---------|----------------| | `rsi_14` | RSI standard | Momentum actual | | `rsi_divergence` | `np.sign(price_slope) - np.sign(rsi_slope)` | Divergencia bull/bear | | `rsi_zone` | Discretizado (-1, 0, 1) | Zona de RSI | #### 2. MACD (Moving Average Convergence Divergence) ```python MACD Features: macd: EMA_12 - EMA_26 macd_signal: EMA_9(macd) macd_hist: macd - macd_signal macd_crossover: binary (1 if macd > signal, else -1) macd_hist_slope: trend of histogram ``` | Feature | Descripcion | |---------|-------------| | `macd_hist` | Histograma MACD | | `macd_crossover` | Cruce de linea de senal | | `macd_hist_slope` | Direccion del histograma | #### 3. ROC (Rate of Change) ```python ROC Features: roc_5: (close / close.shift(5) - 1) * 100 roc_10: (close / close.shift(10) - 1) * 100 roc_20: (close / close.shift(20) - 1) * 100 roc_acceleration: roc_5 - roc_5.shift(5) ``` #### 4. ADX (Average Directional Index) ```python ADX Features: adx: ADX(14) plus_di: +DI(14) minus_di: -DI(14) di_crossover: +DI > -DI ? 1 : -1 trend_strength: ADX > 25 ? 'strong' : 'weak' ``` | Feature | Interpretacion | |---------|----------------| | `adx > 25` | Mercado en tendencia | | `adx < 20` | Mercado en rango | | `+DI > -DI` | Tendencia alcista dominante | #### 5. EMA Crossovers ```python EMA_Crossover Features: ema_8_21_cross: EMA(8) vs EMA(21) ema_21_55_cross: EMA(21) vs EMA(55) ema_stack: 1 if EMA8 > EMA21 > EMA55 else -1 if EMA8 < EMA21 < EMA55 else 0 price_vs_ema21: (close - EMA21) / close ``` --- ## Estados del Regimen ### Definicion de Estados HMM ```python class RegimeState(Enum): TREND_UP = 0 # Mercado en tendencia alcista RANGE = 1 # Mercado lateral/consolidacion TREND_DOWN = 2 # Mercado en tendencia bajista ``` ### Caracteristicas por Estado | Estado | RSI | MACD | ADX | EMA Stack | Volatilidad | |--------|-----|------|-----|-----------|-------------| | TREND_UP | > 55 | > 0, rising | > 25 | 8 > 21 > 55 | Media | | RANGE | 40-60 | Near 0 | < 20 | Mixto | Baja | | TREND_DOWN | < 45 | < 0, falling | > 25 | 8 < 21 < 55 | Media-Alta | ### Matriz de Transicion ``` TREND_UP RANGE TREND_DOWN TREND_UP [0.80 0.15 0.05 ] RANGE [0.25 0.50 0.25 ] TREND_DOWN [0.05 0.15 0.80 ] ``` La matriz de transicion se estima dinamicamente via EM. --- ## Pipeline de Entrenamiento ### Fase 1: Entrenamiento HMM ```python # Entrenar HMM en features de momentum hmm_model = GaussianHMM(n_components=3, covariance_type='full') hmm_model.fit(momentum_features) # Obtener estados y probabilidades hidden_states = hmm_model.predict(momentum_features) state_probs = hmm_model.predict_proba(momentum_features) transition_matrix = hmm_model.transmat_ ``` ### Fase 2: Entrenamiento LSTM ```python # Entrenar LSTM en secuencias de momentum lstm_encoder = MRDLSTMEncoder( input_dim=n_features, hidden_dim=128, n_layers=2, output_dim=64 ) # Loss: Combinacion de regime prediction + reconstruction loss = regime_cross_entropy + 0.3 * reconstruction_mse ``` ### Fase 3: Entrenamiento XGBoost ```python # Combinar features para XGBoost combined_features = np.concatenate([ one_hot_regime, # Estado HMM actual state_probs, # Probabilidades de estado lstm_features, # Features LSTM momentum_features, # Features originales transition_probs # Probabilidades de transicion ], axis=1) # Entrenar clasificador de direccion xgb_direction = XGBClassifier(**xgb_params) xgb_direction.fit(combined_features, direction_labels) ``` --- ## Metricas de Evaluacion ### Metricas de Regimen | Metrica | Descripcion | Target | |---------|-------------|--------| | **Regime Accuracy** | Precision en deteccion de estado | >= 70% | | **Transition Accuracy** | Precision en cambios de regimen | >= 60% | | **Regime Duration Error** | MAE en duracion esperada | < 5 candles | ### Metricas de Direccion | Metrica | Descripcion | Target | |---------|-------------|--------| | **Direction Accuracy** | Precision en direccion | >= 55% | | **Regime-Conditional Accuracy** | Accuracy por regimen | Trend >= 60%, Range >= 50% | | **Transition Signal Quality** | Performance en cambios | > 0 return | ### Evaluacion de HMM ```python MRDMetrics: log_likelihood: float # Log-likelihood del modelo aic: float # Akaike Information Criterion bic: float # Bayesian Information Criterion regime_accuracy: float transition_f1: float avg_regime_duration: Dict[str, float] ``` --- ## API y Uso ### Clase Principal: MRDModel ```python from models.strategies.mrd import MRDModel, MRDConfig # Configuracion config = MRDConfig( n_regimes=3, lstm_hidden_dim=128, lstm_layers=2, sequence_length=50, xgb_n_estimators=200 ) # Inicializar modelo model = MRDModel(config) # Entrenar model.fit(df_train, df_val) # Prediccion predictions = model.predict(df_new) for pred in predictions: print(f"Regime: {pred.current_regime}") print(f"Direction: {pred.direction}") print(f"Next Regime Probs: {pred.next_regime_probs}") ``` ### Clase MRDPrediction ```python @dataclass class MRDPrediction: current_regime: str # 'TREND_UP', 'RANGE', 'TREND_DOWN' regime_confidence: float # 0 to 1 direction: float # -1 to 1 direction_confidence: float next_regime_probs: Dict[str, float] # Probabilidades del proximo estado expected_regime_duration: int # Candles esperados en este regimen momentum_strength: float # Fuerza del momentum actual @property def trading_bias(self) -> str: if self.current_regime == 'TREND_UP' and self.direction > 0: return 'STRONG_LONG' elif self.current_regime == 'TREND_DOWN' and self.direction < 0: return 'STRONG_SHORT' elif self.current_regime == 'RANGE': return 'NEUTRAL' else: return 'WEAK_' + ('LONG' if self.direction > 0 else 'SHORT') ``` ### Deteccion de Cambio de Regimen ```python # Obtener probabilidad de cambio de regimen def detect_regime_change(predictions: List[MRDPrediction]) -> bool: if len(predictions) < 2: return False current = predictions[-1] previous = predictions[-2] # Cambio de regimen si: # 1. Estado actual diferente # 2. Probabilidad del nuevo estado > 70% if current.current_regime != previous.current_regime: if current.regime_confidence > 0.7: return True return False ``` --- ## Estructura de Archivos ``` apps/ml-engine/src/models/strategies/mrd/ ├── __init__.py ├── model.py # MRDModel, MRDConfig, MRDPrediction ├── feature_engineering.py # MRDFeatureEngineer ├── hmm_regime.py # HMM regime detector (GaussianHMM wrapper) ├── lstm_encoder.py # BiLSTM encoder └── trainer.py # MRDTrainer ``` --- ## Consideraciones de Produccion ### Actualizacion Online del HMM ```python # El HMM puede actualizarse incrementalmente def update_hmm(model, new_data, window_size=1000): """Actualiza HMM con datos recientes manteniendo estabilidad""" if len(new_data) > window_size: recent_data = new_data[-window_size:] else: recent_data = new_data # Re-fit con warm start model.hmm.fit(recent_data) ``` ### Deteccion de Regimen en Tiempo Real ```python # Pipeline de inferencia optimizado class MRDInference: def __init__(self, model_path: str): self.model = MRDModel.load(model_path) self.feature_buffer = deque(maxlen=100) def update(self, candle: Dict) -> MRDPrediction: self.feature_buffer.append(candle) if len(self.feature_buffer) >= 50: features = self.compute_features() return self.model.predict_single(features) return None ``` ### Alertas de Cambio de Regimen ```python # Sistema de alertas def check_regime_alerts(prediction: MRDPrediction) -> List[Alert]: alerts = [] # Alerta de cambio de regimen inminente if prediction.regime_confidence < 0.5: alerts.append(Alert( type='REGIME_UNCERTAINTY', message='Regimen actual inestable', severity='WARNING' )) # Alerta de transicion probable for regime, prob in prediction.next_regime_probs.items(): if regime != prediction.current_regime and prob > 0.4: alerts.append(Alert( type='REGIME_TRANSITION', message=f'Posible transicion a {regime}', severity='INFO' )) return alerts ``` --- ## Referencias - [ET-ML-001: Arquitectura ML Engine](./ET-ML-001-arquitectura.md) - [ET-ML-010: PVA Strategy](./ET-ML-010-pva-strategy.md) - [Hidden Markov Models (Rabiner, 1989)](https://web.ece.ucsb.edu/Faculty/Rabiner/ece259/Reprints/tutorial%20on%20hmm%20and%20applications.pdf) - [hmmlearn Documentation](https://hmmlearn.readthedocs.io/) --- **Autor:** ML-Specialist (NEXUS v4.0) **Fecha:** 2026-01-25