--- id: "RF-TRD-005" title: "Sistema de Ordenes" type: "Requirement" status: "Done" priority: "Alta" module: "trading" epic: "OQI-003" version: "1.0" created_date: "2025-12-05" updated_date: "2026-01-04" --- # RF-TRD-005: Sistema de Órdenes **Versión:** 1.0.0 **Fecha:** 2025-12-05 **Épica:** OQI-003 - Trading y Charts **Prioridad:** P0 **Story Points:** 13 --- ## Descripción El sistema debe proporcionar una interfaz completa para crear, gestionar y monitorear órdenes de trading, tanto para paper trading como para trading real (futuro). Incluye validaciones avanzadas, previsualización de costos y gestión del ciclo de vida completo de las órdenes. --- ## Requisitos Funcionales ### RF-TRD-005.1: Tipos de Órdenes El sistema debe soportar los siguientes tipos: | Tipo | Ejecución | Parámetros requeridos | |------|-----------|----------------------| | Market | Inmediata al precio actual | quantity | | Limit | Cuando precio alcanza limit | quantity, limitPrice | | Stop-Loss | Se activa al alcanzar stop | quantity, stopPrice | | Stop-Limit | Stop + Limit combinados | quantity, stopPrice, limitPrice | | Take-Profit | Cierra posición en ganancia | quantity, takeProfitPrice | | OCO | One-Cancels-Other | quantity, stopPrice, limitPrice | ### RF-TRD-005.2: Formulario de Creación El sistema debe proporcionar interfaz con: **Campos básicos:** - Selector de símbolo (autocomplete) - Selector de lado (Buy/Sell) - Selector de tipo de orden - Input de cantidad (con calculadora) - Inputs de precios según tipo **Calculadora de cantidad:** - Por cantidad de activo (0.5 BTC) - Por valor en USD ($1,000) - Por porcentaje de balance (25%, 50%, 75%, 100%) - Mostrar equivalencia en tiempo real **Previsualización:** - Costo total estimado - Fees estimados (0% en paper trading) - Slippage estimado (para market orders) - Balance disponible después - Margen requerido - Precio promedio estimado ### RF-TRD-005.3: Validaciones Pre-Order El sistema debe validar antes de crear orden: | Validación | Condición | Mensaje de error | |------------|-----------|------------------| | Balance suficiente | balance >= costo total | "Balance insuficiente" | | Cantidad mínima | quantity >= minQty | "Cantidad mínima: X" | | Cantidad máxima | quantity <= maxQty | "Cantidad máxima: X" | | Precio válido | price > 0 | "Precio debe ser mayor a 0" | | Tick size | price % tickSize == 0 | "Precio inválido" | | Step size | quantity % stepSize == 0 | "Cantidad inválida" | | Posición existente | verificar conflictos | "Ya existe posición" | ### RF-TRD-005.4: Confirmación de Orden El sistema debe mostrar modal de confirmación con: - Resumen de la orden - Advertencias si las hay - Costo total final - Impacto en balance - Botones: "Confirmar" y "Cancelar" - Checkbox "No volver a preguntar" (configurable) ### RF-TRD-005.5: Estados de Orden El sistema debe manejar los siguientes estados: ``` NEW → PENDING → FILLED ↓ PARTIALLY_FILLED → FILLED ↓ CANCELLED ↓ REJECTED ↓ EXPIRED ``` **Transiciones:** - NEW: Orden creada, pendiente de procesamiento - PENDING: Esperando que precio alcance nivel - PARTIALLY_FILLED: Ejecución parcial (split orders) - FILLED: Completamente ejecutada - CANCELLED: Cancelada por usuario - REJECTED: Rechazada por validaciones - EXPIRED: Expiró por timeout (para limit orders) ### RF-TRD-005.6: Panel de Órdenes Abiertas El sistema debe mostrar tabla con: | Columna | Descripción | |---------|-------------| | Time | Hora de creación | | Symbol | Par de trading | | Type | Tipo de orden | | Side | Buy/Sell | | Price | Precio límite/stop | | Amount | Cantidad | | Filled | % ejecutado | | Total | Valor total | | Actions | Cancelar, Editar | **Funcionalidades:** - Filtrar por símbolo, tipo, lado - Ordenar por cualquier columna - Cancelar orden individual - Cancelar todas las órdenes de un símbolo - Cancelar todas las órdenes - Auto-refresh cada 1 segundo ### RF-TRD-005.7: Modificación de Órdenes El sistema debe permitir modificar órdenes pending: - Cambiar precio límite/stop - Cambiar cantidad (solo reducir) - Cambiar take profit / stop loss - No se puede cambiar: símbolo, tipo, lado ### RF-TRD-005.8: Cancelación El sistema debe permitir: - Cancelar orden individual con confirmación - Cancelar múltiples órdenes seleccionadas - Cancelar todas las órdenes de símbolo - Cancelar todas las órdenes (con confirmación) - Botón de pánico "Cancel All" destacado ### RF-TRD-005.9: Notificaciones El sistema debe notificar cuando: - Orden es ejecutada (filled) - Orden es parcialmente ejecutada - Orden es cancelada - Orden es rechazada - Orden está cerca de ejecutarse (5% del precio) --- ## Datos de Entrada ### Crear Orden ```typescript interface CreateOrderDto { symbol: string; side: 'buy' | 'sell'; type: 'market' | 'limit' | 'stop_loss' | 'stop_limit' | 'take_profit' | 'oco'; // Cantidad quantity: number; quoteQuantity?: number; // Alternativa en USD // Precios según tipo limitPrice?: number; stopPrice?: number; takeProfitPrice?: number; // Opcionales timeInForce?: 'GTC' | 'IOC' | 'FOK'; // Good Till Cancel, Immediate or Cancel, Fill or Kill reduceOnly?: boolean; // Solo para cerrar posiciones // Stop Loss / Take Profit automáticos stopLoss?: { type: 'price' | 'percent'; value: number; }; takeProfit?: { type: 'price' | 'percent'; value: number; }; } ``` --- ## Datos de Salida ### Orden Creada ```typescript interface Order { id: string; userId: string; symbol: string; side: 'buy' | 'sell'; type: OrderType; status: OrderStatus; // Cantidades quantity: number; filledQuantity: number; remainingQuantity: number; // Precios limitPrice: number | null; stopPrice: number | null; avgFillPrice: number | null; // Costos totalCost: number; totalFees: number; // Stop Loss / Take Profit stopLoss: OrderStopLoss | null; takeProfit: OrderTakeProfit | null; // Timestamps createdAt: string; updatedAt: string; filledAt: string | null; cancelledAt: string | null; // Metadatos timeInForce: string; reduceOnly: boolean; isTriggered: boolean; // Para stop orders } enum OrderStatus { NEW = 'new', PENDING = 'pending', PARTIALLY_FILLED = 'partially_filled', FILLED = 'filled', CANCELLED = 'cancelled', REJECTED = 'rejected', EXPIRED = 'expired' } ``` ### Previsualización de Orden ```typescript interface OrderPreview { estimatedCost: number; estimatedFees: number; estimatedSlippage: number; estimatedTotal: number; balanceAfter: number; marginRequired: number; priceImpact: number; // Para grandes volúmenes warnings: string[]; } ``` --- ## Reglas de Negocio 1. **Tipos de orden:** - Paper trading: Todos los tipos soportados - Real trading (futuro): Validar con Binance API 2. **Validaciones de cantidad:** - Mínimo: $10 USD equivalente - Máximo: 100% del balance disponible - Step size según símbolo (ej: 0.001 BTC) 3. **Validaciones de precio:** - Tick size según símbolo (ej: $0.01) - Limit price debe ser razonable (±20% del precio actual) - Stop price debe ser lógico según side 4. **Time In Force:** - GTC (default): Hasta que se ejecute o cancele - IOC: Ejecutar inmediatamente lo posible, cancelar resto - FOK: Ejecutar todo o cancelar 5. **Órdenes conflictivas:** - No permitir 2 limit buy al mismo precio - Advertir si existe posición contraria 6. **Expiración:** - Limit orders expiran en 30 días - Stop orders no expiran 7. **Prioridad de ejecución:** - Precio-tiempo (mejor precio primero, luego FIFO) --- ## Criterios de Aceptación ```gherkin Escenario: Usuario crea orden market buy DADO que el usuario tiene balance de $10,000 Y BTCUSDT cotiza a $50,000 CUANDO crea orden market BUY de 0.1 BTC Y confirma la orden ENTONCES se crea orden con status "filled" Y se ejecuta inmediatamente a ~$50,050 (con slippage) Y se descuenta $5,005 del balance Y aparece notificación "Orden ejecutada" Escenario: Usuario crea orden limit sell DADO que el usuario tiene posición long de 0.5 BTC Y precio actual es $50,000 CUANDO crea orden limit SELL de 0.5 BTC a $52,000 Y confirma la orden ENTONCES se crea orden con status "pending" Y aparece en tabla de órdenes abiertas Y se monitorea el precio cada segundo Escenario: Orden limit se ejecuta DADO que el usuario tiene orden limit SELL a $52,000 CUANDO el precio de mercado alcanza $52,000 ENTONCES la orden cambia a status "filled" Y se cierra la posición Y se actualiza el balance Y aparece notificación Escenario: Validación de balance insuficiente DADO que el usuario tiene balance de $1,000 CUANDO intenta crear orden de $5,000 ENTONCES aparece error "Balance insuficiente" Y muestra balance disponible: $1,000 Y no se crea la orden Escenario: Usuario cancela orden pending DADO que el usuario tiene orden limit pending CUANDO hace click en "Cancelar" Y confirma la cancelación ENTONCES la orden cambia a status "cancelled" Y desaparece de órdenes abiertas Y libera el balance reservado Escenario: Stop Loss se activa automáticamente DADO que el usuario creó orden con stop loss al -5% Y tiene posición long con entry a $50,000 CUANDO el precio baja a $47,500 ENTONCES se crea orden market sell automática Y se cierra la posición Y se registra pérdida de -5% ``` --- ## Interfaz de Usuario ``` ┌─────────────────────────────────────────────────┐ │ CREATE ORDER │ ├─────────────────────────────────────────────────┤ │ │ │ Symbol: [BTCUSDT ▼] Price: $50,234.56 │ │ │ │ ┌─────────┬─────────┐ │ │ │ BUY │ SELL │ │ │ └─────────┴─────────┘ │ │ │ │ Type: [Market ▼] │ │ │ │ Amount: │ │ ┌────────────────────┐ BTC │ │ │ 0.5 │ │ │ └────────────────────┘ │ │ ≈ $25,117.28 USD │ │ │ │ [25%] [50%] [75%] [100%] │ │ │ │ ☐ Stop Loss: [_____] (-5%) │ │ ☐ Take Profit: [_____] (+10%) │ │ │ │ ─────────────────────────────────────── │ │ Cost: $25,117.28 │ │ Fees: $0.00 │ │ Slippage (est): $25.12 │ │ ─────────────────────────────────────── │ │ Total: $25,142.40 │ │ Balance after: $74,857.60 │ │ │ │ [ Cancel ] [ Place Order ] │ └─────────────────────────────────────────────────┘ ``` --- ## Dependencias - RF-TRD-004: Paper Trading (lógica de ejecución) - RF-TRD-006: Gestión de Posiciones (actualizar posiciones) - Binance API para datos de mercado - WebSocket para monitoreo de precios --- ## Notas Técnicas - Implementar validaciones en frontend y backend - Usar transacciones para operaciones de balance - Implementar locks para evitar race conditions - Calcular slippage basado en depth del orderbook - Guardar snapshots de precio para auditoría - Implementar rate limiting (máx 10 órdenes/minuto) - Usar WebSocket para monitoreo eficiente de órdenes pending - Cachear datos de símbolos (min/max qty, tick size) --- ## Métricas a Trackear - Órdenes creadas por tipo - Tasa de ejecución (filled / created) - Tasa de cancelación - Tiempo promedio hasta ejecución - Errores de validación más comunes - Slippage real vs estimado