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