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 | story_points | created_date | updated_date |
|---|---|---|---|---|---|---|---|---|
| US-TRD-008 | Cerrar Posicion | User Story | Done | Alta | OQI-003 | 3 | 2025-12-05 | 2026-01-04 |
US-TRD-008: Cerrar Posición
Metadata
| Campo | Valor |
|---|---|
| ID | US-TRD-008 |
| Épica | OQI-003 - Trading y Charts |
| Módulo | trading |
| Prioridad | P0 |
| Story Points | 3 |
| Sprint | Sprint 4 |
| Estado | Pendiente |
| Asignado a | Por asignar |
Historia de Usuario
Como trader practicante, quiero cerrar mis posiciones abiertas total o parcialmente, para realizar mis ganancias o limitar mis pérdidas en el momento que decida.
Descripción Detallada
El usuario debe poder cerrar posiciones long o short en cualquier momento, ya sea completamente o una porción específica. Al cerrar, se ejecuta una orden market en dirección opuesta y se calcula el P&L (profit and loss) realizado.
Mockups/Wireframes
┌─────────────────────────────────────────────────────────────────┐
│ OPEN POSITIONS │
├─────────────────────────────────────────────────────────────────┤
│ Symbol Side Size Entry Current PnL Actions │
│ ────────────────────────────────────────────────────────────── │
│ BTCUSDT LONG 0.1 BTC $95,000 $97,234.50 +$223.45 [Close]│
│ (+2.35%) [ ▼ ] │
│ ────────────────────────────────────────────────────────────── │
│ │
│ ┌────────────────────────────────────┐ │
│ │ CLOSE POSITION │ │
│ ├────────────────────────────────────┤ │
│ │ Symbol: BTCUSDT │ │
│ │ Position: 0.1 BTC LONG │ │
│ │ │ │
│ │ Amount to close: │ │
│ │ ┌──────────────────────────────┐ │ │
│ │ │ 0.1 BTC │ │ │
│ │ └──────────────────────────────┘ │ │
│ │ [25%] [50%] [75%] [100%] │ │
│ │ │ │
│ │ Entry Price: $95,000.00 │ │
│ │ Current Price: $97,234.50 │ │
│ │ Est. P&L: +$223.45 (+2.35%) │ │
│ │ │ │
│ │ [Cancel] [Close Position] │ │
│ └────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Criterios de Aceptación
Escenario 1: Cerrar posición long completa
DADO que el usuario tiene posición long de 0.1 BTC en BTCUSDT
Y el precio de entrada fue $95,000
Y el precio actual es $97,234.50
CUANDO hace click en "Close" en la posición
Y selecciona cerrar 100% (0.1 BTC)
Y confirma
ENTONCES se ejecuta orden market SELL de 0.1 BTC
Y la posición se cierra completamente
Y se calcula P&L: +$223.45 (+2.35%)
Y el balance se incrementa en $9,723.45 ($9,500 + $223.45)
Y la posición desaparece de "Open Positions"
Y se muestra notificación "Position closed. P&L: +$223.45"
Escenario 2: Cerrar posición short con ganancia
DADO que el usuario tiene posición short de 0.05 BTC
Y el precio de entrada fue $97,000
Y el precio actual es $96,000
CUANDO cierra la posición completa
ENTONCES se ejecuta orden market BUY de 0.05 BTC
Y se calcula P&L: +$50.00 (+1.03%)
Y la posición se cierra
Escenario 3: Cerrar posición parcial (50%)
DADO que el usuario tiene posición long de 0.1 BTC
CUANDO hace click en "Close"
Y selecciona 50% (0.05 BTC)
Y confirma
ENTONCES se cierra solo 0.05 BTC
Y la posición restante es 0.05 BTC
Y el P&L parcial se registra
Y la posición sigue apareciendo con nuevo tamaño
Escenario 4: Cerrar posición con pérdida
DADO que el usuario tiene posición long a $97,000
Y el precio actual es $95,000
CUANDO cierra la posición
ENTONCES se calcula P&L: -$200.00 (-2.06%)
Y el balance se reduce en $200
Y se registra la pérdida en el historial
Escenario 5: Confirmación antes de cerrar
DADO que el usuario hace click en "Close"
CUANDO se abre el diálogo de confirmación
ENTONCES muestra:
- Cantidad a cerrar
- Precio de entrada vs actual
- P&L estimado
- Botón de confirmar
Y debe confirmar antes de ejecutar
Criterios Adicionales
- Slippage aplicado al cerrar (±0.1%)
- Keyboard shortcut: Esc para cancelar
- Color verde para P&L positivo, rojo para negativo
- Mostrar ROI (Return on Investment) en %
- Registro en trade history
Tareas Técnicas
Database:
- DB-TRD-012: Crear tabla paper_trade_history
- DB-TRD-013: Añadir campo closed_at a paper_positions
Backend:
- BE-TRD-038: Crear endpoint POST /trading/paper/positions/:id/close
- BE-TRD-039: Implementar PositionService.closePosition()
- BE-TRD-040: Implementar cálculo de P&L
- BE-TRD-041: Implementar cierre parcial
- BE-TRD-042: Actualizar BalanceService con P&L
- BE-TRD-043: Crear registro en trade_history
Frontend:
- FE-TRD-038: Crear componente OpenPositionsPanel.tsx
- FE-TRD-039: Crear componente ClosePositionDialog.tsx
- FE-TRD-040: Crear componente PositionRow.tsx con P&L
- FE-TRD-041: Implementar hook useClosePosition
- FE-TRD-042: Actualizar positionStore con cierres
- FE-TRD-043: Implementar animación al cerrar
Tests:
- TEST-TRD-019: Test unitario cálculo P&L
- TEST-TRD-020: Test integración cerrar posición
- TEST-TRD-021: Test E2E flujo completo cierre
Dependencias
Depende de:
- US-TRD-006: Crear orden market - Estado: Pendiente (necesita posiciones abiertas)
Bloquea:
- US-TRD-010: Ver historial de trades
Notas Técnicas
Endpoints involucrados:
| Método | Endpoint | Descripción |
|---|---|---|
| POST | /trading/paper/positions/:id/close | Cerrar posición |
| GET | /trading/paper/positions | Listar posiciones abiertas |
| GET | /trading/paper/positions/:id | Obtener detalles de posición |
Entidades/Tablas:
CREATE TABLE trading.paper_trade_history (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES auth.users(id),
symbol VARCHAR(20) NOT NULL,
side VARCHAR(10) NOT NULL,
quantity DECIMAL(20, 8) NOT NULL,
entry_price DECIMAL(20, 8) NOT NULL,
exit_price DECIMAL(20, 8) NOT NULL,
pnl DECIMAL(20, 8) NOT NULL,
pnl_percentage DECIMAL(10, 4) NOT NULL,
opened_at TIMESTAMP NOT NULL,
closed_at TIMESTAMP DEFAULT NOW(),
duration_seconds INTEGER
);
ALTER TABLE trading.paper_positions ADD COLUMN closed_at TIMESTAMP;
ALTER TABLE trading.paper_positions ADD COLUMN status VARCHAR(20) DEFAULT 'open';
Componentes UI:
OpenPositionsPanel: Panel de posiciones abiertasClosePositionDialog: Modal de confirmaciónPositionRow: Fila con datos de posiciónPnLBadge: Badge con P&L coloreado
Request Body:
{
quantity: 0.05, // Cantidad a cerrar (o null para cerrar todo)
percentage: 50 // O porcentaje (25, 50, 75, 100)
}
Response:
{
trade: {
id: "uuid",
symbol: "BTCUSDT",
side: "long",
quantity: 0.05,
entryPrice: 95000.00,
exitPrice: 97234.50,
pnl: 111.73,
pnlPercentage: 2.35,
openedAt: "2025-12-05T09:00:00Z",
closedAt: "2025-12-05T10:30:00Z",
durationSeconds: 5400
},
position: {
id: "uuid",
remainingQuantity: 0.05, // Si cierre parcial
status: "open" // o "closed"
},
balance: {
balance: 9611.73,
equity: 9723.46,
marginUsed: 4762.50
}
}
Cálculo de P&L:
// Para posición LONG
const pnl = (exitPrice - entryPrice) * quantity;
const pnlPercentage = ((exitPrice - entryPrice) / entryPrice) * 100;
// Para posición SHORT
const pnl = (entryPrice - exitPrice) * quantity;
const pnlPercentage = ((entryPrice - exitPrice) / entryPrice) * 100;
// Aplicar slippage (simulación)
const slippage = 0.001; // 0.1%
const actualExitPrice = side === 'long'
? currentPrice * (1 - slippage)
: currentPrice * (1 + slippage);
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