ML Engine Updates: - Updated BTCUSD with Polygon API data (2024-2025): 215,699 new records - Re-trained all ML models: Attention (R²: 0.223), Base, Metamodel (87.3% confidence) - Backtest results: +176.71R profit with aggressive_filter strategy Documentation Consolidation: - Created docs/99-analisis/_MAP.md index with 13 new analysis documents - Consolidated inventories: removed duplicates from orchestration/inventarios/ - Updated ML_INVENTORY.yml with BTCUSD metrics and training results - Added execution reports: FASE11-BTCUSD, correction issues, alignment validation Architecture & Integration: - Updated all module documentation with NEXUS v3.4 frontmatter - Fixed _MAP.md indexes across all folders - Updated orchestration plans and traces Files: 229 changed, 5064 insertions(+), 1872 deletions(-) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1427 lines
42 KiB
Markdown
1427 lines
42 KiB
Markdown
---
|
|
id: "ESTRATEGIA-AMD-COMPLETA"
|
|
title: "Estrategia AMD (Accumulation-Manipulation-Distribution)"
|
|
type: "Documentation"
|
|
project: "trading-platform"
|
|
version: "1.0.0"
|
|
updated_date: "2026-01-04"
|
|
---
|
|
|
|
# Estrategia AMD (Accumulation-Manipulation-Distribution)
|
|
|
|
**Versi\u00f3n:** 1.0.0
|
|
**Fecha:** 2025-12-05
|
|
**M\u00f3dulo:** OQI-006-ml-signals
|
|
**Autor:** Trading Strategist - Trading Platform
|
|
|
|
---
|
|
|
|
## 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@trading.ai
|