# Estrategia AMD (Accumulation-Manipulation-Distribution)

**Versi\u00f3n:** 1.0.0
**Fecha:** 2025-12-05
**M\u00f3dulo:** OQI-006-ml-signals
**Autor:** Trading Strategist - OrbiQuant IA

---

## Tabla de Contenidos

1. [Introducci\u00f3n](#introducci\u00f3n)
2. [Conceptos Fundamentales](#conceptos-fundamentales)
3. [Fase 1: Accumulation](#fase-1-accumulation)
4. [Fase 2: Manipulation](#fase-2-manipulation)
5. [Fase 3: Distribution](#fase-3-distribution)
6. [Detecci\u00f3n de Transiciones](#detecci\u00f3n-de-transiciones)
7. [Indicadores T\u00e9cnicos para AMD](#indicadores-t\u00e9cnicos-para-amd)
8. [Integraci\u00f3n con Modelos ML](#integraci\u00f3n-con-modelos-ml)
9. [Implementaci\u00f3n Pr\u00e1ctica](#implementaci\u00f3n-pr\u00e1ctica)
10. [Referencias](#referencias)

---

## Introducci\u00f3n

La estrategia AMD es un marco conceptual desarrollado por Richard Wyckoff que describe c\u00f3mo el "dinero inteligente" (instituciones financieras, market makers, hedge funds) opera en los mercados. El ciclo AMD se compone de tres fases secuenciales que se repiten continuamente:

```
ACCUMULATION → MANIPULATION → DISTRIBUTION → [CICLO REINICIA]
```

### Principios Clave

1. **Smart Money vs Retail**: Las instituciones acumulan cuando los minoristas venden, y distribuyen cuando los minoristas compran
2. **Ciclo Perpetuo**: Los mercados siempre est\u00e1n en alguna fase del ciclo AMD
3. **Volumen como Confirmaci\u00f3n**: El volumen institucional deja huellas detectables
4. **Liquidez como Combustible**: Las instituciones necesitan liquidez para entrar/salir de posiciones grandes

### Objetivos de la Estrategia

- **Identificar** la fase actual del mercado con alta precisi\u00f3n (>70%)
- **Predecir** transiciones entre fases antes de que ocurran
- **Operar** alineado con el dinero inteligente, no contra \u00e9l
- **Evitar** falsas rupturas y manipulaciones (stop hunting)

---

## Conceptos Fundamentales

### Smart Money Concepts (SMC)

El dinero inteligente opera bajo principios espec\u00edficos:

| Concepto | Descripci\u00f3n | Implicaci\u00f3n |
|----------|----------------|------------------|
| **Order Flow** | Flujo de \u00f3rdenes institucionales | Movimientos grandes dejan rastro en volumen y precio |
| **Liquidity Pools** | Zonas de concentraci\u00f3n de stops | Instituciones "cazan" liquidez antes de moverse |
| **Market Structure** | Estructura de highs/lows | Rupturas de estructura se\u00f1alan cambios de fase |
| **Fair Value Gaps** | Desequilibrios de precio | Zonas donde el precio se movi\u00f3 sin consolidar |
| **Order Blocks** | Zonas de acumulaci\u00f3n/distribuci\u00f3n | \u00daltimo movimiento institucional antes de impulso |

### El Ciclo Wyckoff Completo

```
┌─────────────────────────────────────────────────────────────────┐
│                         CICLO AMD                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ACCUMULATION           MANIPULATION          DISTRIBUTION      │
│  ┌───────────┐          ┌──────────┐          ┌──────────┐     │
│  │           │          │          │          │          │     │
│  │ LOW VOL   │─────────▶│ HIGH VOL │─────────▶│ HIGH VOL │     │
│  │ TIGHT RNG │          │ WHIPSAWS │          │ DOWN BIAS│     │
│  │ BUYING    │          │ FAKEOUTS │          │ SELLING  │     │
│  │           │          │          │          │          │     │
│  └───────────┘          └──────────┘          └──────────┘     │
│       ▲                                            │            │
│       │                                            │            │
│       └────────────────────────────────────────────┘            │
│                    CICLO REINICIA                               │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

### Caracter\u00edsticas de Cada Fase

| Fase | Volumen | Volatilidad | Precio | Tendencia | Sentimiento |
|------|---------|-------------|--------|-----------|-------------|
| **Accumulation** | Bajo/Decreciente | Baja | Lateral/Compresi\u00f3n | Rango | Apatía/Capitulaci\u00f3n |
| **Manipulation** | Alto/Errático | Alta | Whipsaws | Sin dirección clara | Confusi\u00f3n/Miedo |
| **Distribution** | Alto/Decreciente | Media-Alta | Bajista | Debilidad | Euforia→Pánico |

---

## Fase 1: Accumulation

### Definici\u00f3n

La acumulaci\u00f3n es la fase donde el dinero inteligente construye posiciones largas a precios bajos, absorbiendo la oferta de traders minoristas que est\u00e1n vendiendo por miedo o desesperaci\u00f3n.

### Caracter\u00edsticas Principales

#### 1. Rango de Consolidaci\u00f3n Estrecho

```python
# Compresi\u00f3n de rango
range_compression = current_range / average_range_20
# Accumulation si: range_compression < 0.7 (30% menos que el promedio)
```

**Criterios:**
- Rango High-Low < 70% del promedio de 20 periodos
- Precio se mantiene en zona de soporte
- Cuerpos de velas peque\u00f1os (body_size < 0.5 * ATR)

#### 2. Volumen Decreciente o Bajo

```python
# Patr\u00f3n de volumen
volume_ratio = current_volume / sma_volume_20
# Accumulation si: volume_ratio < 0.7
```

**Observaciones:**
- Volumen disminuye progresivamente
- Picos de volumen en rebounds desde soporte
- Volumen bajo en retesteos de resistencia

#### 3. Buying Pressure Oculta

```python
# Presi\u00f3n compradora
buying_pressure = (close - low) / (high - low)
# Accumulation si: buying_pressure > 0.55 (cierre en 55%+ del rango)
```

**Indicadores:**
- Cierres consistentemente por encima del 50% del rango
- Mechas inferiores largas (rechazo de precios bajos)
- Support holds (soporte no se rompe)

#### 4. Order Blocks Bullish

**Definici\u00f3n:** Zonas donde instituciones acumularon antes de un movimiento alcista

**Detecci\u00f3n:**
```python
# Order block bullish
if close[i] > high[i-1] and volume[i] > volume_avg * 1.5:
    order_block = {
        'type': 'bullish',
        'zone': (low[i-1], high[i-1]),
        'strength': volume[i] / volume_avg
    }
```

**Caracter\u00edsticas:**
- Movimiento fuerte al alza con alto volumen
- Zona anterior de consolidaci\u00f3n
- Precio no vuelve a visitar (demand zone)

#### 5. Market Structure

**Patr\u00f3n de Higher Lows:**
```
Higher Low #3
    /\
   /  \
  /    \     Higher Low #2
 /      \     /\
/        \   /  \
          \ /    \  Higher Low #1
           V      \ /\
                   V  \
                       V
```

**Criterios:**
- Cada low es m\u00e1s alto que el anterior
- Resistencia no se rompe a\u00fan
- Estructura alcista formándose

### Subfases de Accumulation (Wyckoff)

#### PS - Preliminary Support
- Primera se\u00f1al de inter\u00e9s de compra
- Volumen aumenta en caídas pero precio no cae tanto

#### SC - Selling Climax
- Capitulaci\u00f3n final de vendedores
- Volumen extremadamente alto
- Reversión rápida (V-bottom)

#### AR - Automatic Rally
- Rebote autom\u00e1tico después del SC
- Prueba que hay demand

#### ST - Secondary Test
- Retesteo del low formado en SC
- Volumen MENOR que SC (confirmaci\u00f3n)

#### Spring (Manipulaci\u00f3n Bullish)
- Falsa ruptura del soporte
- "Stop hunting" de posiciones cortas
- Reversi\u00f3n r\u00e1pida al rango
- **CLAVE:** Se\u00f1al de que acumulaci\u00f3n est\u00e1 completa

### Indicadores T\u00e9cnicos para Accumulation

| Indicador | Condici\u00f3n | Peso | Justificaci\u00f3n |
|-----------|-------------|------|-------------------|
| **Range Compression** | range_ratio < 0.7 | 25% | Consolidaci\u00f3n estrecha |
| **Volume Pattern** | Corr(price_up, volume_up) > 0.3 | 25% | Volumen en alzas |
| **ATR Ratio** | atr_ratio < 1.0 | 20% | Volatilidad baja |
| **Bullish Order Blocks** | count > 5 en 30 periodos | 15% | Acumulaci\u00f3n institucional |
| **Buying Pressure** | buying_pressure > 0.55 | 15% | Cierres alcistas |

**Score de Accumulation:**
```python
accumulation_score = (
    0.25 * range_compression_signal +
    0.25 * volume_pattern_signal +
    0.20 * low_volatility_signal +
    0.15 * order_blocks_signal +
    0.15 * buying_pressure_signal
)

# Accumulation confirmada si score > 0.6
```

### Estrategias de Trading en Accumulation

#### Estrategia 1: Spring Trading
```
SETUP:
1. Identificar rango de acumulaci\u00f3n (min 20 periodos)
2. Esperar spring (falsa ruptura del soporte)
3. Confirmar reversi\u00f3n (cierre dentro del rango)

ENTRY:
- Compra cuando precio vuelve al rango
- Entry: Close above spring low

STOP LOSS:
- Below spring low (falsa ruptura)
- Distancia: 1.5 * ATR

TAKE PROFIT:
- Resistencia del rango (top de acumulaci\u00f3n)
- R:R m\u00ednimo 2:1
```

#### Estrategia 2: Breakout de Acumulaci\u00f3n
```
SETUP:
1. Accumulation confirmada (score > 0.6)
2. Esperar breakout de resistencia
3. Volumen confirma (> 1.5x average)

ENTRY:
- Pullback al level de breakout (retest)
- Entry: Rejection del retest

STOP LOSS:
- Middle del rango de acumulaci\u00f3n
- Distancia: 2 * ATR

TAKE PROFIT:
- Altura del rango proyectada hacia arriba
- R:R m\u00ednimo 3:1
```

### Ejemplos de Accumulation

#### XAUUSD Accumulation (Ejemplo)
```
Periodo: 2024-10-15 a 2024-10-22
Precio: $2,310 - $2,325 (rango de $15)
ATR: $22

Señales:
- Range compression: 0.68 (32% menor que promedio)
- Volume ratio: 0.65 (35% menor)
- Higher lows: 3 consecutivos
- Buying pressure: 0.62
- Order blocks bullish: 6

Score Accumulation: 0.78 → CONFIRMADO

Resultado:
- Spring el 2024-10-21 a $2,305 (falso break)
- Breakout el 2024-10-24 a $2,340
- Movimiento: +$35 (+1.5%)
```

---

## Fase 2: Manipulation

### Definici\u00f3n

La manipulaci\u00f3n es la fase donde las instituciones "cazan" liquidez mediante movimientos falsos, atrapando a traders minoristas en posiciones perdedoras antes de iniciar el movimiento real.

### Prop\u00f3sito de la Manipulaci\u00f3n

1. **Liquidity Grab**: Activar stop losses para obtener liquidez
2. **Shake Out**: Expulsar traders débiles de buenas posiciones
3. **Create Liquidity**: Generar contrapartida para posiciones institucionales grandes
4. **Test Levels**: Probar niveles clave antes del movimiento real

### Tipos de Manipulaci\u00f3n

#### 1. Spring (Wyckoff)
**Manipulaci\u00f3n Bullish**

```
Resistencia
─────────────────────────────────
         │
  Rango  │         ┌────MARKUP
         │        /
─────────┼───────/──────────────
 Soporte │      /
         │     /
         ▼    /
      SPRING (falso break)
         │
    [LIQUIDEZ]
```

**Caracter\u00edsticas:**
- Falsa ruptura del soporte
- Volumen alto en ruptura falsa
- Reversi\u00f3n r\u00e1pida al rango (< 3 velas)
- Caza de stops de traders largos

**Detecci\u00f3n:**
```python
def detect_spring(df, i):
    support = df['low'].iloc[i-20:i].min()

    # Falsa ruptura
    if df['low'].iloc[i] < support * 0.995:
        # Reversi\u00f3n r\u00e1pida
        if df['close'].iloc[i] > support:
            # Volumen alto
            if df['volume'].iloc[i] > df['volume'].iloc[i-20:i].mean() * 1.5:
                return True
    return False
```

#### 2. Upthrust (Wyckoff)
**Manipulaci\u00f3n Bearish**

```
         UPTHRUST (falso break)
              │
         [LIQUIDEZ]
              ▼
─────────┬────────────────────
Resistencia   \
         │     \
  Rango  │      \
         │       \______MARKDOWN
─────────┴───────────────────────
 Soporte
```

**Caracter\u00edsticas:**
- Falsa ruptura de resistencia
- Volumen alto pero sin seguimiento
- Reversi\u00f3n bajista inmediata
- Caza de stops de traders cortos

#### 3. Stop Hunt (Modern SMC)
**Barrido de Liquidez**

```
BSL (Buy Side Liquidity)
    ↑ [Stops largos]
────┼────────────────
    │    /\  Sweep
    │   /  \
────┼──/────\─────────
    │        \
              \_____ Movimiento real
```

**Tipos:**
- **BSL Hunt**: Sweep de highs para activar stops de cortos
- **SSL Hunt**: Sweep de lows para activar stops de largos

**Identificaci\u00f3n:**
```python
def detect_liquidity_hunt(df, i):
    # Swing high de últimos 20 periodos
    swing_high = df['high'].iloc[i-20:i].max()

    # Sweep del high
    if df['high'].iloc[i] > swing_high * 1.005:
        # Rechazo inmediato
        if df['close'].iloc[i] < swing_high:
            return {
                'type': 'BSL_hunt',
                'liquidity_level': swing_high,
                'sweep_distance': df['high'].iloc[i] - swing_high
            }
    return None
```

### Caracter\u00edsticas de Manipulation

#### 1. Volatilidad Alta

```python
atr_ratio = current_atr / atr_50_average
# Manipulation si: atr_ratio > 1.3 (30% mayor que promedio)
```

#### 2. Whipsaw Price Action

```python
# Reversiones r\u00e1pidas
price_changes = df['close'].pct_change()
reversals = ((price_changes > 0.01) & (price_changes.shift(-1) < -0.01)).sum()
whipsaw_intensity = reversals / len(df)

# Manipulation si: whipsaw_intensity > 0.3
```

#### 3. False Breakouts

```python
def count_false_breakouts(df, window=30):
    false_breaks = 0
    for i in range(window, len(df)):
        # Breakout de resistencia
        if df['high'].iloc[i] > df['high'].iloc[i-window:i].max() * 1.01:
            # Falla (close below breakout)
            if df['close'].iloc[i+2] < df['close'].iloc[i]:
                false_breaks += 1
    return false_breaks
```

#### 4. Volumen An\u00f3malo

**Spikes sin Seguimiento:**
```python
volume_spikes = (df['volume'] > df['volume'].rolling(20).mean() * 2.0).sum()
# Manipulation si: volume_spikes > 3 en \u00faltimas 30 velas
```

### Indicadores para Manipulation

| Indicador | Condici\u00f3n | Peso | Se\u00f1al |
|-----------|-------------|------|---------|
| **Liquidity Grabs** | count > 3 en 30 periodos | 30% | Stop hunting activo |
| **Whipsaws** | intensity > 0.3 | 25% | Movimientos erráticos |
| **False Breakouts** | ratio > 0.4 | 25% | Falsas rupturas |
| **Volume Spikes** | spikes > 3 | 20% | Volumen an\u00f3malo |

**Score de Manipulation:**
```python
manipulation_score = (
    0.30 * liquidity_grabs_signal +
    0.25 * whipsaw_signal +
    0.25 * false_breakouts_signal +
    0.20 * volume_anomalies_signal
)

# Manipulation confirmada si score > 0.6
```

### Estrategias de Trading en Manipulation

#### Estrategia 1: Fade the Fake (Desvanece lo Falso)
```
CONCEPTO:
- Operar CONTRA la ruptura falsa
- Entrada en reversi\u00f3n

SETUP:
1. Identificar manipulation (score > 0.6)
2. Esperar false breakout
3. Confirmar rechazo del nivel

ENTRY:
- Reversi\u00f3n confirmada (cierre opuesto)
- Entry: Close back inside range

STOP LOSS:
- Beyond extreme del false breakout
- Tight stop (1 * ATR)

TAKE PROFIT:
- Lado opuesto del rango
- R:R 3:1+
```

#### Estrategia 2: Wait for Confirmation
```
CONCEPTO:
- NO operar durante manipulation
- Esperar a que termine la fase

CRITERIOS DE ESPERA:
- Manipulation score > 0.6
- False breakouts frecuentes
- Volumen errático

ENTRY:
- Solo cuando manipulation score < 0.5
- Clear break de rango con volumen
- Retest exitoso

VENTAJA:
- Evita whipsaws
- Mejor R:R
- Menor estr\u00e9s
```

### Fair Value Gaps (FVG) en Manipulation

**Definici\u00f3n:** Zonas donde precio se movi\u00f3 r\u00e1pido sin consolidar

```
Gap Bullish:
  High[i-2] < Low[i]

   i-2    i-1     i
  ──┐           ┌──
    │    GAP   /
    └─────────/
         FVG (imbalance)
```

**Detecci\u00f3n:**
```python
def identify_fvg(df, i):
    # Bullish FVG
    if df['low'].iloc[i] > df['high'].iloc[i-2]:
        gap_size = df['low'].iloc[i] - df['high'].iloc[i-2]
        return {
            'type': 'bullish',
            'zone': (df['high'].iloc[i-2], df['low'].iloc[i]),
            'size_pct': gap_size / df['close'].iloc[i]
        }

    # Bearish FVG
    elif df['high'].iloc[i] < df['low'].iloc[i-2]:
        gap_size = df['low'].iloc[i-2] - df['high'].iloc[i]
        return {
            'type': 'bearish',
            'zone': (df['high'].iloc[i], df['low'].iloc[i-2]),
            'size_pct': gap_size / df['close'].iloc[i]
        }
    return None
```

**Uso en Trading:**
- FVG act\u00faa como imán (precio tiende a rellenarlos)
- Entrada cuando precio vuelve a FVG
- FVG = zona de alta probabilidad para reversi\u00f3n

---

## Fase 3: Distribution

### Definici\u00f3n

La distribuci\u00f3n es la fase donde el dinero inteligente vende posiciones a precios altos, transfiriendo holdings a traders minoristas que est\u00e1n comprando por codicia o FOMO (fear of missing out).

### Caracter\u00edsticas Principales

#### 1. Volumen Alto en Bajadas

```python
# Correlaci\u00f3n negativa precio-volumen
price_change = df['close'].pct_change()
volume_corr = price_change.corr(df['volume'] / df['volume'].rolling(20).mean())

# Distribution si: volume_corr < -0.3
```

#### 2. Debilidad de Precio

```python
# Tendencia bajista emergente
trend_slope = df['close'].rolling(20).mean().diff(5) / 5
# Distribution si: trend_slope < 0
```

#### 3. Lower Highs Pattern

```
Lower High #1   Lower High #2   Lower High #3
     /\              /\              /\
    /  \            /  \            /  \
   /    \          /    \          /    \
  /      \        /      \        /      \
 /        \      /        \      /        \
/          \    /          \    /          \
            \  /            \  /            \
             \/              \/              \/
        [Estructura Bajista]
```

#### 4. Selling Pressure

```python
selling_pressure = (high - close) / (high - low)
# Distribution si: selling_pressure > 0.55
```

#### 5. Bearish Order Blocks

**Zonas donde instituciones distribuyeron antes de caída:**
```python
# Order block bearish
if close[i] < low[i-1] and volume[i] > volume_avg * 1.5:
    order_block = {
        'type': 'bearish',
        'zone': (low[i-1], high[i-1]),
        'strength': volume[i] / volume_avg
    }
```

### Subfases de Distribution (Wyckoff)

#### PSY - Preliminary Supply
- Primera se\u00f1al de venta institucional
- Volumen aumenta en alzas pero precio no sube tanto

#### BC - Buying Climax
- Euforia final de compradores
- Volumen extremadamente alto
- Reversión rápida (M-top)

#### AR - Automatic Reaction
- Caída autom\u00e1tica despu\u00e9s del BC
- Prueba que hay supply

#### ST - Secondary Test
- Retesteo del high formado en BC
- Volumen MENOR que BC (confirmaci\u00f3n de debilidad)

#### UTAD - Upthrust After Distribution
- Falsa ruptura final de resistencia
- "Bull trap" - atrapa a compradores
- Reversión bearish inmediata
- **CLAVE:** Se\u00f1al de que distribuci\u00f3n est\u00e1 completa

### Indicadores para Distribution

| Indicador | Condici\u00f3n | Peso | Justificaci\u00f3n |
|-----------|-------------|------|-------------------|
| **Volume Pattern** | Corr(price_down, volume_up) < -0.3 | 25% | Volumen en caídas |
| **Price Weakness** | trend_slope < 0 | 25% | Tendencia bajista |
| **Lower Highs** | count < 5 en 20 periodos | 20% | Estructura d\u00e9bil |
| **Bearish Order Blocks** | count > 5 en 30 periodos | 15% | Distribuci\u00f3n institucional |
| **Selling Pressure** | selling_pressure > 0.55 | 15% | Cierres bajistas |

**Score de Distribution:**
```python
distribution_score = (
    0.25 * volume_pattern_signal +
    0.25 * price_weakness_signal +
    0.20 * lower_highs_signal +
    0.15 * bearish_order_blocks_signal +
    0.15 * selling_pressure_signal
)

# Distribution confirmada si score > 0.6
```

### Estrategias de Trading en Distribution

#### Estrategia 1: UTAD Short
```
SETUP:
1. Identificar rango de distribuci\u00f3n (min 20 periodos)
2. Esperar UTAD (falsa ruptura de resistencia)
3. Confirmar rechazo (cierre dentro del rango)

ENTRY:
- Venta cuando precio vuelve al rango
- Entry: Close below UTAD high

STOP LOSS:
- Above UTAD high
- Distancia: 1.5 * ATR

TAKE PROFIT:
- Soporte del rango (bottom de distribuci\u00f3n)
- R:R m\u00ednimo 2:1
```

#### Estrategia 2: Breakdown Short
```
SETUP:
1. Distribution confirmada (score > 0.6)
2. Esperar breakdown de soporte
3. Volumen confirma (> 1.5x average)

ENTRY:
- Pullback al level de breakdown (retest)
- Entry: Rejection del retest

STOP LOSS:
- Middle del rango de distribuci\u00f3n
- Distancia: 2 * ATR

TAKE PROFIT:
- Altura del rango proyectada hacia abajo
- R:R m\u00ednimo 3:1
```

---

## Detecci\u00f3n de Transiciones

### Transici\u00f3n: Accumulation → Manipulation

**Se\u00f1ales:**
```python
transition_signals = {
    'accumulation_mature': accumulation_score > 0.7 and duration > 20_bars,
    'volatility_spike': atr_ratio > 1.3,
    'volume_increase': volume_ratio > 1.5,
    'spring_detected': spring_count > 0
}

# Transici\u00f3n probable si 3+ se\u00f1ales activas
```

**Timeline T\u00edpico:**
- Accumulation: 15-30 velas (75-150 min en 5m)
- Spring (manipulation): 3-10 velas (15-50 min)
- Breakout: 1-5 velas

### Transici\u00f3n: Manipulation → Distribution

**Se\u00f1ales:**
```python
transition_signals = {
    'markup_complete': price > accumulation_high * 1.05,
    'volume_on_dips': volume_corr < -0.2,
    'lower_highs_forming': higher_highs_count < 3,
    'utad_detected': utad_count > 0
}
```

### Transici\u00f3n: Distribution → Accumulation

**Se\u00f1ales (Nuevo Ciclo):**
```python
transition_signals = {
    'markdown_complete': price < distribution_low * 0.95,
    'capitulation': volume_spike > 3.0 and price_drop > 0.03,
    'range_forming': range_compression < 0.7,
    'higher_lows': higher_lows_count > 2
}
```

### Matriz de Transiciones

| Desde → Hacia | Accumulation | Manipulation | Distribution |
|---------------|--------------|--------------|--------------|
| **Accumulation** | - | Spring/Breakout | Raro (solo si falla) |
| **Manipulation** | Si falla markup | - | Post-markup |
| **Distribution** | Post-markdown | UTAD | - |

---

## Indicadores T\u00e9cnicos para AMD

### 1. Volume Profile / VWAP

**Volume Profile:**
- Muestra distribuci\u00f3n de volumen por nivel de precio
- **POC (Point of Control)**: Nivel con m\u00e1s volumen
- **HVN (High Volume Nodes)**: Zonas de alta actividad
- **LVN (Low Volume Nodes)**: Zonas de baja actividad

```python
# Simplified Volume Profile
def calculate_volume_profile(df, bins=50):
    price_range = df['high'].max() - df['low'].min()
    bin_size = price_range / bins

    profile = {}
    for i in range(bins):
        price_level = df['low'].min() + (i * bin_size)
        # Volume en ese nivel
        mask = (df['low'] <= price_level) & (df['high'] >= price_level)
        profile[price_level] = df.loc[mask, 'volume'].sum()

    # POC
    poc = max(profile, key=profile.get)
    return profile, poc
```

**Uso en AMD:**
- **Accumulation**: POC cerca de soporte, HVN en rango bajo
- **Distribution**: POC cerca de resistencia, HVN en rango alto

**VWAP (Volume Weighted Average Price):**
```python
vwap = (df['close'] * df['volume']).cumsum() / df['volume'].cumsum()

# Bands
vwap_std = ((df['close'] - vwap)**2 * df['volume']).cumsum() / df['volume'].cumsum()
vwap_upper = vwap + 1.5 * np.sqrt(vwap_std)
vwap_lower = vwap - 1.5 * np.sqrt(vwap_std)
```

**Uso:**
- Precio > VWAP: Bullish bias
- Precio < VWAP: Bearish bias
- VWAP bands como soporte/resistencia din\u00e1mica

### 2. Order Blocks (POI - Points of Interest)

**Definici\u00f3n:** \u00daltima zona de consolidaci\u00f3n antes de movimiento fuerte

```python
def identify_order_blocks(df, window=5):
    order_blocks = []

    for i in range(window, len(df)):
        # Bullish OB: strong move up
        if df['close'].iloc[i] > df['high'].iloc[i-1]:
            volume_spike = df['volume'].iloc[i] > df['volume'].iloc[i-window:i].mean() * 1.5
            if volume_spike:
                order_blocks.append({
                    'type': 'bullish',
                    'index': i,
                    'zone': (df['low'].iloc[i-1], df['high'].iloc[i-1]),
                    'strength': df['volume'].iloc[i] / df['volume'].iloc[i-window:i].mean()
                })

        # Bearish OB: strong move down
        elif df['close'].iloc[i] < df['low'].iloc[i-1]:
            volume_spike = df['volume'].iloc[i] > df['volume'].iloc[i-window:i].mean() * 1.5
            if volume_spike:
                order_blocks.append({
                    'type': 'bearish',
                    'index': i,
                    'zone': (df['low'].iloc[i-1], df['high'].iloc[i-1]),
                    'strength': df['volume'].iloc[i] / df['volume'].iloc[i-window:i].mean()
                })

    return order_blocks
```

**Uso en Trading:**
- Order blocks = zonas de alta probabilidad de reversi\u00f3n
- Entrada cuando precio retesta OB
- OB bullish en accumulation, bearish en distribution

### 3. Fair Value Gaps (FVG)

**Ver secci\u00f3n Manipulation** para implementaci\u00f3n completa.

**Tipos:**
- **Bullish FVG**: Gap hacia arriba (imbalance alcista)
- **Bearish FVG**: Gap hacia abajo (imbalance bajista)

**Estrategia:**
- FVG no rellenados = zonas de soporte/resistencia futuras
- Entrada cuando precio vuelve a FVG (50% fill com\u00fan)

### 4. Liquidity Pools (BSL/SSL)

**BSL - Buy Side Liquidity:**
- Stops de traders cortos por encima de swing highs
- Instituciones "sweep" estos niveles antes de bajar

**SSL - Sell Side Liquidity:**
- Stops de traders largos por debajo de swing lows
- Instituciones "sweep" estos niveles antes de subir

```python
def identify_liquidity_pools(df, window=20):
    pools = []

    # BSL - Swing highs
    for i in range(window, len(df) - window):
        if df['high'].iloc[i] == df['high'].iloc[i-window:i+window].max():
            pools.append({
                'type': 'BSL',
                'price': df['high'].iloc[i],
                'index': i,
                'strength': 'major' if window >= 50 else 'minor'
            })

    # SSL - Swing lows
    for i in range(window, len(df) - window):
        if df['low'].iloc[i] == df['low'].iloc[i-window:i+window].min():
            pools.append({
                'type': 'SSL',
                'price': df['low'].iloc[i],
                'index': i,
                'strength': 'major' if window >= 50 else 'minor'
            })

    return pools
```

**Distancia a Liquidez:**
```python
# Feature para ML
bsl_distance = (nearest_bsl - current_price) / current_price
ssl_distance = (current_price - nearest_ssl) / current_price
```

### 5. Market Structure (BOS/CHOCH)

**BOS - Break of Structure:**
- Ruptura de high/low anterior en direcci\u00f3n de la tendencia
- Confirmaci\u00f3n de continuaci\u00f3n

**CHOCH - Change of Character:**
- Ruptura de estructura CONTRA la tendencia
- Se\u00f1al de reversi\u00f3n potencial

```python
def detect_market_structure(df, window=10):
    structure = []

    for i in range(window, len(df)):
        # Identify swing points
        is_swing_high = df['high'].iloc[i] == df['high'].iloc[i-window:i+window].max()
        is_swing_low = df['low'].iloc[i] == df['low'].iloc[i-window:i+window].min()

        if is_swing_high:
            # Check if BOS or CHOCH
            prev_high = df['high'].iloc[:i-window].max()
            if df['high'].iloc[i] > prev_high:
                structure.append({
                    'type': 'BOS_high',
                    'index': i,
                    'price': df['high'].iloc[i]
                })

        if is_swing_low:
            prev_low = df['low'].iloc[:i-window].min()
            if df['low'].iloc[i] < prev_low:
                structure.append({
                    'type': 'BOS_low',
                    'index': i,
                    'price': df['low'].iloc[i]
                })

    return structure
```

### 6. Imbalances (Supply/Demand Zones)

**Supply Zone (Zona de Oferta):**
- Zona donde instituciones vendieron
- Precio cae fuerte desde esta zona
- Futuro soporte si se convierte en demand

**Demand Zone (Zona de Demanda):**
- Zona donde instituciones compraron
- Precio sube fuerte desde esta zona
- Futuro resistencia si se convierte en supply

```python
def identify_imbalances(df, min_move=0.015):
    zones = []

    for i in range(5, len(df) - 5):
        # Demand zone (strong move up)
        move_up = (df['high'].iloc[i+5] - df['low'].iloc[i]) / df['low'].iloc[i]
        if move_up > min_move:
            zones.append({
                'type': 'demand',
                'zone': (df['low'].iloc[i-2:i+1].min(), df['high'].iloc[i-2:i+1].max()),
                'strength': move_up,
                'fresh': True  # Not retested yet
            })

        # Supply zone (strong move down)
        move_down = (df['high'].iloc[i] - df['low'].iloc[i+5]) / df['high'].iloc[i]
        if move_down > min_move:
            zones.append({
                'type': 'supply',
                'zone': (df['low'].iloc[i-2:i+1].min(), df['high'].iloc[i-2:i+1].max()),
                'strength': move_down,
                'fresh': True
            })

    return zones
```

---

## Integraci\u00f3n con Modelos ML

### AMDDetector como Feature Provider

El modelo AMDDetector se integra con otros modelos ML de la siguiente manera:

```
┌─────────────────┐
│   AMDDetector   │
│   (XGBoost)     │
└────────┬────────┘
         │
         ▼
  [Phase Detection]
         │
         ├──────────────────────────┐
         │                          │
         ▼                          ▼
┌─────────────────┐        ┌─────────────────┐
│ RangePredictor  │        │ TPSLClassifier  │
│   (XGBoost)     │        │   (XGBoost)     │
└────────┬────────┘        └────────┬────────┘
         │                          │
         └──────────┬───────────────┘
                    ▼
          ┌─────────────────┐
          │SignalGenerator  │
          │  (Meta-Model)   │
          └─────────────────┘
```

### Features Derivados de AMD

**Output del AMDDetector:**
```python
amd_output = {
    # Phase classification
    'phase': 'accumulation',  # or 'manipulation', 'distribution', 'neutral'
    'confidence': 0.78,

    # Phase characteristics
    'range_compression': 0.68,
    'buying_pressure': 0.62,
    'volume_trend': -0.15,
    'order_blocks_bullish': 6,
    'order_blocks_bearish': 1,

    # Manipulation signals
    'liquidity_grab_count': 2,
    'whipsaw_intensity': 0.25,
    'false_breakout_ratio': 0.3,

    # Distribution signals
    'selling_pressure': 0.42,
    'volume_divergence': 0.05,
    'lower_highs_count': 1,

    # Phase strength
    'strength': 0.71
}
```

**Features para RangePredictor:**
```python
# Features AMD para predicci\u00f3n de rangos
amd_features_for_range = [
    'phase_encoded',           # 0: neutral, 1: acc, 2: manip, 3: dist
    'phase_confidence',
    'phase_strength',
    'range_compression',
    'order_blocks_net',        # bullish - bearish
    'liquidity_grab_count',
    'bsl_distance',
    'ssl_distance',
    'fvg_count_bullish',
    'fvg_count_bearish'
]
```

**Features para TPSLClassifier:**
```python
# Features AMD para probabilidad TP/SL
amd_features_for_tpsl = [
    'phase_encoded',
    'phase_strength',
    'manipulation_score',      # Alta manipulaci\u00f3n = mayor riesgo
    'trend_alignment',         # Phase alineada con trend
    'liquidity_proximity',     # Cercan\u00eda a pools de liquidez
    'order_block_proximity',   # Distancia a OB m\u00e1s cercano
    'market_structure_breaks'  # BOS/CHOCH recientes
]
```

### Targets para Entrenar AMDDetector

```python
# Target principal: Fase AMD
target_phase = {
    0: 'neutral',
    1: 'accumulation',
    2: 'manipulation',
    3: 'distribution'
}

# Construcci\u00f3n del target
def label_amd_phase(df, i, forward_window=20):
    """
    Etiqueta la fase AMD basada en comportamiento futuro
    """
    future = df.iloc[i:i+forward_window]

    # Accumulation criteria
    if (future['high'].max() - future['low'].min()) / future['close'].iloc[0] < 0.02:
        # Rango estrecho
        if future['close'].iloc[-1] > future['close'].iloc[0]:
            return 1  # accumulation

    # Manipulation criteria
    false_breaks = count_false_breakouts(future)
    if false_breaks >= 2:
        return 2  # manipulation

    # Distribution criteria
    if future['close'].iloc[-1] < future['close'].iloc[0] * 0.98:
        # Caída significativa
        volume_on_down = check_volume_on_down_moves(future)
        if volume_on_down:
            return 3  # distribution

    return 0  # neutral
```

### Arquitectura del AMDDetector

**Modelo Recomendado:** XGBoost Multiclass

```python
from xgboost import XGBClassifier

amd_detector = XGBClassifier(
    objective='multi:softprob',
    num_class=4,  # neutral, acc, manip, dist
    n_estimators=300,
    max_depth=6,
    learning_rate=0.05,
    subsample=0.8,
    colsample_bytree=0.8,
    min_child_weight=5,
    gamma=0.2,
    reg_alpha=0.1,
    reg_lambda=1.0,
    scale_pos_weight=1.0,
    tree_method='hist',
    device='cuda',
    random_state=42
)
```

**Features de Entrada (50+):**
```python
amd_input_features = [
    # Price action (10)
    'range_ratio', 'range_ma', 'hl_range_pct',
    'body_size', 'upper_wick', 'lower_wick',
    'buying_pressure', 'selling_pressure',
    'close_position_in_range', 'range_expansion',

    # Volume (8)
    'volume_ratio', 'volume_trend', 'volume_ma',
    'volume_spike_count', 'volume_on_up', 'volume_on_down',
    'obv_slope', 'vwap_distance',

    # Volatility (6)
    'atr', 'atr_ratio', 'atr_percentile',
    'volatility_10', 'volatility_20', 'volatility_50',

    # Trend (8)
    'sma_10', 'sma_20', 'sma_50',
    'close_sma_ratio_20', 'sma_slope_20',
    'trend_strength', 'adx', 'trend_consistency',

    # Market structure (10)
    'higher_highs_count', 'higher_lows_count',
    'lower_highs_count', 'lower_lows_count',
    'swing_high_distance', 'swing_low_distance',
    'bos_count', 'choch_count',
    'market_structure_strength', 'structure_alignment',

    # Order flow (8)
    'order_blocks_bullish', 'order_blocks_bearish',
    'fvg_count_bullish', 'fvg_count_bearish',
    'liquidity_grab_count', 'false_breakout_count',
    'whipsaw_intensity', 'reversal_count',

    # Liquidity (5)
    'bsl_distance', 'ssl_distance',
    'bsl_strength', 'ssl_strength',
    'liquidity_density',

    # Time (5)
    'hour_sin', 'hour_cos', 'day_of_week',
    'is_session_overlap', 'time_in_phase'
]
```

### M\u00e9tricas de Evaluaci\u00f3n

**Para AMDDetector:**
```python
from sklearn.metrics import classification_report, confusion_matrix

# Accuracy por clase
accuracy_overall = (y_pred == y_true).mean()
accuracy_per_class = {
    'neutral': accuracy_score(y_true[y_true == 0], y_pred[y_true == 0]),
    'accumulation': accuracy_score(y_true[y_true == 1], y_pred[y_true == 1]),
    'manipulation': accuracy_score(y_true[y_true == 2], y_pred[y_true == 2]),
    'distribution': accuracy_score(y_true[y_true == 3], y_pred[y_true == 3])
}

# Confusion matrix
cm = confusion_matrix(y_true, y_pred)

# F1 scores
f1_macro = f1_score(y_true, y_pred, average='macro')
f1_weighted = f1_score(y_true, y_pred, average='weighted')

# Target: 70%+ accuracy overall, 60%+ per class
```

### Pipeline de Entrenamiento

```python
# 1. Preparar datos
X_train, y_train = prepare_amd_data(df_train)

# 2. Entrenar AMDDetector
amd_detector.fit(X_train, y_train)

# 3. Generar features AMD para otros modelos
amd_features_train = amd_detector.predict_proba(X_train)  # Soft probabilities
phase_train = amd_detector.predict(X_train)                # Hard labels

# 4. Concatenar con features existentes
X_range_train = np.hstack([X_train, amd_features_train])

# 5. Entrenar RangePredictor con features AMD
range_predictor.fit(X_range_train, y_range_train)

# 6. Similar para TPSLClassifier
X_tpsl_train = np.hstack([X_train, amd_features_train, range_predictions_train])
tpsl_classifier.fit(X_tpsl_train, y_tpsl_train)
```

---

## Implementaci\u00f3n Pr\u00e1ctica

### Clase AMDDetector Completa

**Ver `[LEGACY: apps/ml-engine - migrado desde TradingAgent]/src/strategies/amd_detector.py`** para implementaci\u00f3n existente.

**Mejoras Sugeridas:**

```python
class AMDDetectorV2:
    """
    Versi\u00f3n mejorada del detector AMD con ML
    """

    def __init__(self, config=None):
        self.config = config or self._default_config()
        self.model = self._init_model()
        self.scaler = StandardScaler()
        self.is_trained = False

    def _init_model(self):
        """Inicializar modelo XGBoost multiclass"""
        return XGBClassifier(
            objective='multi:softprob',
            num_class=4,
            **self.config['xgboost']
        )

    def train(self, df_train, df_val=None):
        """Entrenar detector AMD"""
        # 1. Extract features
        X_train = self._extract_features(df_train)

        # 2. Label phases
        y_train = self._label_phases(df_train)

        # 3. Scale features
        X_train_scaled = self.scaler.fit_transform(X_train)

        # 4. Train model
        eval_set = []
        if df_val is not None:
            X_val = self.scaler.transform(self._extract_features(df_val))
            y_val = self._label_phases(df_val)
            eval_set = [(X_val, y_val)]

        self.model.fit(
            X_train_scaled, y_train,
            eval_set=eval_set,
            verbose=100
        )

        self.is_trained = True

        # 5. Evaluate
        y_pred = self.model.predict(X_train_scaled)
        accuracy = accuracy_score(y_train, y_pred)
        print(f"Training accuracy: {accuracy:.2%}")

        return {
            'accuracy': accuracy,
            'classification_report': classification_report(y_train, y_pred)
        }

    def detect_phase(self, df):
        """Detectar fase AMD actual"""
        if not self.is_trained:
            raise RuntimeError("Model not trained")

        # Extract features from latest data
        features = self._extract_features(df)
        features_scaled = self.scaler.transform(features)

        # Predict
        phase_proba = self.model.predict_proba(features_scaled[-1].reshape(1, -1))[0]
        phase = self.model.predict(features_scaled[-1].reshape(1, -1))[0]

        phase_names = ['neutral', 'accumulation', 'manipulation', 'distribution']

        return {
            'phase': phase_names[phase],
            'confidence': phase_proba[phase],
            'probabilities': dict(zip(phase_names, phase_proba)),
            'timestamp': df.index[-1]
        }

    def _extract_features(self, df):
        """Extraer todas las features AMD"""
        # Implementar extracci\u00f3n de 50+ features listadas arriba
        pass

    def _label_phases(self, df, forward_window=20):
        """Etiquetar fases AMD"""
        # Implementar l\u00f3gica de labeling basada en comportamiento futuro
        pass
```

### Uso en Producci\u00f3n

```python
# 1. Inicializar detector
amd_detector = AMDDetectorV2()

# 2. Entrenar con datos hist\u00f3ricos
amd_detector.train(df_train, df_val)

# 3. Guardar modelo
amd_detector.save('models/amd_detector_v2.pkl')

# 4. En producci\u00f3n
amd_detector.load('models/amd_detector_v2.pkl')
current_phase = amd_detector.detect_phase(latest_data)

print(f"Fase actual: {current_phase['phase']}")
print(f"Confianza: {current_phase['confidence']:.2%}")

# 5. Usar fase para trading
if current_phase['phase'] == 'accumulation' and current_phase['confidence'] > 0.7:
    # Look for long entries
    signal = 'BUY'
elif current_phase['phase'] == 'distribution' and current_phase['confidence'] > 0.7:
    # Look for short entries or exits
    signal = 'SELL'
elif current_phase['phase'] == 'manipulation':
    # Avoid trading or fade false breakouts
    signal = 'HOLD'
```

---

## Referencias

### Literatura Fundamental

1. **Wyckoff, Richard D.** - "The Richard D. Wyckoff Method of Trading and Investing in Stocks" (1931)
2. **Williams, Larry** - "Long-Term Secrets to Short-Term Trading" (1999)
3. **Nison, Steve** - "Japanese Candlestick Charting Techniques" (1991)

### Smart Money Concepts

4. **ICT (Inner Circle Trader)** - YouTube Series on Market Maker Models
5. **Stacey Burke Trading** - Smart Money Concepts Breakdown
6. **The Trading Channel** - Order Flow & Liquidity Analysis

### Papers Acad\u00e9micos

7. Harris, L. (2003). "Trading and Exchanges: Market Microstructure for Practitioners"
8. Easley, D., et al. (2012). "Flow Toxicity and Liquidity in a High-Frequency World"
9. Cartea, Á., et al. (2015). "Algorithmic and High-Frequency Trading"

### Recursos Online

- **TradingView** - Community scripts for AMD detection
- **Wyckoff Analytics** - Modern Wyckoff method resources
- **Smart Money Concepts Hub** - Educational resources on SMC

---

**Documento Generado:** 2025-12-05
**Pr\u00f3xima Revisi\u00f3n:** 2025-Q1
**Contacto:** trading-strategist@orbiquant.ai
