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>
42 KiB
| id | title | type | project | version | updated_date |
|---|---|---|---|---|---|
| ESTRATEGIA-AMD-COMPLETA | Estrategia AMD (Accumulation-Manipulation-Distribution) | Documentation | trading-platform | 1.0.0 | 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
- Introducci\u00f3n
- Conceptos Fundamentales
- Fase 1: Accumulation
- Fase 2: Manipulation
- Fase 3: Distribution
- Detecci\u00f3n de Transiciones
- Indicadores T\u00e9cnicos para AMD
- Integraci\u00f3n con Modelos ML
- Implementaci\u00f3n Pr\u00e1ctica
- 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
- Smart Money vs Retail: Las instituciones acumulan cuando los minoristas venden, y distribuyen cuando los minoristas compran
- Ciclo Perpetuo: Los mercados siempre est\u00e1n en alguna fase del ciclo AMD
- Volumen como Confirmaci\u00f3n: El volumen institucional deja huellas detectables
- 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
# 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
# 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
# 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:
# 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:
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
- Liquidity Grab: Activar stop losses para obtener liquidez
- Shake Out: Expulsar traders débiles de buenas posiciones
- Create Liquidity: Generar contrapartida para posiciones institucionales grandes
- 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:
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:
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
atr_ratio = current_atr / atr_50_average
# Manipulation si: atr_ratio > 1.3 (30% mayor que promedio)
2. Whipsaw Price Action
# 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
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:
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:
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:
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
# 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
# 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
selling_pressure = (high - close) / (high - low)
# Distribution si: selling_pressure > 0.55
5. Bearish Order Blocks
Zonas donde instituciones distribuyeron antes de caída:
# 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:
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:
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:
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):
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
# 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):
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
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
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:
# 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
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
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:
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:
# 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:
# 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
# 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
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+):
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:
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
# 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:
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
# 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
- Wyckoff, Richard D. - "The Richard D. Wyckoff Method of Trading and Investing in Stocks" (1931)
- Williams, Larry - "Long-Term Secrets to Short-Term Trading" (1999)
- Nison, Steve - "Japanese Candlestick Charting Techniques" (1991)
Smart Money Concepts
- ICT (Inner Circle Trader) - YouTube Series on Market Maker Models
- Stacey Burke Trading - Smart Money Concepts Breakdown
- The Trading Channel - Order Flow & Liquidity Analysis
Papers Acad\u00e9micos
- Harris, L. (2003). "Trading and Exchanges: Market Microstructure for Practitioners"
- Easley, D., et al. (2012). "Flow Toxicity and Liquidity in a High-Frequency World"
- 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