--- id: "US-TRD-012" title: "Configurar Take Profit y Stop Loss" type: "User Story" status: "Done" priority: "Alta" epic: "OQI-003" story_points: 5 created_date: "2025-12-05" updated_date: "2026-01-04" --- # US-TRD-012: Configurar Take Profit y Stop Loss ## Metadata | Campo | Valor | |-------|-------| | **ID** | US-TRD-012 | | **Épica** | OQI-003 - Trading y Charts | | **Módulo** | trading | | **Prioridad** | P1 | | **Story Points** | 3 | | **Sprint** | Sprint 5 | | **Estado** | Pendiente | | **Asignado a** | Por asignar | --- ## Historia de Usuario **Como** trader practicante, **quiero** configurar niveles de Take Profit y Stop Loss en mis posiciones, **para** automatizar la gestión de riesgo y asegurar ganancias sin monitoreo constante. ## Descripción Detallada El usuario debe poder establecer niveles de Take Profit (TP) y Stop Loss (SL) en posiciones abiertas, tanto al crear una orden como después de que la posición esté abierta. El sistema debe monitorear estos niveles y ejecutar automáticamente el cierre cuando el precio los alcance. ## Mockups/Wireframes ``` ┌─────────────────────────────────────────────────────────────────┐ │ CONFIGURE TP/SL - BTCUSDT LONG Position │ ├─────────────────────────────────────────────────────────────────┤ │ Position Details: │ │ Size: 0.1 BTC | Entry: $95,000 | Current: $97,234.50 │ │ Current P&L: +$223.45 (+2.35%) │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ TAKE PROFIT [✓ Enable]│ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ Price: │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ │ 100,000.00 │ │ │ │ │ └─────────────────────────────────────┘ │ │ │ │ Distance: +2.84% (+$2,765.50) │ │ │ │ [Set 1%] [Set 2%] [Set 5%] [Set 10%] │ │ │ │ │ │ │ │ Est. Profit if triggered: +$500.00 (+5.26%) │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ STOP LOSS [✓ Enable]│ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ Price: │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ │ 93,000.00 │ │ │ │ │ └─────────────────────────────────────┘ │ │ │ │ Distance: -4.35% (-$4,234.50) │ │ │ │ [Set 1%] [Set 2%] [Set 5%] [Set 10%] │ │ │ │ │ │ │ │ Est. Loss if triggered: -$200.00 (-2.11%) │ │ │ │ ⚠ Warning: SL is below entry price │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ Risk/Reward Ratio: 2.50 (Good) │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ Chart Preview: │ │ │ │ $100,000 ─────────────────── TP (Green line) │ │ │ │ $97,234 ████ Current Price │ │ │ │ $95,000 ──── Entry (Blue line) │ │ │ │ $93,000 ─────────────────── SL (Red line) │ │ │ │ │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ [Cancel] [Save TP/SL] │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## Criterios de Aceptación **Escenario 1: Configurar TP y SL en posición existente** ```gherkin DADO que el usuario tiene posición long BTCUSDT a $95,000 Y el precio actual es $97,234.50 CUANDO abre el diálogo de TP/SL Y habilita Take Profit en $100,000 Y habilita Stop Loss en $93,000 Y hace click en "Save" ENTONCES se guardan los niveles Y aparecen en el panel de posiciones Y se muestran líneas horizontales en el chart Y el sistema comienza a monitorear estos niveles ``` **Escenario 2: Activación automática de Take Profit** ```gherkin DADO que la posición tiene TP en $100,000 CUANDO el precio sube y alcanza $100,000 ENTONCES se ejecuta automáticamente orden market sell Y la posición se cierra Y el P&L realizado es +$500.00 Y el close_reason es "take_profit" Y se envía notificación "Take Profit triggered at $100,000" ``` **Escenario 3: Activación automática de Stop Loss** ```gherkin DADO que la posición tiene SL en $93,000 CUANDO el precio baja y alcanza $93,000 ENTONCES se ejecuta automáticamente orden market sell Y la posición se cierra con pérdida Y el P&L realizado es -$200.00 Y el close_reason es "stop_loss" Y se envía notificación "Stop Loss triggered at $93,000" ``` **Escenario 4: Validación de niveles lógicos** ```gherkin DADO que el usuario tiene posición LONG CUANDO intenta configurar TP=$90,000 (menor al precio actual) ENTONCES se muestra warning "TP should be above current price for LONG" Y permite continuar (puede ser trailing stop futuro) CUANDO intenta configurar SL=$105,000 (mayor al precio actual) ENTONCES se muestra warning "SL should be below current price for LONG" ``` **Escenario 5: Modificar TP/SL existentes** ```gherkin DADO que la posición tiene TP=$100,000 y SL=$93,000 CUANDO el usuario modifica TP a $105,000 Y guarda los cambios ENTONCES el sistema actualiza solo el TP Y mantiene el SL en $93,000 Y las líneas en el chart se actualizan ``` **Escenario 6: Deshabilitar TP o SL** ```gherkin DADO que la posición tiene TP y SL configurados CUANDO el usuario deshabilita el checkbox de TP Y guarda ENTONCES el TP se elimina Y solo queda activo el SL Y la línea verde desaparece del chart ``` **Escenario 7: Mostrar Risk/Reward Ratio** ```gherkin DADO que el usuario configura TP=$100,000 y SL=$93,000 CUANDO el sistema calcula ENTONCES muestra Risk/Reward = 2.50 - Potencial ganancia: $500 (riesgo hacia arriba) - Potencial pérdida: $200 (riesgo hacia abajo) - Ratio: 500 / 200 = 2.50 Y muestra indicador "Good" si ratio > 2.0 ``` ## Criterios Adicionales - [ ] Botones rápidos para configurar TP/SL en % - [ ] Trailing Stop Loss (futuro enhancement) - [ ] Notificación cuando el precio se acerca a TP/SL (±1%) - [ ] Mostrar distancia a TP/SL en tiempo real - [ ] Histórico de TP/SL activados --- ## Tareas Técnicas **Database:** - [ ] DB-TRD-019: Añadir campos take_profit, stop_loss a paper_positions - [ ] DB-TRD-020: Añadir índice en (take_profit, stop_loss) para queries **Backend:** - [ ] BE-TRD-064: Crear endpoint PATCH /trading/paper/positions/:id/tp-sl - [ ] BE-TRD-065: Implementar PositionService.updateTPSL() - [ ] BE-TRD-066: Implementar TPSLMonitorService (background job) - [ ] BE-TRD-067: Implementar lógica de activación de TP - [ ] BE-TRD-068: Implementar lógica de activación de SL - [ ] BE-TRD-069: Integrar con PositionService.closePosition() **Frontend:** - [ ] FE-TRD-064: Crear componente ConfigureTPSLDialog.tsx - [ ] FE-TRD-065: Crear componente TPSLInput.tsx - [ ] FE-TRD-066: Crear componente RiskRewardIndicator.tsx - [ ] FE-TRD-067: Añadir líneas de TP/SL en TradingChart - [ ] FE-TRD-068: Implementar hook useConfigureTPSL - [ ] FE-TRD-069: Actualizar PositionRow con indicadores de TP/SL **Tests:** - [ ] TEST-TRD-031: Test unitario cálculo risk/reward - [ ] TEST-TRD-032: Test integración activación TP/SL - [ ] TEST-TRD-033: Test E2E flujo completo TP/SL --- ## Dependencias **Depende de:** - [ ] US-TRD-009: Ver posiciones - Estado: Pendiente - [ ] US-TRD-008: Cerrar posición - Estado: Pendiente **Bloquea:** - Ninguna --- ## Notas Técnicas **Endpoints involucrados:** | Método | Endpoint | Descripción | |--------|----------|-------------| | PATCH | /trading/paper/positions/:id/tp-sl | Configurar/actualizar TP/SL | | DELETE | /trading/paper/positions/:id/tp-sl | Eliminar TP/SL | **Entidades/Tablas:** ```sql ALTER TABLE trading.paper_positions ADD COLUMN take_profit DECIMAL(20, 8), ADD COLUMN stop_loss DECIMAL(20, 8); CREATE INDEX idx_positions_tp_sl ON trading.paper_positions(take_profit, stop_loss) WHERE take_profit IS NOT NULL OR stop_loss IS NOT NULL; ``` **Componentes UI:** - `ConfigureTPSLDialog`: Modal de configuración - `TPSLInput`: Input con validación - `RiskRewardIndicator`: Indicador de ratio - `TPSLLines`: Líneas horizontales en chart - `QuickPercentButtons`: Botones de % rápidos **Request Body:** ```typescript { takeProfit: 100000.00, // null para deshabilitar stopLoss: 93000.00 // null para deshabilitar } ``` **Response:** ```typescript { position: { id: "uuid", symbol: "BTCUSDT", side: "long", quantity: 0.1, entryPrice: 95000.00, currentPrice: 97234.50, takeProfit: 100000.00, stopLoss: 93000.00, riskRewardRatio: 2.50 }, preview: { distanceToTP: 2.84, distanceToSL: -4.35, potentialProfit: 500.00, potentialLoss: -200.00, riskRewardRatio: 2.50 } } ``` **TP/SL Monitor Logic (Background Job - cada segundo):** ```typescript // Para posición LONG const positions = await getPositionsWithTPSL(); for (const position of positions) { const currentPrice = await getCurrentPrice(position.symbol); // Check Take Profit if (position.takeProfit && currentPrice >= position.takeProfit) { await closePosition(position.id, 'take_profit'); await sendNotification(`TP triggered at ${currentPrice}`); } // Check Stop Loss if (position.stopLoss && currentPrice <= position.stopLoss) { await closePosition(position.id, 'stop_loss'); await sendNotification(`SL triggered at ${currentPrice}`); } } // Para posición SHORT (lógica inversa) // TP se activa cuando currentPrice <= takeProfit // SL se activa cuando currentPrice >= stopLoss ``` **Cálculos:** ```typescript // Risk/Reward Ratio const potentialProfit = Math.abs(takeProfit - entryPrice) * quantity; const potentialLoss = Math.abs(entryPrice - stopLoss) * quantity; const riskRewardRatio = potentialProfit / potentialLoss; // Distance to TP/SL (%) const distanceToTP = ((takeProfit - currentPrice) / currentPrice) * 100; const distanceToSL = ((stopLoss - currentPrice) / currentPrice) * 100; // Validaciones para LONG const validTPForLong = takeProfit > currentPrice; const validSLForLong = stopLoss < currentPrice; // Validaciones para SHORT const validTPForShort = takeProfit < currentPrice; const validSLForShort = stopLoss > currentPrice; ``` **Quick Percentage Buttons:** ```typescript // Para posición LONG, TP const tp1Percent = currentPrice * 1.01; // +1% const tp2Percent = currentPrice * 1.02; // +2% const tp5Percent = currentPrice * 1.05; // +5% const tp10Percent = currentPrice * 1.10; // +10% // Para posición LONG, SL const sl1Percent = currentPrice * 0.99; // -1% const sl2Percent = currentPrice * 0.98; // -2% const sl5Percent = currentPrice * 0.95; // -5% const sl10Percent = currentPrice * 0.90; // -10% ``` --- ## Definition of Ready (DoR) - [x] Historia claramente escrita - [x] Criterios de aceptación definidos - [x] Story points estimados - [x] Dependencias identificadas - [x] Sin bloqueadores - [ ] Diseño/mockup disponible - [ ] API spec disponible ## Definition of Done (DoD) - [ ] Código implementado según criterios - [ ] Tests unitarios escritos y pasando - [ ] Tests de integración pasando - [ ] Code review aprobado - [ ] Documentación actualizada - [ ] QA aprobado - [ ] Desplegado en ambiente de pruebas --- ## Historial de Cambios | Fecha | Cambio | Autor | |-------|--------|-------| | 2025-12-05 | Creación | Requirements-Analyst | --- **Creada por:** Requirements-Analyst **Fecha:** 2025-12-05 **Última actualización:** 2025-12-05