trading-platform/docs/90-transversal/estrategias/ESTRATEGIA-PREDICCION-RANGOS.md
rckrdmrd a7cca885f0 feat: Major platform documentation and architecture updates
Changes include:
- Updated architecture documentation
- Enhanced module definitions (OQI-001 to OQI-008)
- ML integration documentation updates
- Trading strategies documentation
- Orchestration and inventory updates
- Docker configuration updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 05:33:35 -06:00

768 lines
26 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: "ESTRATEGIA-PREDICCION-RANGOS"
title: "Estrategia de Predicción de Rangos para Entradas Óptimas"
type: "Documentation"
project: "trading-platform"
version: "1.0.0"
updated_date: "2026-01-04"
---
# Estrategia de Predicción de Rangos para Entradas Óptimas
**Versión:** 1.0
**Fecha:** 2025-12-05
**Estado:** En Análisis
**Objetivo:** Encontrar entradas con R:R 2:1 y 3:1 con alta efectividad
---
## 1. Visión General
### Objetivo Principal
Predecir **máximos y mínimos** en horizontes de:
- **15 minutos** (3 velas de 5min)
- **60 minutos** (12 velas de 5min / 4 velas de 15min)
Para generar entradas con:
- **R:R 3:1** → Efectividad objetivo: **≥80%**
- **R:R 2:1** → Efectividad objetivo: **≥90%**
### Por qué este enfoque funciona
```
Si predecimos correctamente:
- Máximo probable en próximos 60min: $105
- Mínimo probable en próximos 60min: $98
- Precio actual: $100
Entonces:
- Para LONG: Entry=$100, SL=$98 (riesgo $2), TP=$106 (reward $6) → R:R 3:1
- Para SHORT: Entry=$100, SL=$102 (riesgo $2), TP=$94 (reward $6) → R:R 3:1
Con predicción precisa de rangos, las entradas se vuelven matemáticamente favorables.
```
---
## 2. Arquitectura de Modelos ML
### 2.1 Modelo Principal: RangePredictor
```
┌─────────────────────────────────────────────────────────────┐
│ RANGE PREDICTOR │
├─────────────────────────────────────────────────────────────┤
│ Input: Features técnicas + contextuales │
│ Output: │
│ - delta_high_15m: % máximo esperado en 15min │
│ - delta_low_15m: % mínimo esperado en 15min │
│ - delta_high_60m: % máximo esperado en 60min │
│ - delta_low_60m: % mínimo esperado en 60min │
│ - confidence: nivel de confianza (0-1) │
└─────────────────────────────────────────────────────────────┘
```
### 2.2 Modelos Auxiliares (Ensemble)
```
┌─────────────────────┐ ┌─────────────────────┐
│ TrendClassifier │ │ VolatilityPredictor │
│ (Dirección) │ │ (Rango esperado) │
└─────────┬───────────┘ └──────────┬──────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────┐
│ ENSEMBLE COMBINER │
│ Pondera predicciones según contexto de mercado │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ ENTRY SIGNAL GENERATOR │
│ - Calcula R:R basado en predicciones │
│ - Filtra señales por umbral de confianza │
│ - Genera TP/SL óptimos │
└─────────────────────────────────────────────────┘
```
---
## 3. Features para Predicción de Rangos
### 3.1 Features de Volatilidad (Críticas)
| Feature | Descripción | Importancia |
|---------|-------------|-------------|
| `atr_5` | ATR 5 períodos (volatilidad reciente) | ⭐⭐⭐ |
| `atr_14` | ATR 14 períodos (volatilidad media) | ⭐⭐⭐ |
| `atr_ratio` | ATR_5 / ATR_14 (expansión/contracción) | ⭐⭐⭐ |
| `bb_width` | Ancho de Bollinger Bands | ⭐⭐⭐ |
| `bb_squeeze` | ¿Está en squeeze? (bool) | ⭐⭐⭐ |
| `range_5` | (High-Low)/Close últimas 5 velas | ⭐⭐ |
| `range_20` | (High-Low)/Close últimas 20 velas | ⭐⭐ |
### 3.2 Features de Estructura de Mercado
| Feature | Descripción | Importancia |
|---------|-------------|-------------|
| `dist_to_support` | Distancia % al soporte más cercano | ⭐⭐⭐ |
| `dist_to_resistance` | Distancia % a la resistencia más cercana | ⭐⭐⭐ |
| `in_range` | ¿Precio dentro de rango definido? | ⭐⭐ |
| `range_position` | Posición dentro del rango (0-1) | ⭐⭐ |
| `swing_high_dist` | Distancia al último swing high | ⭐⭐ |
| `swing_low_dist` | Distancia al último swing low | ⭐⭐ |
### 3.3 Features de Tendencia
| Feature | Descripción | Importancia |
|---------|-------------|-------------|
| `trend_adx` | Fuerza de tendencia (ADX) | ⭐⭐⭐ |
| `trend_direction` | +DI vs -DI | ⭐⭐ |
| `ema_slope_20` | Pendiente de EMA 20 | ⭐⭐ |
| `price_vs_ema_20` | Precio / EMA 20 | ⭐⭐ |
| `price_vs_ema_50` | Precio / EMA 50 | ⭐⭐ |
| `higher_tf_trend` | Tendencia en timeframe superior | ⭐⭐⭐ |
### 3.4 Features de Momentum
| Feature | Descripción | Importancia |
|---------|-------------|-------------|
| `rsi_14` | RSI 14 períodos | ⭐⭐ |
| `rsi_divergence` | Divergencia RSI detectada | ⭐⭐⭐ |
| `macd_histogram` | Histograma MACD | ⭐⭐ |
| `macd_divergence` | Divergencia MACD | ⭐⭐⭐ |
| `momentum_10` | Rate of Change 10 períodos | ⭐⭐ |
| `stoch_k` | Stochastic %K | ⭐⭐ |
### 3.5 Features de Volumen
| Feature | Descripción | Importancia |
|---------|-------------|-------------|
| `volume_ratio` | Volumen actual / Volumen promedio 20 | ⭐⭐⭐ |
| `volume_trend` | Tendencia del volumen | ⭐⭐ |
| `obv_slope` | Pendiente de OBV | ⭐⭐ |
| `vwap_dist` | Distancia al VWAP | ⭐⭐ |
### 3.6 Features AMD (Wyckoff)
| Feature | Descripción | Importancia |
|---------|-------------|-------------|
| `amd_phase` | Fase actual (A/M/D) | ⭐⭐⭐ |
| `accumulation_score` | Probabilidad de acumulación | ⭐⭐⭐ |
| `distribution_score` | Probabilidad de distribución | ⭐⭐⭐ |
| `spring_detected` | ¿Spring detectado? | ⭐⭐⭐ |
| `upthrust_detected` | ¿Upthrust detectado? | ⭐⭐⭐ |
---
## 4. Estrategias Complementarias a AMD
### 4.1 Estrategia: Volatility Contraction Pattern (VCP)
**Concepto:** Entrar cuando la volatilidad se contrae antes de expansión.
```python
class VCPStrategy:
"""
Volatility Contraction Pattern - Mark Minervini
Detecta contracciones de volatilidad que preceden movimientos explosivos.
Ideal para encontrar máximos/mínimos antes de breakouts.
"""
def detect_vcp(self, df: pd.DataFrame) -> pd.Series:
# Detectar series de contracciones
# Cada contracción debe ser menor que la anterior
contractions = []
for i in range(len(df) - 20):
ranges = []
for j in range(4): # 4 contracciones típicas
window = df.iloc[i + j*5 : i + (j+1)*5]
range_pct = (window['high'].max() - window['low'].min()) / window['close'].mean()
ranges.append(range_pct)
# VCP válido si cada contracción es menor
if all(ranges[i] > ranges[i+1] for i in range(len(ranges)-1)):
contractions.append(i + 20)
return contractions
def predict_breakout_range(self, df: pd.DataFrame, vcp_idx: int) -> dict:
"""Predice el rango del breakout basado en contracciones previas."""
first_contraction_range = ... # Rango de primera contracción
return {
'expected_move': first_contraction_range * 1.5, # Típicamente 1.5x
'direction': self.determine_direction(df, vcp_idx)
}
```
**Utilidad para predicción de rangos:**
- El rango de la primera contracción predice el movimiento esperado
- Alta probabilidad de alcanzar el target
---
### 4.2 Estrategia: Order Block Detection
**Concepto:** Zonas institucionales donde el precio probablemente reaccione.
```python
class OrderBlockStrategy:
"""
Order Blocks - Smart Money Concepts
Identifica zonas donde instituciones dejaron órdenes.
Estas zonas actúan como imanes para el precio.
"""
def find_order_blocks(self, df: pd.DataFrame) -> List[OrderBlock]:
order_blocks = []
for i in range(3, len(df)):
# Bullish Order Block
# Vela bajista seguida de movimiento impulsivo alcista
if (df['close'].iloc[i-2] < df['open'].iloc[i-2] and # Vela bajista
df['close'].iloc[i] > df['high'].iloc[i-1] and # Impulso alcista
df['volume'].iloc[i] > df['volume'].iloc[i-1] * 1.5): # Alto volumen
order_blocks.append(OrderBlock(
type='bullish',
top=df['open'].iloc[i-2],
bottom=df['close'].iloc[i-2],
strength=self.calculate_strength(df, i)
))
# Bearish Order Block (inverso)
...
return order_blocks
def predict_reaction_zone(self, current_price: float,
order_blocks: List[OrderBlock]) -> dict:
"""Predice dónde el precio probablemente reaccione."""
nearest_bullish = self.find_nearest(order_blocks, 'bullish', current_price)
nearest_bearish = self.find_nearest(order_blocks, 'bearish', current_price)
return {
'probable_low': nearest_bullish.bottom if nearest_bullish else None,
'probable_high': nearest_bearish.top if nearest_bearish else None
}
```
**Utilidad para predicción de rangos:**
- Predice zonas de soporte/resistencia institucional
- Alta probabilidad de reacción en estos niveles
---
### 4.3 Estrategia: Fair Value Gap (FVG)
**Concepto:** Gaps de valor justo que el precio tiende a llenar.
```python
class FairValueGapStrategy:
"""
Fair Value Gaps - ICT Concepts
Detecta gaps de eficiencia que el precio tiende a revisitar.
Excelente para predecir mínimos/máximos de retroceso.
"""
def find_fvg(self, df: pd.DataFrame) -> List[FVG]:
fvgs = []
for i in range(2, len(df)):
# Bullish FVG: Gap entre high de vela 1 y low de vela 3
if df['low'].iloc[i] > df['high'].iloc[i-2]:
fvgs.append(FVG(
type='bullish',
top=df['low'].iloc[i],
bottom=df['high'].iloc[i-2],
filled=False
))
# Bearish FVG
if df['high'].iloc[i] < df['low'].iloc[i-2]:
fvgs.append(FVG(
type='bearish',
top=df['low'].iloc[i-2],
bottom=df['high'].iloc[i],
filled=False
))
return fvgs
def predict_fill_probability(self, fvg: FVG,
time_since_creation: int) -> float:
"""
FVGs se llenan ~70% del tiempo en las primeras 20 velas.
"""
base_probability = 0.70
time_decay = max(0, 1 - time_since_creation / 50)
return base_probability * time_decay
```
**Utilidad para predicción de rangos:**
- FVGs sin llenar son targets probables
- Ayuda a predecir retrocesos antes de continuación
---
### 4.4 Estrategia: Liquidity Sweep
**Concepto:** El precio busca liquidez antes de moverse en dirección opuesta.
```python
class LiquiditySweepStrategy:
"""
Liquidity Sweeps - Smart Money Concepts
Detecta barridas de liquidez que preceden reversiones.
Crítico para predecir máximos/mínimos locales.
"""
def detect_liquidity_zones(self, df: pd.DataFrame) -> dict:
"""Identifica zonas de liquidez (stops acumulados)."""
# Liquidez por encima de equal highs
equal_highs = self.find_equal_highs(df)
# Liquidez por debajo de equal lows
equal_lows = self.find_equal_lows(df)
# Liquidez en swing points obvios
swing_highs = self.find_swing_highs(df)
swing_lows = self.find_swing_lows(df)
return {
'buy_side_liquidity': equal_highs + swing_highs,
'sell_side_liquidity': equal_lows + swing_lows
}
def predict_sweep_target(self, current_price: float,
liquidity_zones: dict) -> dict:
"""
Predice el objetivo de la siguiente barrida de liquidez.
Si el precio se acerca a liquidez, es probable que:
1. Barra la liquidez (crea máximo/mínimo temporal)
2. Revierta en dirección opuesta
"""
nearest_buy_liq = self.find_nearest_above(
liquidity_zones['buy_side_liquidity'], current_price
)
nearest_sell_liq = self.find_nearest_below(
liquidity_zones['sell_side_liquidity'], current_price
)
return {
'probable_high': nearest_buy_liq * 1.001, # Ligeramente por encima
'probable_low': nearest_sell_liq * 0.999, # Ligeramente por debajo
'sweep_probability': self.calculate_sweep_prob(...)
}
```
**Utilidad para predicción de rangos:**
- Predice exactamente dónde se formarán máximos/mínimos
- Las barridas de liquidez son predecibles
---
### 4.5 Estrategia: Market Structure Shift (MSS)
**Concepto:** Detectar cambios de estructura para anticipar reversiones.
```python
class MarketStructureStrategy:
"""
Market Structure Shift - ICT/SMC
Detecta cambios en la estructura del mercado que indican
reversiones de tendencia.
"""
def analyze_structure(self, df: pd.DataFrame) -> MarketStructure:
swing_points = self.identify_swing_points(df)
# Determinar estructura actual
if self.is_higher_highs_higher_lows(swing_points):
structure = 'bullish'
elif self.is_lower_highs_lower_lows(swing_points):
structure = 'bearish'
else:
structure = 'ranging'
return MarketStructure(
current=structure,
last_high=swing_points[-1] if swing_points[-1].type == 'high' else None,
last_low=swing_points[-1] if swing_points[-1].type == 'low' else None
)
def detect_mss(self, df: pd.DataFrame, structure: MarketStructure) -> Optional[MSS]:
"""
Market Structure Shift ocurre cuando:
- En tendencia alcista: precio rompe último low significativo
- En tendencia bajista: precio rompe último high significativo
"""
if structure.current == 'bullish':
if df['close'].iloc[-1] < structure.last_low.price:
return MSS(
type='bearish_shift',
confirmation_level=structure.last_low.price,
target=self.calculate_target(df, 'bearish')
)
# ... inverso para bearish
def predict_range_after_mss(self, mss: MSS) -> dict:
"""Después de MSS, el precio típicamente hace un retroceso."""
return {
'retracement_high': mss.confirmation_level, # No debería superar
'target_low': mss.target,
'probability': 0.75 # MSS tienen alta probabilidad de seguimiento
}
```
---
## 5. Arquitectura del Modelo Ensemble
### 5.1 Modelo de Predicción de Rangos Completo
```python
class RangePredictionEnsemble:
"""
Ensemble que combina múltiples estrategias y modelos ML
para predecir máximos y mínimos con alta precisión.
"""
def __init__(self):
# Modelos ML
self.range_predictor = XGBoostRangePredictor()
self.volatility_predictor = LSTMVolatilityPredictor()
self.direction_classifier = RandomForestDirectionClassifier()
# Estrategias
self.amd_strategy = AMDPhaseStrategy()
self.vcp_strategy = VCPStrategy()
self.order_block_strategy = OrderBlockStrategy()
self.fvg_strategy = FairValueGapStrategy()
self.liquidity_strategy = LiquiditySweepStrategy()
self.mss_strategy = MarketStructureStrategy()
def predict(self, df: pd.DataFrame, horizon: str = '60m') -> RangePrediction:
"""
Genera predicción de rango combinando todos los modelos.
Returns:
RangePrediction con:
- predicted_high: máximo esperado
- predicted_low: mínimo esperado
- confidence: confianza de la predicción
- best_entry: mejor punto de entrada
- optimal_sl: stop loss óptimo
- optimal_tp: take profit óptimo
- rr_ratio: ratio riesgo/recompensa
"""
# 1. Features base
features = self.calculate_features(df)
# 2. Predicciones ML
ml_range = self.range_predictor.predict(features)
ml_volatility = self.volatility_predictor.predict(features)
ml_direction = self.direction_classifier.predict(features)
# 3. Análisis de estrategias
amd_phase = self.amd_strategy.detect_phase(df)
vcp_signal = self.vcp_strategy.detect_vcp(df)
order_blocks = self.order_block_strategy.find_order_blocks(df)
fvgs = self.fvg_strategy.find_fvg(df)
liquidity = self.liquidity_strategy.detect_liquidity_zones(df)
structure = self.mss_strategy.analyze_structure(df)
# 4. Combinar predicciones
combined = self.combine_predictions(
ml_predictions={
'range': ml_range,
'volatility': ml_volatility,
'direction': ml_direction
},
strategy_signals={
'amd': amd_phase,
'vcp': vcp_signal,
'order_blocks': order_blocks,
'fvgs': fvgs,
'liquidity': liquidity,
'structure': structure
}
)
# 5. Calcular entrada óptima
entry = self.calculate_optimal_entry(combined, df['close'].iloc[-1])
return RangePrediction(
predicted_high=combined['high'],
predicted_low=combined['low'],
confidence=combined['confidence'],
best_entry=entry['price'],
entry_type=entry['type'], # 'long' or 'short'
optimal_sl=entry['sl'],
optimal_tp=entry['tp'],
rr_ratio=entry['rr'],
contributing_factors=combined['factors']
)
def combine_predictions(self, ml_predictions: dict,
strategy_signals: dict) -> dict:
"""
Pondera predicciones según confianza y confluencia.
Pesos base:
- ML Range Predictor: 30%
- AMD Phase: 20%
- Liquidity Zones: 15%
- Order Blocks: 15%
- Market Structure: 10%
- FVG/VCP: 10%
Los pesos se ajustan según contexto.
"""
weights = {
'ml_range': 0.30,
'amd': 0.20,
'liquidity': 0.15,
'order_blocks': 0.15,
'structure': 0.10,
'fvg_vcp': 0.10
}
# Ajustar pesos según contexto
if strategy_signals['amd'].phase == 'accumulation':
weights['amd'] = 0.30 # AMD más confiable en fases claras
weights['ml_range'] = 0.20
if len(strategy_signals['order_blocks']) > 0:
# Order blocks cercanos aumentan confianza
weights['order_blocks'] = 0.20
# Calcular predicción ponderada
...
return {
'high': weighted_high,
'low': weighted_low,
'confidence': self.calculate_confluence_confidence(strategy_signals),
'factors': contributing_factors
}
def calculate_optimal_entry(self, prediction: dict,
current_price: float) -> dict:
"""
Calcula la entrada óptima para lograr R:R objetivo.
Prioriza R:R 3:1, fallback a 2:1.
"""
high = prediction['high']
low = prediction['low']
# Para LONG
long_sl = low * 0.998 # SL ligeramente por debajo del mínimo predicho
long_risk = current_price - long_sl
long_tp_3_1 = current_price + (long_risk * 3)
long_tp_2_1 = current_price + (long_risk * 2)
# Verificar si TP es alcanzable según predicción
long_3_1_achievable = long_tp_3_1 <= high
long_2_1_achievable = long_tp_2_1 <= high
# Para SHORT (inverso)
short_sl = high * 1.002
short_risk = short_sl - current_price
short_tp_3_1 = current_price - (short_risk * 3)
short_tp_2_1 = current_price - (short_risk * 2)
short_3_1_achievable = short_tp_3_1 >= low
short_2_1_achievable = short_tp_2_1 >= low
# Seleccionar mejor entrada
if long_3_1_achievable and prediction['direction'] == 'bullish':
return {
'type': 'long',
'price': current_price,
'sl': long_sl,
'tp': long_tp_3_1,
'rr': 3.0
}
elif short_3_1_achievable and prediction['direction'] == 'bearish':
return {
'type': 'short',
'price': current_price,
'sl': short_sl,
'tp': short_tp_3_1,
'rr': 3.0
}
# Fallback a 2:1
...
```
---
## 6. Métricas de Éxito
### 6.1 Objetivos por R:R
| R:R | Win Rate Objetivo | Profit Factor | Expectativa |
|-----|-------------------|---------------|-------------|
| 3:1 | ≥80% | ≥4.0 | +1.4R por trade |
| 2:1 | ≥90% | ≥6.0 | +0.8R por trade |
### 6.2 Fórmulas de Validación
```python
# Expectativa = (Win% × Avg Win) - (Loss% × Avg Loss)
# Para 3:1 con 80% win rate:
expectativa_3_1 = (0.80 * 3) - (0.20 * 1) = 2.4 - 0.2 = 2.2R
# Para 2:1 con 90% win rate:
expectativa_2_1 = (0.90 * 2) - (0.10 * 1) = 1.8 - 0.1 = 1.7R
```
### 6.3 Métricas de Predicción de Rangos
| Métrica | Objetivo | Descripción |
|---------|----------|-------------|
| `high_accuracy` | ≥85% | % de veces que el precio alcanza el high predicho |
| `low_accuracy` | ≥85% | % de veces que el precio alcanza el low predicho |
| `range_mae` | ≤0.5% | Error absoluto medio del rango predicho |
| `direction_accuracy` | ≥75% | % de veces que la dirección es correcta |
---
## 7. Pipeline de Training
### 7.1 Generación de Labels
```python
def generate_range_labels(df: pd.DataFrame,
horizons: List[int] = [3, 12]) -> pd.DataFrame:
"""
Genera labels para entrenamiento de predicción de rangos.
Args:
df: DataFrame con OHLCV
horizons: [3, 12] = [15min, 60min] en velas de 5min
Returns:
DataFrame con labels:
- delta_high_{horizon}: (max_high - current_close) / current_close
- delta_low_{horizon}: (min_low - current_close) / current_close
"""
labels = pd.DataFrame(index=df.index)
for horizon in horizons:
# Máximo en las próximas N velas
future_high = df['high'].rolling(horizon).max().shift(-horizon)
labels[f'delta_high_{horizon}'] = (future_high - df['close']) / df['close']
# Mínimo en las próximas N velas
future_low = df['low'].rolling(horizon).min().shift(-horizon)
labels[f'delta_low_{horizon}'] = (future_low - df['close']) / df['close']
# Label de dirección (cuál se alcanza primero)
labels[f'direction_{horizon}'] = np.where(
abs(labels[f'delta_high_{horizon}']) > abs(labels[f'delta_low_{horizon}']),
1, # Más probable alcista
-1 # Más probable bajista
)
return labels
```
### 7.2 Validación Walk-Forward
```python
def walk_forward_validation(model, df: pd.DataFrame,
train_size: int = 5000,
test_size: int = 1000,
step: int = 500) -> List[ValidationResult]:
"""
Validación walk-forward para evitar overfitting.
Simula condiciones reales de trading donde el modelo
solo ve datos pasados.
"""
results = []
for i in range(0, len(df) - train_size - test_size, step):
# Train set
train_df = df.iloc[i:i+train_size]
# Test set (datos "futuros")
test_df = df.iloc[i+train_size:i+train_size+test_size]
# Entrenar modelo
model.fit(train_df)
# Evaluar en test
predictions = model.predict(test_df)
metrics = evaluate_range_predictions(predictions, test_df)
results.append(ValidationResult(
train_period=(i, i+train_size),
test_period=(i+train_size, i+train_size+test_size),
metrics=metrics
))
return results
```
---
## 8. Próximos Pasos
### Fase 1: Preparación de Datos
1. [ ] Recolectar datos históricos (mínimo 2 años)
2. [ ] Calcular todas las features definidas
3. [ ] Generar labels de rangos
4. [ ] Split train/validation/test
### Fase 2: Desarrollo de Modelos
1. [ ] Implementar RangePredictor base (XGBoost)
2. [ ] Implementar estrategias complementarias
3. [ ] Crear ensemble combiner
4. [ ] Optimizar pesos del ensemble
### Fase 3: Validación
1. [ ] Walk-forward validation
2. [ ] Backtesting con R:R targets
3. [ ] Paper trading
4. [ ] Ajuste fino
### Fase 4: Integración
1. [ ] Integrar con ML Engine
2. [ ] Exponer endpoints de predicción
3. [ ] Conectar con LLM Agent
4. [ ] Dashboard de métricas
---
## 9. Referencias
- Wyckoff Method (AMD Phases)
- ICT/SMC Concepts (Order Blocks, FVG, Liquidity)
- Mark Minervini (VCP Pattern)
- Elder Triple Screen
- Documentación interna: `ML_INVENTORY.yml`
---
**Autor:** NEXUS-TRADING-STRATEGIST
**Revisado por:** Product Owner
**Estado:** Análisis Inicial