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>
26 KiB
| id | title | type | project | version | updated_date |
|---|---|---|---|---|---|
| ESTRATEGIA-PREDICCION-RANGOS | Estrategia de Predicción de Rangos para Entradas Óptimas | Documentation | trading-platform | 1.0.0 | 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.
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.
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.
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.
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.
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
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
# 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
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
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
- Recolectar datos históricos (mínimo 2 años)
- Calcular todas las features definidas
- Generar labels de rangos
- Split train/validation/test
Fase 2: Desarrollo de Modelos
- Implementar RangePredictor base (XGBoost)
- Implementar estrategias complementarias
- Crear ensemble combiner
- Optimizar pesos del ensemble
Fase 3: Validación
- Walk-forward validation
- Backtesting con R:R targets
- Paper trading
- Ajuste fino
Fase 4: Integración
- Integrar con ML Engine
- Exponer endpoints de predicción
- Conectar con LLM Agent
- 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