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>
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_highajustado 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_lowajustado 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 | Sí |
| 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
- Generación Continua: Las señales se generan cada 5 minutos (cierre de vela)
- Expiración: Una señal expira después de su horizonte temporal
- No Duplicados: No generar señal BUY si ya existe una activa del mismo horizonte
- Señal Contradictoria: Una SELL cancela una BUY anterior del mismo horizonte
- Límite Diario: Máximo 50 señales HIGH por símbolo por día
- 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