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>
768 lines
26 KiB
Markdown
768 lines
26 KiB
Markdown
---
|
||
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
|