# TRACEABILITY.yml - OQI-008 Portfolio Manager
# Mapeo de requerimientos a implementacion

version: "1.1.0"
epic: OQI-008
name: "Portfolio Manager Avanzado"
updated: "2026-01-28"
status: planned

# Resumen de trazabilidad
summary:
  total_requirements: 7
  total_specs: 11
  total_user_stories: 14
  total_files_to_implement: 55
  test_coverage: "TBD"
  story_points: 75
  phase: 2
  documentation_progress: "100%"

# Nuevas especificaciones agregadas 2026-01-28
new_specs:
  - id: ET-PFM-010
    name: "Arquitectura General del Sistema"
    path: "../especificaciones/ET-PFM-010-architecture.md"
    description: "Vision completa de arquitectura: capas, flujos de datos, integraciones"
    added: "2026-01-28"
  - id: ET-PFM-011
    name: "Sistema de Goals Completo"
    path: "../especificaciones/ET-PFM-011-goals-system.md"
    description: "Sistema completo de metas: entities, Monte Carlo, proyecciones"
    added: "2026-01-28"

# Mapeo de Requerimientos Funcionales
requirements:
  RF-PFM-001:
    name: "Dashboard de Portfolio"
    status: planned
    specs:
      - ET-PFM-001
      - ET-PFM-005
    user_stories:
      - US-PFM-001
      - US-PFM-002
    implementation:
      backend:
        - path: apps/backend/src/modules/portfolio/services/portfolio.service.ts
          description: "Servicio principal de portfolio"
          methods:
            - getPortfolioSummary
            - getPortfolioValue
            - getPortfolioHistory
            - getAssetAllocation
            - getDiversificationScore
        - path: apps/backend/src/modules/portfolio/controllers/portfolio.controller.ts
          methods:
            - getSummary
            - getValue
            - getHistory
        - path: apps/backend/src/modules/portfolio/portfolio.routes.ts
          routes:
            - "GET /portfolio/summary"
            - "GET /portfolio/value"
            - "GET /portfolio/history"
            - "GET /portfolio/allocation"
      frontend:
        - path: apps/frontend/src/modules/portfolio/pages/Portfolio.tsx
          description: "Página principal de portfolio"
        - path: apps/frontend/src/modules/portfolio/components/PortfolioSummary.tsx
          description: "Resumen de portfolio"
        - path: apps/frontend/src/modules/portfolio/components/PortfolioChart.tsx
          description: "Gráfico de valor histórico"
        - path: apps/frontend/src/modules/portfolio/components/AllocationPie.tsx
          description: "Pie chart de asignación"
        - path: apps/frontend/src/modules/portfolio/components/NetWorthCard.tsx
          description: "Tarjeta de patrimonio neto"
      database:
        - path: apps/database/schemas/08_portfolio_schema.sql
          tables:
            - portfolios
            - portfolio_snapshots
            - portfolio_settings
          enums:
            - portfolio_type_enum
    tests:
      - path: apps/backend/tests/portfolio/portfolio.service.test.ts
        status: planned

  RF-PFM-002:
    name: "Gestión de Holdings"
    status: planned
    specs:
      - ET-PFM-001
      - ET-PFM-002
    user_stories:
      - US-PFM-003
      - US-PFM-004
    implementation:
      backend:
        - path: apps/backend/src/modules/portfolio/services/holding.service.ts
          description: "Servicio de holdings"
          methods:
            - getHoldings
            - getHoldingById
            - addHolding
            - updateHolding
            - removeHolding
            - getHoldingPerformance
            - syncWithBroker
        - path: apps/backend/src/modules/portfolio/controllers/portfolio.controller.ts
          methods:
            - getHoldings
            - addHolding
            - updateHolding
            - deleteHolding
        - path: apps/backend/src/modules/portfolio/portfolio.routes.ts
          routes:
            - "GET /portfolio/holdings"
            - "POST /portfolio/holdings"
            - "PUT /portfolio/holdings/:id"
            - "DELETE /portfolio/holdings/:id"
            - "POST /portfolio/holdings/sync"
      frontend:
        - path: apps/frontend/src/modules/portfolio/components/HoldingsTable.tsx
          description: "Tabla de holdings"
        - path: apps/frontend/src/modules/portfolio/components/HoldingCard.tsx
          description: "Tarjeta de holding"
        - path: apps/frontend/src/modules/portfolio/components/AddHoldingModal.tsx
          description: "Modal para agregar holding"
        - path: apps/frontend/src/modules/portfolio/components/HoldingDetail.tsx
          description: "Detalle de holding"
      database:
        - path: apps/database/schemas/08_portfolio_schema.sql
          tables:
            - holdings
            - holding_transactions
            - holding_lots
          enums:
            - holding_type_enum
            - asset_class_enum
    tests:
      - path: apps/backend/tests/portfolio/holding.service.test.ts
        status: planned

  RF-PFM-003:
    name: "Análisis de Rendimiento"
    status: planned
    specs:
      - ET-PFM-003
      - ET-PFM-004
    user_stories:
      - US-PFM-005
      - US-PFM-006
    implementation:
      backend:
        - path: apps/backend/src/modules/portfolio/services/performance.service.ts
          description: "Servicio de análisis de rendimiento"
          methods:
            - calculateTWR
            - calculateMWR
            - calculateAlpha
            - calculateBeta
            - calculateSharpe
            - calculateSortino
            - compareWithBenchmark
            - getAttributionAnalysis
        - path: apps/backend/src/modules/portfolio/controllers/portfolio.controller.ts
          methods:
            - getPerformance
            - getBenchmarkComparison
            - getAttribution
        - path: apps/backend/src/modules/portfolio/portfolio.routes.ts
          routes:
            - "GET /portfolio/performance"
            - "GET /portfolio/performance/metrics"
            - "GET /portfolio/performance/benchmark"
            - "GET /portfolio/performance/attribution"
      frontend:
        - path: apps/frontend/src/modules/portfolio/pages/Performance.tsx
          description: "Página de rendimiento"
        - path: apps/frontend/src/modules/portfolio/components/PerformanceMetrics.tsx
          description: "Métricas de rendimiento"
        - path: apps/frontend/src/modules/portfolio/components/BenchmarkComparison.tsx
          description: "Comparación con benchmark"
        - path: apps/frontend/src/modules/portfolio/components/ReturnChart.tsx
          description: "Gráfico de retornos"
        - path: apps/frontend/src/modules/portfolio/components/DrawdownChart.tsx
          description: "Gráfico de drawdown"
      database:
        - path: apps/database/schemas/08_portfolio_schema.sql
          tables:
            - performance_metrics
            - benchmark_data
            - performance_attribution
    tests:
      - path: apps/backend/tests/portfolio/performance.service.test.ts
        status: planned

  RF-PFM-004:
    name: "Análisis de Riesgo"
    status: planned
    specs:
      - ET-PFM-003
      - ET-PFM-004
    user_stories:
      - US-PFM-007
    implementation:
      backend:
        - path: apps/backend/src/modules/portfolio/services/risk.service.ts
          description: "Servicio de análisis de riesgo"
          methods:
            - calculateVaR
            - calculateCVaR
            - calculateVolatility
            - calculateCorrelation
            - stressTest
            - getConcentrationRisk
            - getSectorExposure
        - path: apps/backend/src/modules/portfolio/controllers/portfolio.controller.ts
          methods:
            - getRiskAnalysis
            - getVaR
            - runStressTest
        - path: apps/backend/src/modules/portfolio/portfolio.routes.ts
          routes:
            - "GET /portfolio/risk"
            - "GET /portfolio/risk/var"
            - "POST /portfolio/risk/stress-test"
            - "GET /portfolio/risk/concentration"
      frontend:
        - path: apps/frontend/src/modules/portfolio/pages/Risk.tsx
          description: "Página de análisis de riesgo"
        - path: apps/frontend/src/modules/portfolio/components/RiskMetrics.tsx
          description: "Métricas de riesgo"
        - path: apps/frontend/src/modules/portfolio/components/VaRChart.tsx
          description: "Gráfico de VaR"
        - path: apps/frontend/src/modules/portfolio/components/CorrelationMatrix.tsx
          description: "Matriz de correlación"
        - path: apps/frontend/src/modules/portfolio/components/StressTestResults.tsx
          description: "Resultados de stress test"
      database:
        - path: apps/database/schemas/08_portfolio_schema.sql
          tables:
            - risk_metrics
            - stress_test_results
            - correlation_data
    tests:
      - path: apps/backend/tests/portfolio/risk.service.test.ts
        status: planned

  RF-PFM-005:
    name: "Rebalanceo"
    status: planned
    specs:
      - ET-PFM-002
      - ET-PFM-006
    user_stories:
      - US-PFM-008
      - US-PFM-009
    implementation:
      backend:
        - path: apps/backend/src/modules/portfolio/services/rebalance.service.ts
          description: "Servicio de rebalanceo"
          methods:
            - getTargetAllocation
            - setTargetAllocation
            - calculateRebalanceActions
            - executeRebalance
            - scheduleRebalance
            - getRebalanceHistory
        - path: apps/backend/src/modules/portfolio/controllers/portfolio.controller.ts
          methods:
            - getRebalanceSuggestions
            - setTargetAllocation
            - executeRebalance
        - path: apps/backend/src/modules/portfolio/portfolio.routes.ts
          routes:
            - "GET /portfolio/rebalance/suggestions"
            - "POST /portfolio/rebalance/target"
            - "POST /portfolio/rebalance/execute"
            - "GET /portfolio/rebalance/history"
      frontend:
        - path: apps/frontend/src/modules/portfolio/pages/Rebalance.tsx
          description: "Página de rebalanceo"
        - path: apps/frontend/src/modules/portfolio/components/TargetAllocation.tsx
          description: "Configurar asignación objetivo"
        - path: apps/frontend/src/modules/portfolio/components/RebalancePreview.tsx
          description: "Preview de acciones de rebalanceo"
        - path: apps/frontend/src/modules/portfolio/components/AllocationSliders.tsx
          description: "Sliders de asignación"
      database:
        - path: apps/database/schemas/08_portfolio_schema.sql
          tables:
            - target_allocations
            - rebalance_actions
            - rebalance_history
    tests:
      - path: apps/backend/tests/portfolio/rebalance.service.test.ts
        status: planned

  RF-PFM-006:
    name: "Reportes"
    status: planned
    specs:
      - ET-PFM-005
      - ET-PFM-007
    user_stories:
      - US-PFM-010
      - US-PFM-011
    implementation:
      backend:
        - path: apps/backend/src/modules/portfolio/services/report.service.ts
          description: "Servicio de reportes"
          methods:
            - generateReport
            - getReports
            - downloadReport
            - scheduleReport
            - sendReportEmail
        - path: apps/backend/src/modules/portfolio/controllers/portfolio.controller.ts
          methods:
            - generateReport
            - getReports
            - downloadReport
        - path: apps/backend/src/modules/portfolio/portfolio.routes.ts
          routes:
            - "POST /portfolio/reports"
            - "GET /portfolio/reports"
            - "GET /portfolio/reports/:id/download"
      frontend:
        - path: apps/frontend/src/modules/portfolio/pages/Reports.tsx
          description: "Página de reportes"
        - path: apps/frontend/src/modules/portfolio/components/ReportGenerator.tsx
          description: "Generador de reportes"
        - path: apps/frontend/src/modules/portfolio/components/ReportPreview.tsx
          description: "Preview de reporte"
        - path: apps/frontend/src/modules/portfolio/components/ReportList.tsx
          description: "Lista de reportes"
      database:
        - path: apps/database/schemas/08_portfolio_schema.sql
          tables:
            - reports
            - report_templates
            - scheduled_reports
          enums:
            - report_type_enum
            - report_frequency_enum
    tests:
      - path: apps/backend/tests/portfolio/report.service.test.ts
        status: planned

  RF-PFM-007:
    name: "Objetivos Financieros"
    status: planned
    specs:
      - ET-PFM-006
    user_stories:
      - US-PFM-012
    implementation:
      backend:
        - path: apps/backend/src/modules/portfolio/services/goal.service.ts
          description: "Servicio de objetivos"
          methods:
            - createGoal
            - updateGoal
            - deleteGoal
            - getGoals
            - calculateProgress
            - projectCompletion
            - suggestContributions
        - path: apps/backend/src/modules/portfolio/controllers/portfolio.controller.ts
          methods:
            - createGoal
            - getGoals
            - updateGoal
            - deleteGoal
        - path: apps/backend/src/modules/portfolio/portfolio.routes.ts
          routes:
            - "GET /portfolio/goals"
            - "POST /portfolio/goals"
            - "PUT /portfolio/goals/:id"
            - "DELETE /portfolio/goals/:id"
            - "GET /portfolio/goals/:id/progress"
      frontend:
        - path: apps/frontend/src/modules/portfolio/pages/Goals.tsx
          description: "Página de objetivos"
        - path: apps/frontend/src/modules/portfolio/components/GoalCard.tsx
          description: "Tarjeta de objetivo"
        - path: apps/frontend/src/modules/portfolio/components/GoalProgress.tsx
          description: "Progreso del objetivo"
        - path: apps/frontend/src/modules/portfolio/components/GoalCreator.tsx
          description: "Creador de objetivos"
        - path: apps/frontend/src/modules/portfolio/components/ProjectionChart.tsx
          description: "Gráfico de proyección"
      database:
        - path: apps/database/schemas/08_portfolio_schema.sql
          tables:
            - financial_goals
            - goal_contributions
            - goal_projections
          enums:
            - goal_type_enum
            - goal_priority_enum
    tests:
      - path: apps/backend/tests/portfolio/goal.service.test.ts
        status: planned

# Métricas de portfolio
portfolio_metrics:
  return_metrics:
    - TWR (Time-Weighted Return)
    - MWR (Money-Weighted Return)
    - CAGR
    - YTD Return
    - Annualized Return
  risk_metrics:
    - Standard Deviation
    - Sharpe Ratio
    - Sortino Ratio
    - Max Drawdown
    - VaR (95%, 99%)
    - CVaR / Expected Shortfall
    - Beta
    - Tracking Error
  advanced_metrics:
    - Alpha
    - Information Ratio
    - Treynor Ratio
    - Calmar Ratio
    - Ulcer Index

# Benchmarks soportados
benchmarks:
  - code: SPY
    name: "S&P 500"
    asset_class: equity
  - code: QQQ
    name: "NASDAQ 100"
    asset_class: equity
  - code: IWM
    name: "Russell 2000"
    asset_class: equity
  - code: AGG
    name: "US Aggregate Bond"
    asset_class: fixed_income
  - code: BTC
    name: "Bitcoin"
    asset_class: crypto
  - code: CUSTOM
    name: "Custom Benchmark"
    asset_class: mixed

# Mapeo de archivos de configuración
config_files:
  backend:
    - path: apps/backend/src/modules/portfolio/portfolio.module.ts
      description: "Módulo de portfolio"
    - path: apps/backend/src/modules/portfolio/types/portfolio.types.ts
      description: "Tipos TypeScript"
    - path: apps/backend/src/modules/portfolio/validators/portfolio.validators.ts
      description: "Validadores Zod"
    - path: apps/backend/src/modules/portfolio/cron/portfolio.cron.ts
      description: "Jobs programados"
  frontend:
    - path: apps/frontend/src/modules/portfolio/stores/portfolio.store.ts
      description: "Store de portfolio Zustand"
    - path: apps/frontend/src/modules/portfolio/hooks/usePortfolio.ts
      description: "Hook principal de portfolio"
    - path: apps/frontend/src/modules/portfolio/services/portfolio.api.ts
      description: "Cliente API de portfolio"

# Dependencias externas
external_dependencies:
  npm_backend:
    - name: mathjs
      version: "^12.0.0"
      usage: "Cálculos financieros"
    - name: simple-statistics
      version: "^7.8.0"
      usage: "Estadísticas"
    - name: pdfkit
      version: "^0.14.0"
      usage: "Generación de reportes PDF"
    - name: node-cron
      version: "^3.0.0"
      usage: "Jobs programados"
  npm_frontend:
    - name: recharts
      version: "^2.10.0"
      usage: "Gráficos"
    - name: "@tanstack/react-table"
      version: "^8.10.0"
      usage: "Tablas de datos"
    - name: react-grid-layout
      version: "^1.4.0"
      usage: "Dashboard customizable"

# APIs de terceros
third_party_apis:
  - name: Alpaca Markets
    docs: https://alpaca.markets/docs
    usage:
      - Posiciones reales (opcional)
      - Sincronización de cuenta
  - name: Yahoo Finance
    docs: https://finance.yahoo.com
    usage:
      - Datos históricos de benchmark
      - Precios de activos
  - name: Alpha Vantage
    docs: https://www.alphavantage.co/documentation/
    usage:
      - Datos fundamentales
      - Información de sectores

# Endpoints API
api_endpoints:
  base_path: /api/v1/portfolio
  endpoints:
    # Dashboard
    - method: GET
      path: /summary
      requirement: RF-PFM-001
      auth: true
    - method: GET
      path: /value
      requirement: RF-PFM-001
      auth: true
    - method: GET
      path: /history
      requirement: RF-PFM-001
      auth: true
    - method: GET
      path: /allocation
      requirement: RF-PFM-001
      auth: true
    # Holdings
    - method: GET
      path: /holdings
      requirement: RF-PFM-002
      auth: true
    - method: POST
      path: /holdings
      requirement: RF-PFM-002
      auth: true
    - method: PUT
      path: /holdings/:id
      requirement: RF-PFM-002
      auth: true
    - method: DELETE
      path: /holdings/:id
      requirement: RF-PFM-002
      auth: true
    # Performance
    - method: GET
      path: /performance
      requirement: RF-PFM-003
      auth: true
    - method: GET
      path: /performance/benchmark
      requirement: RF-PFM-003
      auth: true
    # Risk
    - method: GET
      path: /risk
      requirement: RF-PFM-004
      auth: true
    - method: GET
      path: /risk/var
      requirement: RF-PFM-004
      auth: true
    - method: POST
      path: /risk/stress-test
      requirement: RF-PFM-004
      auth: true
    # Rebalance
    - method: GET
      path: /rebalance/suggestions
      requirement: RF-PFM-005
      auth: true
    - method: POST
      path: /rebalance/target
      requirement: RF-PFM-005
      auth: true
    - method: POST
      path: /rebalance/execute
      requirement: RF-PFM-005
      auth: true
    # Reports
    - method: POST
      path: /reports
      requirement: RF-PFM-006
      auth: true
    - method: GET
      path: /reports
      requirement: RF-PFM-006
      auth: true
    - method: GET
      path: /reports/:id/download
      requirement: RF-PFM-006
      auth: true
    # Goals
    - method: GET
      path: /goals
      requirement: RF-PFM-007
      auth: true
    - method: POST
      path: /goals
      requirement: RF-PFM-007
      auth: true
    - method: PUT
      path: /goals/:id
      requirement: RF-PFM-007
      auth: true
    - method: DELETE
      path: /goals/:id
      requirement: RF-PFM-007
      auth: true

# Dependencias de épicas
dependencies:
  blocks: []
  blocked_by:
    - epic: OQI-001
      reason: "Requiere autenticación"
    - epic: OQI-003
      reason: "Usa datos de trading para holdings"
    - epic: OQI-004
      reason: "Integra cuentas de inversión"

# Notas y decisiones
notes:
  - "TWR como métrica principal de rendimiento"
  - "Snapshots diarios automáticos del portfolio"
  - "VaR calculado con método histórico (252 días)"
  - "Rebalanceo manual con preview de acciones"
  - "Reportes mensuales automáticos opcionales"
  - "Soporte para holdings manuales y sincronizados"
  - "Dashboard customizable con drag-and-drop"
  - "Proyecciones Monte Carlo para objetivos"
