trading-platform/docs/02-definicion-modulos/OQI-006-ml-signals/requerimientos/RF-ML-002-senales.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

10 KiB

id title type status priority epic project version created_date updated_date
RF-ML-002 Generacion de Senales de Trading Requirement Done Alta OQI-006 trading-platform 1.0.0 2025-12-05 2026-01-04

RF-ML-002: Generación de Señales de Trading

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 generar señales de trading (BUY/SELL/HOLD) basadas en las predicciones del modelo ML, combinando análisis de rango esperado, clasificación de TP/SL (Take Profit / Stop Loss) y gestión de riesgo. Las señales deben incluir niveles recomendados de entrada, objetivos y stops.


Requisitos Funcionales

RF-ML-002.1: Tipos de Señales

El sistema debe generar tres tipos de señales:

Tipo Condición Acción Recomendada
BUY Predicción alcista con alta confianza Abrir posición long
SELL Predicción bajista con alta confianza Abrir posición short o cerrar long
HOLD Señal neutral o baja confianza Mantener posición actual, no operar

RF-ML-002.2: Clasificador TP/SL

El sistema debe incluir un clasificador que determine:

Take Profit (TP):

  • Nivel de precio objetivo para cerrar con ganancia
  • Basado en predicted_high ajustado por confianza
  • Múltiples niveles: TP1 (conservador), TP2 (moderado), TP3 (agresivo)

Stop Loss (SL):

  • Nivel de precio máximo de pérdida aceptable
  • Basado en predicted_low ajustado por confianza
  • Ratio riesgo/recompensa mínimo: 1:2

RF-ML-002.3: Cálculo de Señales

El sistema debe aplicar la siguiente lógica:

Señal BUY:

Condiciones:
- predicted_high > current_price * 1.005 (mín 0.5% de subida esperada)
- confidence >= 0.60
- rsi_14 < 70 (no sobrecompra)
- volume_ratio > 0.8 (volumen suficiente)

Niveles:
- entry_price = current_price
- tp1 = current_price + (predicted_high - current_price) * 0.5
- tp2 = current_price + (predicted_high - current_price) * 0.75
- tp3 = predicted_high
- stop_loss = current_price - (current_price - predicted_low) * 0.5

Señal SELL:

Condiciones:
- predicted_low < current_price * 0.995 (mín 0.5% de bajada esperada)
- confidence >= 0.60
- rsi_14 > 30 (no sobreventa)
- volume_ratio > 0.8

Niveles:
- entry_price = current_price
- tp1 = current_price - (current_price - predicted_low) * 0.5
- tp2 = current_price - (current_price - predicted_low) * 0.75
- tp3 = predicted_low
- stop_loss = current_price + (predicted_high - current_price) * 0.5

Señal HOLD:

Condiciones:
- No cumple criterios de BUY ni SELL
- O confidence < 0.60
- O rango esperado muy estrecho (< 0.5%)

RF-ML-002.4: Gestión de Riesgo

El sistema debe calcular:

Risk/Reward Ratio:

rr_ratio = (tp_price - entry_price) / (entry_price - stop_loss)
  • Mínimo aceptable: 1:2
  • Óptimo: 1:3 o superior

Position Size Recomendado:

position_size = account_balance * risk_per_trade / (entry_price - stop_loss)

Donde:
- risk_per_trade: 1% - 2% del balance (configurable)

RF-ML-002.5: Priorización de Señales

El sistema debe asignar prioridad a las señales:

Prioridad Score Criterios
HIGH >= 8.0 confidence > 0.70, RR > 1:3, volumen alto
MEDIUM 6.0 - 7.9 confidence > 0.60, RR > 1:2, volumen normal
LOW 4.0 - 5.9 confidence > 0.50, RR > 1:1.5

Fórmula de Score:

score = (confidence * 10) * 0.4
      + (rr_ratio / 3) * 10 * 0.4
      + (volume_ratio) * 10 * 0.2

RF-ML-002.6: Histórico de Señales

El sistema debe:

  • Guardar todas las señales generadas con timestamp
  • Rastrear el outcome real vs predicción
  • Calcular accuracy histórico de señales
  • Permitir filtrado por símbolo, horizonte, tipo de señal

Datos de Entrada

Campo Tipo Descripción Requerido
symbol string Par de trading
horizon enum scalping, intraday, swing, position No (default: scalping)
risk_per_trade float % de balance a arriesgar No (default: 0.01)

Datos de Salida

interface TradingSignal {
  signal_id: string;              // UUID único
  symbol: string;
  timestamp: string;              // ISO 8601
  horizon: string;

  // Señal principal
  action: 'BUY' | 'SELL' | 'HOLD';
  priority: 'HIGH' | 'MEDIUM' | 'LOW';
  score: number;                  // 0-10

  // Precios
  current_price: number;
  entry_price: number;

  // Niveles objetivo
  take_profit: {
    tp1: number;
    tp2: number;
    tp3: number;
  };
  stop_loss: number;

  // Métricas
  risk_reward_ratio: number;
  expected_gain_pct: number;
  max_risk_pct: number;
  confidence: number;             // 0-1

  // Posición recomendada
  recommended_position_size?: number;

  // Indicadores técnicos
  rsi: number;
  volume_ratio: number;

  // Razones
  reasons: string[];              // Por qué se generó la señal
}

Ejemplo:

{
  "signal_id": "550e8400-e29b-41d4-a716-446655440000",
  "symbol": "BTCUSDT",
  "timestamp": "2025-12-05T18:30:00.000Z",
  "horizon": "scalping",
  "action": "BUY",
  "priority": "HIGH",
  "score": 8.5,
  "current_price": 89400.00,
  "entry_price": 89400.00,
  "take_profit": {
    "tp1": 89650.00,
    "tp2": 89775.00,
    "tp3": 89900.00
  },
  "stop_loss": 89150.00,
  "risk_reward_ratio": 2.0,
  "expected_gain_pct": 0.56,
  "max_risk_pct": 0.28,
  "confidence": 0.72,
  "recommended_position_size": 0.05,
  "rsi": 55.3,
  "volume_ratio": 1.2,
  "reasons": [
    "Strong upward prediction (0.72 confidence)",
    "Healthy RSI (55.3, not overbought)",
    "Above average volume (1.2x)",
    "Favorable risk/reward (1:2)"
  ]
}

Reglas de Negocio

  1. Generación Continua: Las señales se generan cada 5 minutos (cierre de vela)
  2. Expiración: Una señal expira después de su horizonte temporal
  3. No Duplicados: No generar señal BUY si ya existe una activa del mismo horizonte
  4. Señal Contradictoria: Una SELL cancela una BUY anterior del mismo horizonte
  5. Límite Diario: Máximo 50 señales HIGH por símbolo por día
  6. Validación de Precio: El entry_price debe estar dentro del 0.1% del current_price

Criterios de Aceptación

Escenario: Generar señal BUY con alta confianza
  DADO que BTCUSDT tiene predicción alcista
  Y confidence = 0.75
  Y predicted_high = current_price * 1.008
  Y RSI = 55
  CUANDO el sistema calcula la señal
  ENTONCES action = "BUY"
  Y priority = "HIGH"
  Y se generan 3 niveles de TP
  Y risk_reward_ratio >= 2.0

Escenario: Generar señal HOLD por baja confianza
  DADO que ETHUSDT tiene predicción neutral
  Y confidence = 0.45
  CUANDO el sistema calcula la señal
  ENTONCES action = "HOLD"
  Y priority = "LOW"
  Y reasons incluye "Low confidence"

Escenario: Señal SELL en mercado bajista
  DADO que BTCUSDT tiene predicción bajista
  Y confidence = 0.68
  Y predicted_low = current_price * 0.992
  CUANDO el sistema calcula la señal
  ENTONCES action = "SELL"
  Y priority = "MEDIUM" o "HIGH"
  Y stop_loss > entry_price

Escenario: Obtener señales vía API
  DADO que el usuario está autenticado
  CUANDO hace GET /api/signals/BTCUSDT?horizon=scalping
  ENTONCES recibe la señal más reciente
  Y la señal tiene menos de 5 minutos
  Y incluye todos los niveles de TP/SL

Dependencias

Técnicas:

  • RF-ML-001: Predicciones de rangos de precio
  • RF-ML-003: Indicadores técnicos (RSI, volumen)
  • PostgreSQL: Almacenamiento de histórico de señales
  • Redis: Caché de señales activas

Funcionales:

  • Sistema de notificaciones para alertas (RF-ML-005)
  • Integración con charts para visualización (RF-TRD-001)

Notas Técnicas

Arquitectura del Generador de Señales

# apps/ml-services/src/models/signal_generator.py

class SignalGenerator:
    """
    Genera señales de trading basadas en predicciones ML
    """

    def generate_signal(
        self,
        symbol: str,
        horizon: str,
        risk_per_trade: float = 0.01
    ) -> TradingSignal:
        # 1. Obtener predicción del ML
        prediction = predictor.predict(symbol, horizon)

        # 2. Obtener indicadores técnicos actuales
        indicators = get_current_indicators(symbol)

        # 3. Determinar acción (BUY/SELL/HOLD)
        action = classify_action(prediction, indicators)

        # 4. Calcular niveles de TP/SL
        levels = calculate_levels(action, prediction)

        # 5. Calcular métricas de riesgo
        metrics = calculate_risk_metrics(levels, risk_per_trade)

        # 6. Asignar prioridad y score
        priority, score = calculate_priority(prediction, metrics, indicators)

        # 7. Construir razones
        reasons = build_reasons(action, prediction, indicators, metrics)

        return TradingSignal(...)

Base de Datos - Tabla ml_signals

CREATE TABLE ml_signals (
  signal_id UUID PRIMARY KEY,
  symbol VARCHAR(20) NOT NULL,
  horizon VARCHAR(20) NOT NULL,
  action VARCHAR(10) NOT NULL,
  priority VARCHAR(10) NOT NULL,
  score DECIMAL(4,2),

  current_price DECIMAL(20,8),
  entry_price DECIMAL(20,8),
  tp1 DECIMAL(20,8),
  tp2 DECIMAL(20,8),
  tp3 DECIMAL(20,8),
  stop_loss DECIMAL(20,8),

  confidence DECIMAL(4,3),
  risk_reward_ratio DECIMAL(5,2),

  created_at TIMESTAMP DEFAULT NOW(),
  expires_at TIMESTAMP,

  -- Tracking
  actual_outcome VARCHAR(20),  -- hit_tp1, hit_tp2, hit_sl, expired
  closed_at TIMESTAMP,
  actual_gain_pct DECIMAL(6,3),

  INDEX idx_symbol_horizon (symbol, horizon),
  INDEX idx_created_at (created_at),
  INDEX idx_priority (priority)
);

Performance:

  • Generación de señal: < 100ms
  • Consulta de señales activas: < 50ms (con índices)
  • Caché en Redis por 5 minutos

Referencias


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