# RF-ML-001: Predicciones de Rangos de Precio

**Versión:** 1.0.0
**Fecha:** 2025-12-05
**Épica:** OQI-006 - Señales ML y Predicciones
**Prioridad:** P0
**Story Points:** 10

---

## Descripción

El sistema debe proporcionar predicciones de rangos de precio futuros (máximo y mínimo esperados) para diferentes horizontes temporales utilizando modelos de Machine Learning basados en XGBoost. Las predicciones deben incluir niveles de confianza y actualizarse en tiempo real.

---

## Requisitos Funcionales

### RF-ML-001.1: Modelo de Predicción XGBoost

El sistema debe:
- Utilizar XGBoost para predecir `max_ratio` y `min_ratio`
- Entrenar dos modelos independientes (uno para máximos, otro para mínimos)
- Configuración del modelo:
  - `n_estimators`: 100 árboles
  - `max_depth`: 6 niveles
  - `learning_rate`: 0.1
  - `subsample`: 0.8
  - `colsample_bytree`: 0.8

### RF-ML-001.2: Horizontes de Predicción

El sistema debe soportar 4 horizontes temporales:

| Horizonte | Candles (5min) | Tiempo Total | Uso Típico |
|-----------|----------------|--------------|------------|
| **Scalping** | 6 | 30 minutos | Trading rápido intraday |
| **Intraday** | 18 | 90 minutos | Day trading activo |
| **Swing** | 36 | 3 horas | Posiciones de días |
| **Position** | 72 | 6 horas | Posiciones largas |

### RF-ML-001.3: Cálculo de Predicciones

El sistema debe calcular:

**Precio Máximo Esperado:**
```
predicted_high = current_price × (1 + max_ratio)
```

**Precio Mínimo Esperado:**
```
predicted_low = current_price × (1 - min_ratio)
```

**Nivel de Confianza:**
```
confidence = f(MAE, RMSE, horizon)
- Scalping: ~0.69 (mayor confianza)
- Intraday: ~0.59
- Swing: ~0.45
- Position: ~0.45 (menor confianza)
```

### RF-ML-001.4: Features del Modelo

El sistema debe calcular 30+ features técnicas agrupadas en:

**Volatilidad (8 features):**
- `volatility_5`, `volatility_10`, `volatility_20`, `volatility_50`
- `atr_5`, `atr_10`, `atr_20`, `atr_50`

**Momentum (6 features):**
- `momentum_5`, `momentum_10`, `momentum_20`
- `roc_5`, `roc_10`, `roc_20`

**Medias Móviles (12 features):**
- SMA: `sma_5`, `sma_10`, `sma_20`, `sma_50`
- EMA: `ema_5`, `ema_10`, `ema_20`, `ema_50`
- Ratios: `sma_ratio_5`, `sma_ratio_10`, `sma_ratio_20`, `sma_ratio_50`

**Indicadores Técnicos (4 features):**
- `rsi_14` - Relative Strength Index
- `macd`, `macd_signal`, `macd_histogram`
- `bb_position` - Posición en Bollinger Bands

**Volumen (1 feature):**
- `volume_ratio` - Ratio vs SMA 20 períodos

**High/Low (6+ features):**
- `hl_range_pct` - Rango high-low como porcentaje
- `high_distance`, `low_distance`
- `hist_max_ratio_*`, `hist_min_ratio_*`

### RF-ML-001.5: Métricas de Precisión

El sistema debe rastrear métricas de entrenamiento:

| Métrica | Descripción | Valor Aceptable |
|---------|-------------|-----------------|
| `high_mae` | Mean Absolute Error para máximos | < 2% |
| `high_rmse` | Root Mean Squared Error para máximos | < 2.5% |
| `low_mae` | Mean Absolute Error para mínimos | < 2% |
| `low_rmse` | Root Mean Squared Error para mínimos | < 2.5% |

### RF-ML-001.6: Actualización en Tiempo Real

El sistema debe:
- Recalcular predicciones cada vez que se cierra una nueva vela de 5 minutos
- Mantener WebSocket activo en `/ws/{symbol}` para streaming de predicciones
- Enviar actualizaciones automáticas a clientes conectados
- Incluir timestamp de la predicción en formato ISO 8601

---

## Datos de Entrada

| Campo | Tipo | Descripción | Requerido |
|-------|------|-------------|-----------|
| symbol | string | Par de trading (ej: BTCUSDT) | Sí |
| horizon | enum | Horizonte: scalping, intraday, swing, position, all | No (default: all) |

---

## Datos de Salida

```typescript
interface Prediction {
  symbol: string;
  timestamp: string;              // ISO 8601
  current_price: number;
  predictions: {
    [horizon: string]: {
      high: number;               // Precio máximo esperado
      low: number;                // Precio mínimo esperado
      high_ratio: number;         // Ratio de subida (1 + %)
      low_ratio: number;          // Ratio de bajada (1 - %)
      confidence: number;         // 0-1, nivel de confianza
      minutes: number;            // Duración del horizonte
    }
  };
  model_version: string;
  is_trained: boolean;
}
```

**Ejemplo:**
```json
{
  "symbol": "BTCUSDT",
  "timestamp": "2025-12-05T18:05:08.889327Z",
  "current_price": 89388.99,
  "predictions": {
    "scalping": {
      "high": 89663.86,
      "low": 88930.53,
      "high_ratio": 1.0031,
      "low_ratio": 0.9949,
      "confidence": 0.69,
      "minutes": 30
    },
    "intraday": {
      "high": 90213.60,
      "low": 88013.61,
      "high_ratio": 1.0093,
      "low_ratio": 0.9848,
      "confidence": 0.59,
      "minutes": 90
    }
  },
  "model_version": "1.0.0",
  "is_trained": true
}
```

---

## Reglas de Negocio

1. **Símbolos Soportados:** Solo BTCUSDT y ETHUSDT inicialmente
2. **Modelo Pre-entrenado:** Debe existir modelo entrenado antes de hacer predicciones
3. **Datos Históricos:** Requiere mínimo 500 velas de 5min para predicción confiable
4. **Confianza Decreciente:** La confianza disminuye con horizontes más largos
5. **Caché:** Predicciones se cachean por 5 minutos (1 vela completa)
6. **Rate Limiting:** Máximo 10 requests/minuto por usuario para endpoint REST

---

## Criterios de Aceptación

```gherkin
Escenario: Obtener predicción para BTCUSDT
  DADO que el modelo está entrenado para BTCUSDT
  Y el usuario está autenticado
  CUANDO hace GET /api/predict/BTCUSDT?horizon=all
  ENTONCES recibe predicciones para los 4 horizontes
  Y cada predicción incluye high, low, confidence
  Y el precio actual coincide con el último cierre
  Y el timestamp es reciente (< 5 min)

Escenario: Predicción de horizonte único
  DADO que el modelo está entrenado
  CUANDO hace GET /api/predict/BTCUSDT?horizon=scalping
  ENTONCES recibe solo predicción de scalping (30 min)
  Y el nivel de confianza es >= 0.65

Escenario: Modelo no entrenado
  DADO que NO existe modelo entrenado para ETHUSDT
  CUANDO hace GET /api/predict/ETHUSDT
  ENTONCES recibe error 503 Service Unavailable
  Y el mensaje indica "Model not trained for ETHUSDT"
  Y is_trained = false

Escenario: Actualización en tiempo real vía WebSocket
  DADO que el usuario está conectado a /ws/BTCUSDT
  CUANDO se cierra una nueva vela de 5 minutos
  ENTONCES recibe predicción actualizada automáticamente
  Y el timestamp de la predicción es el actual
```

---

## Dependencias

### Técnicas:
- **XGBoost 2.0+:** Motor de predicción
- **Binance API:** Datos de mercado (velas de 5min)
- **Pandas/NumPy:** Procesamiento de features
- **FastAPI:** Endpoints REST y WebSocket
- **Redis:** Caché de predicciones (opcional)

### Funcionales:
- **RF-ML-003:** Indicadores técnicos para features
- **RF-ML-004:** Pipeline de entrenamiento previo

---

## Notas Técnicas

### Arquitectura del Predictor

```python
# apps/ml-services/src/models/predictor.py

class MaxMinPricePredictor:
    """
    Predictor de rangos de precio máximo/mínimo

    Utiliza dos modelos XGBoost independientes:
    - xgb_high: Predice max_ratio
    - xgb_low: Predice min_ratio
    """

    def predict(self, symbol: str, horizon: str) -> dict:
        # 1. Fetch últimas 500 velas de 5min
        # 2. Calcular 30+ features técnicas
        # 3. Predecir max_ratio y min_ratio
        # 4. Convertir ratios a precios absolutos
        # 5. Calcular nivel de confianza
        # 6. Retornar predicción estructurada
```

### Optimizaciones:
- Feature engineering vectorizado con NumPy
- Caché de datos de mercado (TTL: 1 min)
- Modelos pre-cargados en memoria
- Batch processing para múltiples horizontes

### Limitaciones:
- Precisión disminuye en horizontes largos (>3h)
- Requiere re-entrenamiento semanal para mantener accuracy
- No funciona bien en mercados extremadamente volátiles (eventos black swan)

---

## Referencias

- [XGBoost Documentation](https://xgboost.readthedocs.io/)
- [Binance API - Klines](https://binance-docs.github.io/apidocs/spot/en/#kline-candlestick-data)
- [Technical Indicators Library - TA-Lib](https://ta-lib.org/)
- [FastAPI WebSockets](https://fastapi.tiangolo.com/advanced/websockets/)

---

**Creado por:** Requirements-Analyst
**Fecha:** 2025-12-05
**Última actualización:** 2025-12-05
