--- id: "ET-ML-013" title: "MSA (Market Structure Analysis) 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-013: MSA (Market Structure Analysis) Strategy ## Metadata | Campo | Valor | |-------|-------| | **ID** | ET-ML-013 | | **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 MSA (Market Structure Analysis) aplica conceptos de **ICT/SMC** (Inner Circle Trader / Smart Money Concepts) mediante machine learning. Utiliza **XGBoost** para predecir la direccion del proximo BOS (Break of Structure), reacciones en POI (Points of Interest), y probabilidad de continuacion de estructura. ### Caracteristicas Clave - **Arquitectura XGBoost**: Tres clasificadores especializados - **Features ICT/SMC**: BOS, CHoCH, FVG, Order Blocks, Liquidity - **Predicciones Multiple**: Direccion BOS, reaccion POI, continuacion - **GNN Opcional**: Para relaciones entre swing points --- ## Conceptos ICT/SMC ### Terminologia Clave | Concepto | Descripcion | Uso en Trading | |----------|-------------|----------------| | **BOS** | Break of Structure - Ruptura de estructura | Confirmacion de tendencia | | **CHoCH** | Change of Character - Cambio de caracter | Reversion de tendencia | | **FVG** | Fair Value Gap - Hueco de valor justo | Zonas de reversion | | **Order Block** | Vela institucional antes de movimiento | Soporte/resistencia | | **Liquidity** | Zonas con stop losses | Objetivos de precio | | **POI** | Point of Interest | Zonas de entrada | ### Estructura de Mercado ``` HH (Higher High) / HL / / / LH / / <-- CHoCH (cambio a alcista) / / / LL / / \ / \ / BOS (ruptura) ``` --- ## Arquitectura ### Diagrama de Alto Nivel ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ MSA MODEL │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ Input: OHLCV Data │ │ └── Structure Detection Pipeline │ │ │ │ │ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ STRUCTURE DETECTOR │ │ │ │ │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │ │ │ │ │ Swing Point │──▶│ HH/HL/LH/LL │──▶│ BOS/CHoCH Detection │ │ │ │ │ │ Detection │ │ Classification│ │ │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────────────────┘ │ │ │ │ │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │ │ │ │ │ FVG │ │ Order Block │ │ Liquidity Level │ │ │ │ │ │ Detection │ │ Detection │ │ Detection │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ MSA FEATURE ENGINEER │ │ │ │ │ │ │ │ Features: 60+ structure-based features │ │ │ │ - Swing point distances │ │ │ │ - BOS/CHoCH counts and recency │ │ │ │ - FVG distances and fill rates │ │ │ │ - Order Block strengths │ │ │ │ - Premium/Discount zones │ │ │ │ - Liquidity imbalances │ │ │ └───────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ XGBOOST CLASSIFIERS (3) │ │ │ │ │ │ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ │ │ BOS Direction Classifier │ │ │ │ │ │ Classes: neutral (0), bullish (1), bearish (2) │ │ │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ │ │ POI Reaction Classifier │ │ │ │ │ │ Binary: no_reaction (0), reaction (1) │ │ │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ │ │ Structure Continuation Classifier │ │ │ │ │ │ Binary: reversal (0), continuation (1) │ │ │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ Output: MSAPrediction │ │ - next_bos_direction: 'bullish' | 'bearish' | 'neutral' │ │ - poi_reaction_prob: float │ │ - structure_continuation_prob: float │ │ - trading_bias: 'LONG_BIAS' | 'SHORT_BIAS' | 'NEUTRAL' │ └─────────────────────────────────────────────────────────────────────────┘ ``` ### Componente GNN Opcional ```python class SwingPointGNN: """GNN para modelar relaciones entre swing points""" # Nodos: swing points (high/low) # Edges: relaciones temporales y de precio # Output: embeddings para cada swing point input_dim: 8 # Features por nodo hidden_dim: 32 output_dim: 16 n_layers: 2 ``` --- ## Feature Engineering ### Structure Detector El `StructureDetector` identifica todos los elementos de estructura: ```python class StructureDetector: def __init__(self, swing_order: int = 5): self.swing_order = swing_order def analyze(self, df: pd.DataFrame) -> StructureAnalysis: # Detectar swing points swing_highs, swing_lows = self.detect_swing_points(df) # Clasificar HH/HL/LH/LL classified_highs, classified_lows = self.classify_swings(...) # Detectar eventos de estructura bos_events = self.detect_break_of_structure(...) choch_events = self.detect_change_of_character(...) # Detectar POIs fvgs = self.detect_fair_value_gaps(df) order_blocks = self.detect_order_blocks(df, bos_events) liquidity = self.detect_liquidity_levels(...) return StructureAnalysis(...) ``` ### Categories de Features (60+) #### 1. Swing Point Features ```python Swing Features: dist_to_swing_high: Distancia al ultimo swing high dist_to_swing_low: Distancia al ultimo swing low hh_count: Count de Higher Highs en lookback hl_count: Count de Higher Lows lh_count: Count de Lower Highs ll_count: Count de Lower Lows last_swing_type: 1=high, -1=low swing_structure_score: (HH+HL-LH-LL) / 10 ``` #### 2. BOS/CHoCH Features ```python BOS_CHoCH Features: bos_bullish_count: Count de BOS alcistas bos_bearish_count: Count de BOS bajistas choch_bullish_count: Count de CHoCH alcistas choch_bearish_count: Count de CHoCH bajistas bars_since_bos: Candles desde ultimo BOS bars_since_choch: Candles desde ultimo CHoCH last_bos_direction: 1=bullish, -1=bearish last_choch_direction: 1=bullish, -1=bearish bos_net_bias: bullish - bearish has_recent_choch: CHoCH en ultimas 20 velas ``` #### 3. FVG Features ```python FVG Features: bullish_fvg_count: Count de FVGs alcistas bearish_fvg_count: Count de FVGs bajistas unfilled_fvg_count: FVGs sin llenar dist_to_nearest_fvg: Distancia al FVG mas cercano nearest_fvg_type: 1=bullish, -1=bearish in_fvg: Precio dentro de FVG fvg_fill_rate: Tasa de llenado de FVGs fvg_net_bias: bullish - bearish ``` #### 4. Order Block Features ```python Order_Block Features: bullish_ob_count: Count de OB alcistas bearish_ob_count: Count de OB bajistas valid_ob_count: OB validos (no rotos) dist_to_nearest_ob: Distancia al OB mas cercano nearest_ob_type: 1=bullish, -1=bearish in_ob: Precio dentro de OB ob_strength_avg: Fuerza promedio de OB ob_net_bias: bullish - bearish ``` #### 5. Premium/Discount Zone Features ```python Zone Features: position_in_range: 0-1 posicion en rango dist_to_equilibrium: Distancia a equilibrio in_premium: Precio en zona premium in_discount: Precio en zona discount dist_to_premium: Distancia a zona premium dist_to_discount: Distancia a zona discount ``` #### 6. Liquidity Features ```python Liquidity Features: equal_highs_count: Count de equal highs equal_lows_count: Count de equal lows dist_to_nearest_liquidity: Distancia a liquidez liquidity_above: Fuerza de liquidez arriba liquidity_below: Fuerza de liquidez abajo liquidity_imbalance: (above - below) / (above + below + 1) ``` #### 7. POI Distance Features ```python POI Features: dist_to_nearest_poi: Distancia al POI mas cercano nearest_poi_type: Tipo de POI (OB, FVG, swing, liquidity) in_poi: Precio dentro de un POI poi_count_nearby: POIs dentro del 1% ``` #### 8. Trend Features ```python Trend Features: bullish_structure_score: (HH + HL) / total_swings bearish_structure_score: (LH + LL) / total_swings structure_trend_bias: bullish - bearish ``` --- ## Training Pipeline ### Fase 1: Estructura Analysis ```python # Analizar estructura de mercado detector = StructureDetector(swing_order=5) analysis = detector.analyze(df) # Preparar features engineer = MSAFeatureEngineer(swing_order=5, lookback_periods=50) features = engineer.compute_structure_features(df) ``` ### Fase 2: Label Generation ```python def generate_labels(df: pd.DataFrame, forward_bars: int = 12): """Generar labels para entrenamiento""" # Label 1: Direccion del proximo BOS y_bos = compute_next_bos_direction(df, forward_bars) # Label 2: Reaccion en POI actual y_poi = label_poi_reactions(df, pois, forward_bars) # Label 3: Continuacion de estructura y_continuation = label_structure_continuation(df, forward_bars) return y_bos, y_poi, y_continuation ``` ### Fase 3: Training XGBoost ```python model = MSAModel(config) metrics = model.fit( X_train, y_bos=y_bos_train, y_poi=y_poi_train, y_continuation=y_continuation_train, X_val=X_val, y_bos_val=y_bos_val, y_poi_val=y_poi_val, y_continuation_val=y_continuation_val ) ``` ### XGBoost Configuration ```python xgb_config = { 'n_estimators': 200, 'max_depth': 6, 'learning_rate': 0.05, 'subsample': 0.8, 'colsample_bytree': 0.8, 'min_child_weight': 3, 'gamma': 0.1, 'reg_alpha': 0.1, 'reg_lambda': 1.0 } # BOS: multi-class (3 classes) bos_params = {**xgb_config, 'objective': 'multi:softprob', 'num_class': 3} # POI: binary poi_params = {**xgb_config, 'objective': 'binary:logistic'} # Continuation: binary cont_params = {**xgb_config, 'objective': 'binary:logistic'} ``` --- ## Metricas de Evaluacion ### Metricas BOS Direction | Metrica | Descripcion | Target | |---------|-------------|--------| | **BOS Accuracy** | Precision general | >= 55% | | **Macro F1** | F1 promedio por clase | >= 0.50 | | **Per-Class F1** | F1 por clase | Balanced | ### Metricas POI Reaction | Metrica | Descripcion | Target | |---------|-------------|--------| | **POI Accuracy** | Precision en reacciones | >= 60% | | **POI Precision** | True positives / Predicted | >= 55% | | **POI Recall** | True positives / Actual | >= 60% | | **POI F1** | Balance | >= 0.55 | ### Metricas Continuation | Metrica | Descripcion | Target | |---------|-------------|--------| | **Continuation Accuracy** | Precision en continuacion | >= 60% | | **Continuation F1** | F1 score | >= 0.55 | --- ## API y Uso ### Clase Principal: MSAModel ```python from models.strategies.msa import MSAModel, MSAPrediction # Configuracion config = { 'n_estimators': 200, 'max_depth': 6, 'learning_rate': 0.05, 'use_gnn': False # Optional GNN component } # Inicializar modelo model = MSAModel(config, use_gpu=True) # Entrenar metrics = model.fit( X_train, y_bos, y_poi, y_continuation, X_val, y_bos_val, y_poi_val, y_continuation_val ) # Prediccion predictions = model.predict(X_new) for pred in predictions: print(f"Next BOS: {pred.next_bos_direction}") print(f"POI Reaction: {pred.poi_reaction_prob:.2%}") print(f"Trading Bias: {pred.trading_bias}") ``` ### Clase MSAPrediction ```python @dataclass class MSAPrediction: # BOS prediction next_bos_direction: str # 'bullish', 'bearish', 'neutral' bos_confidence: float # 0 to 1 bos_probabilities: Dict[str, float] # POI reaction poi_reaction_prob: float # 0 to 1 poi_reaction_direction: str # 'bullish', 'bearish', 'none' # Structure continuation structure_continuation_prob: float expected_structure: str # 'bullish_continuation', 'bearish_continuation', 'reversal' @property def trading_bias(self) -> str: """Get overall trading bias""" if self.bos_confidence >= 0.7: if self.next_bos_direction == 'bullish': return 'LONG_BIAS' elif self.next_bos_direction == 'bearish': return 'SHORT_BIAS' return 'NEUTRAL' @property def signal_strength(self) -> float: """Calculate overall signal strength 0-1""" bos_factor = self.bos_confidence if self.next_bos_direction != 'neutral' else 0 poi_factor = self.poi_reaction_prob * 0.5 cont_factor = self.structure_continuation_prob * 0.3 return min(1.0, bos_factor + poi_factor + cont_factor) ``` ### Feature Importance ```python # Obtener importancia de features por clasificador importance = model.get_feature_importance(top_n=20) print("BOS Direction - Top Features:") for feat, imp in importance['bos'].items(): print(f" {feat}: {imp:.4f}") print("POI Reaction - Top Features:") for feat, imp in importance['poi'].items(): print(f" {feat}: {imp:.4f}") ``` --- ## Estructura de Archivos ``` apps/ml-engine/src/models/strategies/msa/ ├── __init__.py ├── model.py # MSAModel, MSAPrediction, MSAMetrics ├── feature_engineering.py # MSAFeatureEngineer (60+ features) ├── structure_detector.py # StructureDetector (BOS, CHoCH, FVG, OB) ├── gnn_component.py # Optional SwingPointGNN └── trainer.py # MSATrainer ``` --- ## Estrategias de Trading ### Entry Signals ```python def generate_entry_signal(pred: MSAPrediction) -> Optional[Dict]: """Generar senal de entrada basada en MSA""" # Long Setup if (pred.next_bos_direction == 'bullish' and pred.bos_confidence >= 0.7 and pred.poi_reaction_prob >= 0.6 and pred.structure_continuation_prob >= 0.6): return { 'direction': 'LONG', 'confidence': pred.signal_strength, 'reason': 'MSA Bullish Confluence' } # Short Setup if (pred.next_bos_direction == 'bearish' and pred.bos_confidence >= 0.7 and pred.poi_reaction_prob >= 0.6 and pred.structure_continuation_prob >= 0.6): return { 'direction': 'SHORT', 'confidence': pred.signal_strength, 'reason': 'MSA Bearish Confluence' } return None ``` ### POI-Based Entry ```python def check_poi_entry(price: float, pred: MSAPrediction) -> Optional[Dict]: """Verificar entrada en POI""" # Si estamos en un POI con alta probabilidad de reaccion if pred.poi_reaction_prob >= 0.7: direction = 'LONG' if pred.poi_reaction_direction == 'bullish' else 'SHORT' return { 'type': 'POI_REACTION', 'direction': direction, 'confidence': pred.poi_reaction_prob } return None ``` --- ## Consideraciones de Produccion ### Real-Time Structure Analysis ```python class MSARealtime: def __init__(self, model_path: str, swing_order: int = 5): self.model = MSAModel.load(model_path) self.detector = StructureDetector(swing_order=swing_order) self.engineer = MSAFeatureEngineer(swing_order=swing_order) self.buffer = deque(maxlen=200) def on_candle(self, candle: Dict) -> Optional[MSAPrediction]: self.buffer.append(candle) if len(self.buffer) >= 100: df = pd.DataFrame(list(self.buffer)) features = self.engineer.compute_structure_features(df) return self.model.predict_single(features.iloc[-1:]) return None ``` ### Caching de Structure Analysis ```python # La estructura no cambia frecuentemente # Cache por 5-10 candles @cached(ttl=60) # 5 candles de 5 minutos def get_structure_analysis(symbol: str) -> StructureAnalysis: df = get_recent_data(symbol, bars=200) return detector.analyze(df) ``` ### Performance | Operacion | Tiempo | Notas | |-----------|--------|-------| | Structure detection | 50ms | 200 bars | | Feature engineering | 30ms | 60+ features | | XGBoost prediction | 5ms | 3 classifiers | | **Total** | ~85ms | Per prediction | --- ## Referencias - [ET-ML-001: Arquitectura ML Engine](./ET-ML-001-arquitectura.md) - [ICT Concepts](https://www.youtube.com/c/TheInnerCircleTrader) - [Smart Money Concepts](https://www.tradingview.com/scripts/smartmoneyconcepts/) - [XGBoost Documentation](https://xgboost.readthedocs.io/) --- **Autor:** ML-Specialist (NEXUS v4.0) **Fecha:** 2026-01-25