trading-platform/docs/02-definicion-modulos/OQI-003-trading-charts/historias-usuario/US-TRD-012-configurar-tp-sl.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

14 KiB

id title type status priority epic story_points created_date updated_date
US-TRD-012 Configurar Take Profit y Stop Loss User Story Done Alta OQI-003 5 2025-12-05 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

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

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

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

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

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

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

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:

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:

{
  takeProfit: 100000.00,  // null para deshabilitar
  stopLoss: 93000.00      // null para deshabilitar
}

Response:

{
  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):

// 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:

// 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:

// 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)

  • Historia claramente escrita
  • Criterios de aceptación definidos
  • Story points estimados
  • Dependencias identificadas
  • 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