---
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
