# OQI-004: Cuentas de Inversión

## Resumen Ejecutivo

La épica OQI-004 implementa el sistema de cuentas de inversión gestionadas por agentes de inteligencia artificial. Los usuarios pueden invertir en productos con diferentes perfiles de riesgo (Atlas, Orion, Nova) y recibir distribución de utilidades automática.

---

## Metadata

| Campo | Valor |
|-------|-------|
| **ID** | OQI-004 |
| **Nombre** | Cuentas de Inversión |
| **Módulo** | investment |
| **Fase** | Fase 1 - MVP |
| **Prioridad** | P1 |
| **Estado** | Pendiente |
| **Story Points** | 50 SP |
| **Sprint(s)** | Sprint 5-6 |

---

## Objetivo

Proporcionar un sistema de inversión que permita a los usuarios:
1. Invertir en productos gestionados por agentes IA
2. Monitorear el rendimiento de sus inversiones en tiempo real
3. Realizar depósitos y solicitar retiros
4. Recibir distribución automática de utilidades
5. Acceder a reportes detallados de rendimiento

---

## Productos de Inversión

### Agentes IA Disponibles

| Agente | Perfil | Target Mensual | Max Drawdown | Mín. Inversión |
|--------|--------|----------------|--------------|----------------|
| **Atlas** | Conservador | 3-5% | 5% | $100 USD |
| **Orion** | Moderado | 5-10% | 10% | $500 USD |
| **Nova** | Agresivo | 10%+ | 20% | $1,000 USD |

### Características por Agente

**Atlas - El Guardián**
- Estrategia: Mean reversion + Grid trading
- Activos: BTC, ETH (solo majors)
- Frecuencia: 2-5 trades/día
- Ideal para: Inversores conservadores

**Orion - El Explorador**
- Estrategia: Trend following + Breakouts
- Activos: BTC, ETH, altcoins top 10
- Frecuencia: 5-15 trades/día
- Ideal para: Inversores moderados

**Nova - La Estrella**
- Estrategia: Momentum + Scalping
- Activos: Todos los pares disponibles
- Frecuencia: 20+ trades/día
- Ideal para: Inversores agresivos

---

## Alcance

### Incluido

| Feature | Descripción |
|---------|-------------|
| Productos | 3 productos de inversión (Atlas, Orion, Nova) |
| Apertura | Proceso de apertura de cuenta con KYC básico |
| Depósitos | Depósitos vía Stripe y crypto |
| Retiros | Solicitud de retiros con período de espera |
| Dashboard | Portfolio con métricas en tiempo real |
| Distribuciones | Pago automático de utilidades |
| Reportes | Histórico de rendimiento y transacciones |

### Excluido

| Feature | Razón | Fase |
|---------|-------|------|
| KYC avanzado | Regulación | Fase 2 |
| Retiro instantáneo | Liquidez | Q2 2025 |
| Productos personalizados | Complejidad | Backlog |
| API para terceros | Post-MVP | Fase 3 |

---

## Arquitectura

```
┌─────────────────────────────────────────────────────────────────┐
│                         FRONTEND                                 │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐             │
│  │  Products   │  │  Portfolio  │  │  Withdraw   │             │
│  │   Catalog   │  │  Dashboard  │  │   Request   │             │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘             │
└─────────┼────────────────┼────────────────┼─────────────────────┘
          │                │                │
          └────────────────┼────────────────┘
                           │ HTTPS
                           ▼
┌─────────────────────────────────────────────────────────────────┐
│                      BACKEND API                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │               INVESTMENT CONTROLLER                      │   │
│  │  GET /investment/products  POST /investment/accounts     │   │
│  │  POST /investment/deposit  POST /investment/withdraw     │   │
│  │  GET /investment/portfolio GET /investment/transactions  │   │
│  └─────────────────────────────────────────────────────────┘   │
│                              │                                   │
│  ┌───────────┐  ┌───────────┐  ┌───────────┐  ┌───────────┐   │
│  │  Product  │  │  Account  │  │Transaction│  │Distribution│   │
│  │  Service  │  │  Service  │  │  Service  │  │  Service   │   │
│  └─────┬─────┘  └─────┬─────┘  └─────┬─────┘  └─────┬─────┘   │
└────────┼──────────────┼──────────────┼──────────────┼───────────┘
         │              │              │              │
         ▼              ▼              ▼              ▼
┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│  ML Engine  │  │ PostgreSQL  │  │   Stripe    │  │   Cron      │
│  (Agents)   │  │ investment  │  │  (Payments) │  │(Distributions│
└─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘
```

---

## Flujos Principales

### 1. Apertura de Cuenta de Inversión

```
Usuario                    Frontend                   Backend                    DB
   │                          │                          │                        │
   │─── Selecciona producto ─▶│                          │                        │
   │                          │─── GET /products/:id ───▶│                        │
   │◀── Muestra detalles ─────│◀── Product info ─────────│                        │
   │                          │                          │                        │
   │─── Click "Invertir" ────▶│                          │                        │
   │                          │─── POST /accounts ───────▶│                       │
   │                          │                          │─── Create account ────▶│
   │                          │                          │◀── account_id ─────────│
   │                          │◀── Account created ──────│                        │
   │◀── Redirige a depósito ──│                          │                        │
```

### 2. Depósito en Cuenta

```
Usuario                    Frontend                   Backend                   Stripe
   │                          │                          │                        │
   │─── Ingresa monto ───────▶│                          │                        │
   │                          │─── POST /deposit ────────▶│                       │
   │                          │                          │─── Create payment ────▶│
   │                          │◀── clientSecret ─────────│◀── PaymentIntent ─────│
   │◀── Muestra Stripe form ──│                          │                        │
   │                          │                          │                        │
   │─── Completa pago ───────▶│                          │                        │
   │                          │─── Webhook received ─────│◀── payment.succeeded ─│
   │                          │                          │─── Update balance ────▶│
   │◀── Depósito confirmado ──│◀── Balance updated ──────│                        │
```

### 3. Solicitud de Retiro

```
Usuario                    Frontend                   Backend                    DB
   │                          │                          │                        │
   │─── Solicita retiro ─────▶│                          │                        │
   │                          │─── POST /withdraw ───────▶│                       │
   │                          │                          │─── Validate balance ──▶│
   │                          │                          │─── Create request ────▶│
   │                          │◀── Request created ──────│                        │
   │◀── "Procesando (72h)" ───│                          │                        │
   │                          │                          │                        │
   │                          │        [72h después - Cron Job]                   │
   │                          │                          │─── Process withdraw ───│
   │◀── Email: Retiro completado ────────────────────────│                        │
```

---

## Modelo de Datos

### Tablas Principales

```sql
-- Productos de inversión disponibles
CREATE TABLE investment.products (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    code VARCHAR(20) UNIQUE NOT NULL, -- atlas, orion, nova
    name VARCHAR(100) NOT NULL,
    description TEXT,
    risk_profile risk_profile_enum NOT NULL, -- conservative, moderate, aggressive
    target_return_min DECIMAL(5,2), -- 3.00 (3%)
    target_return_max DECIMAL(5,2), -- 5.00 (5%)
    max_drawdown DECIMAL(5,2), -- 5.00 (5%)
    min_investment DECIMAL(20,8) NOT NULL, -- 100.00
    management_fee DECIMAL(5,2) DEFAULT 0, -- 0% en MVP
    performance_fee DECIMAL(5,2) DEFAULT 20.00, -- 20% de ganancias
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Cuentas de inversión de usuarios
CREATE TABLE investment.accounts (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID REFERENCES public.users(id),
    product_id UUID REFERENCES investment.products(id),
    status account_status_enum DEFAULT 'active', -- active, suspended, closed
    balance DECIMAL(20,8) DEFAULT 0,
    initial_investment DECIMAL(20,8) DEFAULT 0,
    total_deposited DECIMAL(20,8) DEFAULT 0,
    total_withdrawn DECIMAL(20,8) DEFAULT 0,
    total_earnings DECIMAL(20,8) DEFAULT 0,
    total_fees_paid DECIMAL(20,8) DEFAULT 0,
    opened_at TIMESTAMPTZ DEFAULT NOW(),
    closed_at TIMESTAMPTZ,
    UNIQUE(user_id, product_id) -- Una cuenta por producto
);

-- Transacciones de inversión
CREATE TABLE investment.transactions (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    account_id UUID REFERENCES investment.accounts(id),
    type transaction_type_enum NOT NULL, -- deposit, withdrawal, earning, fee
    status transaction_status_enum DEFAULT 'pending',
    amount DECIMAL(20,8) NOT NULL,
    balance_before DECIMAL(20,8),
    balance_after DECIMAL(20,8),
    stripe_payment_id VARCHAR(255),
    description TEXT,
    processed_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Solicitudes de retiro
CREATE TABLE investment.withdrawal_requests (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    account_id UUID REFERENCES investment.accounts(id),
    amount DECIMAL(20,8) NOT NULL,
    status withdrawal_status_enum DEFAULT 'pending', -- pending, processing, completed, rejected
    bank_info JSONB, -- Datos bancarios encriptados
    rejection_reason TEXT,
    requested_at TIMESTAMPTZ DEFAULT NOW(),
    processed_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ
);

-- Rendimiento diario por cuenta
CREATE TABLE investment.daily_performance (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    account_id UUID REFERENCES investment.accounts(id),
    date DATE NOT NULL,
    opening_balance DECIMAL(20,8),
    closing_balance DECIMAL(20,8),
    pnl DECIMAL(20,8),
    pnl_percent DECIMAL(10,4),
    trades_count INTEGER DEFAULT 0,
    win_rate DECIMAL(5,2),
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(account_id, date)
);

-- Distribuciones de utilidades
CREATE TABLE investment.distributions (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    account_id UUID REFERENCES investment.accounts(id),
    period_start DATE NOT NULL,
    period_end DATE NOT NULL,
    gross_earnings DECIMAL(20,8),
    performance_fee DECIMAL(20,8),
    net_earnings DECIMAL(20,8),
    status distribution_status_enum DEFAULT 'pending',
    distributed_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW()
);
```

---

## API Endpoints

### Productos

| Method | Endpoint | Descripción |
|--------|----------|-------------|
| GET | `/investment/products` | Listar productos disponibles |
| GET | `/investment/products/:id` | Detalle de producto |

### Cuentas

| Method | Endpoint | Descripción |
|--------|----------|-------------|
| GET | `/investment/accounts` | Mis cuentas de inversión |
| POST | `/investment/accounts` | Abrir cuenta |
| GET | `/investment/accounts/:id` | Detalle de cuenta |
| POST | `/investment/accounts/:id/close` | Cerrar cuenta |

### Transacciones

| Method | Endpoint | Descripción |
|--------|----------|-------------|
| POST | `/investment/accounts/:id/deposit` | Realizar depósito |
| POST | `/investment/accounts/:id/withdraw` | Solicitar retiro |
| GET | `/investment/accounts/:id/transactions` | Historial |

### Portfolio

| Method | Endpoint | Descripción |
|--------|----------|-------------|
| GET | `/investment/portfolio` | Resumen de portfolio |
| GET | `/investment/portfolio/performance` | Rendimiento histórico |
| GET | `/investment/portfolio/distributions` | Distribuciones |

---

## Métricas de Portfolio

```json
{
  "portfolio": {
    "totalInvested": 5000.00,
    "currentValue": 5750.00,
    "totalReturn": 750.00,
    "totalReturnPercent": 15.00,
    "accounts": [
      {
        "product": "Atlas",
        "invested": 2000.00,
        "currentValue": 2180.00,
        "return": 9.00,
        "status": "active"
      },
      {
        "product": "Orion",
        "invested": 3000.00,
        "currentValue": 3570.00,
        "return": 19.00,
        "status": "active"
      }
    ]
  },
  "performance": {
    "today": 0.5,
    "week": 2.3,
    "month": 8.5,
    "allTime": 15.0
  },
  "distributions": {
    "total": 450.00,
    "lastMonth": 150.00,
    "pending": 75.00
  }
}
```

---

## Seguridad

### Validaciones

- KYC básico requerido para inversiones > $1,000
- Verificación de email obligatoria
- 2FA recomendado para retiros
- Límite diario de retiro: $10,000

### Rate Limiting

| Endpoint | Límite | Ventana |
|----------|--------|---------|
| `/investment/deposit` | 10 | 1 hora |
| `/investment/withdraw` | 5 | 24 horas |
| General | 100 | 1 min |

---

## Entregables

| Entregable | Ruta | Estado |
|------------|------|--------|
| Schema DB | `apps/database/schemas/04_investment_schema.sql` | ✅ |
| Product Service | `apps/backend/src/modules/investment/services/product.service.ts` | Pendiente |
| Account Service | `apps/backend/src/modules/investment/services/account.service.ts` | Pendiente |
| Transaction Service | `apps/backend/src/modules/investment/services/transaction.service.ts` | Pendiente |
| Investment Controller | `apps/backend/src/modules/investment/controllers/investment.controller.ts` | Pendiente |
| Products Page | `apps/frontend/src/modules/investment/pages/Products.tsx` | Pendiente |
| Portfolio Page | `apps/frontend/src/modules/investment/pages/Portfolio.tsx` | Pendiente |
| Account Detail | `apps/frontend/src/modules/investment/pages/AccountDetail.tsx` | Pendiente |

---

## Dependencias

### Esta épica depende de:

| Épica/Módulo | Estado | Bloqueante |
|--------------|--------|------------|
| OQI-001 Auth | ✅ Completado | Sí |
| OQI-005 Payments | Pendiente | Sí (depósitos) |

### Esta épica bloquea:

| Épica/Módulo | Razón |
|--------------|-------|
| OQI-006 ML Signals | Agentes usan señales ML |

---

## Riesgos

| Riesgo | Probabilidad | Impacto | Mitigación |
|--------|--------------|---------|------------|
| Pérdidas de agentes | Media | Alto | Límites de drawdown, stop automático |
| Liquidez para retiros | Baja | Alto | Pool de reserva, delays |
| Regulación | Media | Alto | Términos claros, disclaimers |

---

## Referencias

- [_MAP de la Épica](./_MAP.md)
- [Requerimientos](./requerimientos/)
- [Especificaciones](./especificaciones/)
- [Historias de Usuario](./historias-usuario/)
