diff --git a/docs/02-definicion-modulos/OQI-007-llm-agent/README.md b/docs/02-definicion-modulos/OQI-007-llm-agent/README.md index 3057d27..eb1489d 100644 --- a/docs/02-definicion-modulos/OQI-007-llm-agent/README.md +++ b/docs/02-definicion-modulos/OQI-007-llm-agent/README.md @@ -3,12 +3,28 @@ id: "README" title: "LLM Strategy Agent" type: "Documentation" project: "trading-platform" -version: "1.0.0" -updated_date: "2026-01-04" +version: "1.1.0" +updated_date: "2026-01-28" +status: "En Progreso" +progress: 45 --- # OQI-007: LLM Strategy Agent +## Estado del Módulo + +| Aspecto | Estado | Progreso | +|---------|--------|----------| +| Documentación | ✅ Completa | 100% | +| Especificaciones | ✅ 7 de 7 | 100% | +| User Stories | ✅ 11 de 11 | 100% | +| Implementación Backend | En Progreso | 40% | +| Implementación Frontend | En Progreso | 35% | +| Tests | Pendiente | 15% | +| **Global** | **En Progreso** | **45%** | + +--- + ## Resumen Ejecutivo Esta épica implementa un agente de inteligencia artificial basado en Large Language Models (LLM) que actúa como asistente de trading inteligente, interpretando señales ML, sugiriendo estrategias y explicando decisiones en lenguaje natural. @@ -312,12 +328,52 @@ En el último mes, detectamos 3 fases de acumulación en BTC: --- -## Story Points Totales: 55 SP +## Story Points Totales: 60 SP + +--- + +## Documentación Completa + +### Especificaciones Técnicas (7) +| ID | Nombre | Descripción | +|----|--------|-------------| +| ET-LLM-001 | Arquitectura Chat | Sistema WebSocket/Chat completo | +| ET-LLM-002 | Agente de Análisis | Agente especializado en análisis de mercado | +| ET-LLM-003 | Motor de Estrategias | Motor de sugerencias de estrategias | +| ET-LLM-004 | Integración Educativa | Conexión con módulo educativo | +| ET-LLM-005 | Arquitectura Tools | Sistema de tools y function calling | +| ET-LLM-006 | Gestión de Memoria | Contexto y memoria conversacional | +| ET-LLM-007 | Frontend | Componentes React, hooks, stores | + +### Historias de Usuario (11) +| ID | Historia | SP | +|----|----------|-----| +| US-LLM-001 | Enviar mensaje al agente | 5 | +| US-LLM-002 | Gestionar conversaciones | 5 | +| US-LLM-003 | Solicitar análisis de símbolo | 8 | +| US-LLM-004 | Ver señales ML vía chat | 8 | +| US-LLM-005 | Estrategia personalizada | 5 | +| US-LLM-006 | Ver historial de estrategias | 5 | +| US-LLM-007 | Asistencia educativa | 5 | +| US-LLM-008 | Recomendaciones de aprendizaje | 3 | +| US-LLM-009 | Consultar datos vía chat | 3 | +| US-LLM-010 | Paper trading vía chat | 8 | +| US-LLM-011 | Ejecutar trade desde chat | 5 | + +### Requerimientos Funcionales (6) +- RF-LLM-001: Interfaz de Chat WebSocket +- RF-LLM-002: Análisis de Mercado vía LLM +- RF-LLM-003: Sugerencias de Estrategias +- RF-LLM-004: Asistencia Educativa +- RF-LLM-005: Integración de Tools (16 tools definidos) +- RF-LLM-006: Gestión de Contexto y Memoria --- ## Referencias -- [ET-LLM-001: Arquitectura](./especificaciones/ET-LLM-001-arquitectura.md) +- [ET-LLM-001: Arquitectura Chat](./especificaciones/ET-LLM-001-arquitectura-chat.md) +- [ET-LLM-007: Frontend](./especificaciones/ET-LLM-007-frontend.md) +- [TRACEABILITY.yml](./implementacion/TRACEABILITY.yml) - [TradingAgent SignalLogger](../../../apps/ml-engine/src/utils/signal_logger.py) - [OQI-006: ML Signals](../OQI-006-ml-signals/) diff --git a/docs/02-definicion-modulos/OQI-007-llm-agent/_MAP.md b/docs/02-definicion-modulos/OQI-007-llm-agent/_MAP.md index 2928f33..01f3346 100644 --- a/docs/02-definicion-modulos/OQI-007-llm-agent/_MAP.md +++ b/docs/02-definicion-modulos/OQI-007-llm-agent/_MAP.md @@ -3,14 +3,14 @@ id: "MAP-OQI-007-llm-agent" title: "Mapa de OQI-007-llm-agent" type: "Index" project: "trading-platform" -updated_date: "2026-01-04" +updated_date: "2026-01-28" --- # _MAP: OQI-007 - LLM Strategy Agent -**Última actualización:** 2025-12-05 -**Estado:** Planificado -**Versión:** 1.0.0 +**Última actualización:** 2026-01-28 +**Estado:** En Progreso (45%) +**Versión:** 1.1.0 --- @@ -24,23 +24,24 @@ Esta épica implementa un agente de IA conversacional basado en LLMs que interpr ``` OQI-007-llm-agent/ -├── README.md # Documentación técnica -├── _MAP.md # Este archivo - índice -├── requerimientos/ # Documentos de requerimientos funcionales ✅ +├── README.md # Documentación técnica principal +├── _MAP.md # Este archivo - índice completo +├── requerimientos/ # Documentos de requerimientos funcionales (6) │ ├── RF-LLM-001-chat-interface.md # ✅ Interfaz de chat WebSocket │ ├── RF-LLM-002-market-analysis.md # ✅ Análisis de mercado vía LLM │ ├── RF-LLM-003-strategy-suggestions.md # ✅ Sugerencias de estrategias │ ├── RF-LLM-004-educational-assistance.md # ✅ Asistencia educativa │ ├── RF-LLM-005-tool-integration.md # ✅ Integración de tools (16 tools) │ └── RF-LLM-006-context-management.md # ✅ Gestión de contexto y memoria -├── especificaciones/ # Especificaciones técnicas ✅ +├── especificaciones/ # Especificaciones técnicas (7) │ ├── ET-LLM-001-arquitectura-chat.md # ✅ Arquitectura WebSocket/Chat -│ ├── ET-LLM-002-agente-analisis.md # ✅ Agente de análisis +│ ├── ET-LLM-002-agente-analisis.md # ✅ Agente de análisis de mercado │ ├── ET-LLM-003-motor-estrategias.md # ✅ Motor de estrategias │ ├── ET-LLM-004-integracion-educacion.md # ✅ Integración educativa │ ├── ET-LLM-005-arquitectura-tools.md # ✅ Arquitectura de tools -│ └── ET-LLM-006-gestion-memoria.md # ✅ Gestión de memoria -├── historias-usuario/ # User Stories ✅ +│ ├── ET-LLM-006-gestion-memoria.md # ✅ Gestión de memoria +│ └── ET-LLM-007-frontend.md # ✅ Especificación Frontend completa +├── historias-usuario/ # User Stories (11) │ ├── US-LLM-001-enviar-mensaje.md # ✅ Enviar mensaje al agente │ ├── US-LLM-002-gestionar-conversaciones.md # ✅ Gestionar conversaciones │ ├── US-LLM-003-analisis-simbolo.md # ✅ Solicitar análisis de símbolo @@ -50,25 +51,26 @@ OQI-007-llm-agent/ │ ├── US-LLM-007-asistencia-educativa.md # ✅ Asistencia educativa │ ├── US-LLM-008-recomendaciones-aprendizaje.md # ✅ Recomendaciones │ ├── US-LLM-009-consultar-datos-chat.md # ✅ Consultar datos vía chat -│ └── US-LLM-010-paper-trading-chat.md # ✅ Paper trading vía chat +│ ├── US-LLM-010-paper-trading-chat.md # ✅ Paper trading vía chat +│ └── US-LLM-011-ejecutar-trade-desde-chat.md # ✅ Ejecutar trade desde chat └── implementacion/ # Trazabilidad - └── TRACEABILITY.yml + └── TRACEABILITY.yml # Mapeo req -> implementación ``` --- ## Requerimientos Funcionales -| ID | Nombre | Prioridad | SP | Estado | -|----|--------|-----------|-----|--------| -| RF-LLM-001 | Interfaz de Chat WebSocket | P0 | 8 | ✅ Documentado | -| RF-LLM-002 | Análisis de Mercado vía LLM | P0 | 10 | ✅ Documentado | -| RF-LLM-003 | Sugerencias de Estrategias | P0 | 10 | ✅ Documentado | -| RF-LLM-004 | Asistencia Educativa | P1 | 8 | ✅ Documentado | -| RF-LLM-005 | Integración de Tools | P1 | 8 | ✅ Documentado | -| RF-LLM-006 | Gestión de Contexto y Memoria | P2 | 11 | ✅ Documentado | +| ID | Nombre | Prioridad | SP | Doc | Impl | +|----|--------|-----------|-----|-----|------| +| RF-LLM-001 | Interfaz de Chat WebSocket | P0 | 8 | ✅ | 40% | +| RF-LLM-002 | Análisis de Mercado vía LLM | P0 | 10 | ✅ | 35% | +| RF-LLM-003 | Sugerencias de Estrategias | P0 | 10 | ✅ | 30% | +| RF-LLM-004 | Asistencia Educativa | P1 | 8 | ✅ | 25% | +| RF-LLM-005 | Integración de Tools | P1 | 8 | ✅ | 50% | +| RF-LLM-006 | Gestión de Contexto y Memoria | P2 | 11 | ✅ | 20% | -**Total:** 55 SP (100% documentados) +**Total:** 55 SP | Documentación: 100% | Implementación: ~45% --- @@ -76,14 +78,15 @@ OQI-007-llm-agent/ | ID | Nombre | Componente | Estado | |----|--------|------------|--------| -| ET-LLM-001 | Arquitectura Chat | WebSocket Gateway | ✅ Documentado | -| ET-LLM-002 | Agente de Análisis | LLM Engine | ✅ Documentado | -| ET-LLM-003 | Motor de Estrategias | Strategy Engine | ✅ Documentado | -| ET-LLM-004 | Integración Educativa | Education Module | ✅ Documentado | -| ET-LLM-005 | Arquitectura Tools | Tool Registry | ✅ Documentado | -| ET-LLM-006 | Gestión de Memoria | Context Manager | ✅ Documentado | +| ET-LLM-001 | Arquitectura Chat | WebSocket Gateway | ✅ Completa | +| ET-LLM-002 | Agente de Análisis | LLM Engine | ✅ Completa | +| ET-LLM-003 | Motor de Estrategias | Strategy Engine | ✅ Completa | +| ET-LLM-004 | Integración Educativa | Education Module | ✅ Completa | +| ET-LLM-005 | Arquitectura Tools | Tool Registry | ✅ Completa | +| ET-LLM-006 | Gestión de Memoria | Context Manager | ✅ Completa | +| ET-LLM-007 | Especificación Frontend | React Components | ✅ Completa | -**Total:** 6 ET (100% documentados) +**Total:** 7 ET (100% documentados) --- @@ -91,18 +94,19 @@ OQI-007-llm-agent/ | ID | Historia | Prioridad | SP | Estado | |----|----------|-----------|-----|--------| -| US-LLM-001 | Enviar mensaje al agente | P0 | 5 | ✅ Documentado | -| US-LLM-002 | Gestionar conversaciones | P0 | 5 | ✅ Documentado | -| US-LLM-003 | Solicitar análisis de símbolo | P0 | 8 | ✅ Documentado | -| US-LLM-004 | Ver señales ML vía chat | P1 | 8 | ✅ Documentado | -| US-LLM-005 | Estrategia personalizada | P1 | 5 | ✅ Documentado | -| US-LLM-006 | Ver historial de estrategias | P1 | 5 | ✅ Documentado | -| US-LLM-007 | Asistencia educativa | P1 | 5 | ✅ Documentado | -| US-LLM-008 | Recomendaciones de aprendizaje | P2 | 3 | ✅ Documentado | -| US-LLM-009 | Consultar datos vía chat | P2 | 3 | ✅ Documentado | -| US-LLM-010 | Paper trading vía chat | P2 | 8 | ✅ Documentado | +| US-LLM-001 | Enviar mensaje al agente | P0 | 5 | ✅ Completa | +| US-LLM-002 | Gestionar conversaciones | P0 | 5 | ✅ Completa | +| US-LLM-003 | Solicitar análisis de símbolo | P0 | 8 | ✅ Completa | +| US-LLM-004 | Ver señales ML vía chat | P1 | 8 | ✅ Completa | +| US-LLM-005 | Estrategia personalizada | P1 | 5 | ✅ Completa | +| US-LLM-006 | Ver historial de estrategias | P1 | 5 | ✅ Completa | +| US-LLM-007 | Asistencia educativa | P1 | 5 | ✅ Completa | +| US-LLM-008 | Recomendaciones de aprendizaje | P2 | 3 | ✅ Completa | +| US-LLM-009 | Consultar datos vía chat | P2 | 3 | ✅ Completa | +| US-LLM-010 | Paper trading vía chat | P2 | 8 | ✅ Completa | +| US-LLM-011 | Ejecutar trade desde chat | P0 | 5 | ✅ Completa | -**Total:** 55 SP (100% documentados) +**Total:** 60 SP (100% documentados, 11 historias) --- diff --git a/docs/02-definicion-modulos/OQI-007-llm-agent/implementacion/TRACEABILITY.yml b/docs/02-definicion-modulos/OQI-007-llm-agent/implementacion/TRACEABILITY.yml index 79d9655..e236303 100644 --- a/docs/02-definicion-modulos/OQI-007-llm-agent/implementacion/TRACEABILITY.yml +++ b/docs/02-definicion-modulos/OQI-007-llm-agent/implementacion/TRACEABILITY.yml @@ -1,20 +1,22 @@ # TRACEABILITY.yml - OQI-007 LLM Strategy Agent # Mapeo de requerimientos a implementación -version: "1.0.0" +version: "1.1.0" epic: OQI-007 name: "LLM Strategy Agent (Copilot)" -updated: "2025-12-05" -status: planned +updated: "2026-01-28" +status: in_progress # Resumen de trazabilidad summary: total_requirements: 6 - total_specs: 6 - total_user_stories: 10 - total_files_to_implement: 45 - test_coverage: "TBD" - story_points: 55 + total_specs: 7 + total_user_stories: 11 + total_files_to_implement: 48 + test_coverage: "15%" + story_points: 60 + implementation_progress: "45%" + documentation_progress: "100%" phase: 2 # Mapeo de Requerimientos Funcionales @@ -259,6 +261,16 @@ requirements: - ET-LLM-004 user_stories: - US-LLM-010 + + # Nueva: Trading Execution via Chat + RF-LLM-007: + name: "Trading Execution via Chat" + status: planned + specs: + - ET-LLM-005 + - ET-LLM-007 + user_stories: + - US-LLM-011 implementation: backend: - path: apps/backend/src/modules/copilot/services/context.service.ts diff --git a/docs/02-definicion-modulos/OQI-008-portfolio-manager/README.md b/docs/02-definicion-modulos/OQI-008-portfolio-manager/README.md index 33a9466..745fdc8 100644 --- a/docs/02-definicion-modulos/OQI-008-portfolio-manager/README.md +++ b/docs/02-definicion-modulos/OQI-008-portfolio-manager/README.md @@ -1,10 +1,10 @@ --- id: "README" -title: "Portfolio Manager (Gestión de Cartera a Largo Plazo)" +title: "Portfolio Manager (Gestion de Cartera a Largo Plazo)" type: "Documentation" project: "trading-platform" -version: "1.0.0" -updated_date: "2026-01-04" +version: "1.1.0" +updated_date: "2026-01-28" --- # OQI-008: Portfolio Manager (Gestión de Cartera a Largo Plazo) @@ -353,6 +353,24 @@ Usuario ## Referencias -- [ET-PFM-001: Arquitectura](./especificaciones/ET-PFM-001-arquitectura.md) +### Especificaciones Tecnicas Principales + +- [ET-PFM-010: Arquitectura General del Sistema](./especificaciones/ET-PFM-010-architecture.md) - Vision completa de arquitectura +- [ET-PFM-011: Sistema de Goals](./especificaciones/ET-PFM-011-goals-system.md) - Sistema completo de metas de inversion +- [ET-PFM-001: Arquitectura Dashboard](./especificaciones/ET-PFM-001-arquitectura-dashboard.md) +- [ET-PFM-002: Calculo de Metricas](./especificaciones/ET-PFM-002-calculo-metricas.md) +- [ET-PFM-003: Stress Testing](./especificaciones/ET-PFM-003-stress-testing.md) +- [ET-PFM-004: Motor de Rebalanceo](./especificaciones/ET-PFM-004-motor-rebalanceo.md) +- [ET-PFM-007: Motor de Metas](./especificaciones/ET-PFM-007-motor-metas.md) +- [ET-PFM-008: Frontend](./especificaciones/ET-PFM-008-frontend.md) +- [ET-PFM-009: Custom Charts SVG/Canvas](./especificaciones/ET-PFM-009-custom-charts-svg-canvas.md) + +### Epicas Relacionadas + - [OQI-004: Investment Accounts](../OQI-004-investment-accounts/) - [OQI-005: Payments](../OQI-005-payments-stripe/) + +### Documentacion Adicional + +- [_MAP.md](./_MAP.md) - Indice completo del modulo +- [TRACEABILITY.yml](./implementacion/TRACEABILITY.yml) - Trazabilidad de implementacion diff --git a/docs/02-definicion-modulos/OQI-008-portfolio-manager/_MAP.md b/docs/02-definicion-modulos/OQI-008-portfolio-manager/_MAP.md index 07bde42..fc56f27 100644 --- a/docs/02-definicion-modulos/OQI-008-portfolio-manager/_MAP.md +++ b/docs/02-definicion-modulos/OQI-008-portfolio-manager/_MAP.md @@ -3,14 +3,14 @@ id: "MAP-OQI-008-portfolio-manager" title: "Mapa de OQI-008-portfolio-manager" type: "Index" project: "trading-platform" -updated_date: "2026-01-04" +updated_date: "2026-01-28" --- # _MAP: OQI-008 - Portfolio Manager -**Última actualización:** 2025-12-05 -**Estado:** Planificado -**Versión:** 1.0.0 +**Ultima actualizacion:** 2026-01-28 +**Estado:** En Desarrollo (45% completado) +**Version:** 1.1.0 --- @@ -24,37 +24,43 @@ Esta épica implementa un sistema profesional de gestión de carteras a largo pl ``` OQI-008-portfolio-manager/ -├── README.md # Documentación técnica -├── _MAP.md # Este archivo - índice -├── requerimientos/ # Documentos de requerimientos funcionales ✅ -│ ├── RF-PFM-001-dashboard-portfolio.md # ✅ Dashboard del portfolio -│ ├── RF-PFM-002-analisis-riesgo.md # ✅ Análisis de riesgo (VaR, Sharpe) -│ ├── RF-PFM-003-rebalanceo.md # ✅ Rebalanceo automático -│ ├── RF-PFM-004-historial-transacciones.md # ✅ Historial de transacciones -│ ├── RF-PFM-005-comparacion-benchmark.md # ✅ Comparación vs benchmark -│ ├── RF-PFM-006-reportes-fiscales.md # ✅ Reportes fiscales -│ └── RF-PFM-007-metas-inversión.md # ✅ Metas de inversión -├── especificaciones/ # Especificaciones técnicas ✅ -│ ├── ET-PFM-001-arquitectura-dashboard.md # ✅ Arquitectura del dashboard -│ ├── ET-PFM-002-calculo-metricas.md # ✅ Cálculo de métricas -│ ├── ET-PFM-003-stress-testing.md # ✅ Stress testing -│ ├── ET-PFM-004-motor-rebalanceo.md # ✅ Motor de rebalanceo -│ ├── ET-PFM-005-historial-reportes.md # ✅ Historial y reportes -│ ├── ET-PFM-006-reportes-fiscales.md # ✅ Engine de reportes fiscales -│ └── ET-PFM-007-motor-metas.md # ✅ Motor de metas -├── historias-usuario/ # User Stories ✅ -│ ├── US-PFM-001-ver-resumen-portfolio.md # ✅ Ver resumen del portfolio -│ ├── US-PFM-002-ver-posiciones.md # ✅ Ver posiciones detalladas -│ ├── US-PFM-003-ver-metricas-riesgo.md # ✅ Ver métricas de riesgo -│ ├── US-PFM-004-ejecutar-stress-test.md # ✅ Ejecutar stress test -│ ├── US-PFM-005-configurar-asignacion.md # ✅ Configurar asignación -│ ├── US-PFM-006-ver-desviacion.md # ✅ Ver desviación de targets -│ ├── US-PFM-007-ejecutar-rebalanceo.md # ✅ Ejecutar rebalanceo -│ ├── US-PFM-008-ver-historial.md # ✅ Ver historial transacciones -│ ├── US-PFM-009-exportar-historial.md # ✅ Exportar historial -│ ├── US-PFM-010-comparar-benchmark.md # ✅ Comparar con benchmark -│ ├── US-PFM-011-metricas-benchmark.md # ✅ Métricas de benchmark -│ └── US-PFM-012-reporte-fiscal.md # ✅ Generar reporte fiscal +├── README.md # Documentacion tecnica principal +├── _MAP.md # Este archivo - indice +├── requerimientos/ # Documentos de requerimientos funcionales (7) +│ ├── RF-PFM-001-dashboard-portfolio.md # Dashboard del portfolio +│ ├── RF-PFM-002-analisis-riesgo.md # Analisis de riesgo (VaR, Sharpe) +│ ├── RF-PFM-003-rebalanceo.md # Rebalanceo automatico +│ ├── RF-PFM-004-historial-transacciones.md # Historial de transacciones +│ ├── RF-PFM-005-comparacion-benchmark.md # Comparacion vs benchmark +│ ├── RF-PFM-006-reportes-fiscales.md # Reportes fiscales +│ └── RF-PFM-007-metas-inversion.md # Metas de inversion +├── especificaciones/ # Especificaciones tecnicas (11) +│ ├── ET-PFM-001-arquitectura-dashboard.md # Arquitectura del dashboard +│ ├── ET-PFM-002-calculo-metricas.md # Calculo de metricas +│ ├── ET-PFM-003-stress-testing.md # Stress testing +│ ├── ET-PFM-004-motor-rebalanceo.md # Motor de rebalanceo +│ ├── ET-PFM-005-historial-reportes.md # Historial y reportes +│ ├── ET-PFM-006-reportes-fiscales.md # Engine de reportes fiscales +│ ├── ET-PFM-007-motor-metas.md # Motor de metas (entity) +│ ├── ET-PFM-008-frontend.md # Especificacion frontend +│ ├── ET-PFM-009-custom-charts-svg-canvas.md # Charts SVG + Canvas +│ ├── ET-PFM-010-architecture.md # **Arquitectura general sistema** +│ └── ET-PFM-011-goals-system.md # **Sistema completo de Goals** +├── historias-usuario/ # User Stories (14) +│ ├── US-PFM-001-ver-resumen-portfolio.md # Ver resumen del portfolio +│ ├── US-PFM-002-ver-posiciones.md # Ver posiciones detalladas +│ ├── US-PFM-003-ver-metricas-riesgo.md # Ver metricas de riesgo +│ ├── US-PFM-004-ejecutar-stress-test.md # Ejecutar stress test +│ ├── US-PFM-005-configurar-asignacion.md # Configurar asignacion +│ ├── US-PFM-006-ver-desviacion.md # Ver desviacion de targets +│ ├── US-PFM-007-ejecutar-rebalanceo.md # Ejecutar rebalanceo +│ ├── US-PFM-008-ver-historial.md # Ver historial transacciones +│ ├── US-PFM-009-exportar-historial.md # Exportar historial +│ ├── US-PFM-010-comparar-benchmark.md # Comparar con benchmark +│ ├── US-PFM-011-metricas-benchmark.md # Metricas de benchmark +│ ├── US-PFM-012-reporte-fiscal.md # Generar reporte fiscal +│ ├── US-PFM-013-alerta-rebalanceo.md # Alerta de rebalanceo +│ └── US-PFM-014-generar-pdf.md # Generar reporte PDF └── implementacion/ # Trazabilidad └── TRACEABILITY.yml ``` @@ -77,19 +83,23 @@ OQI-008-portfolio-manager/ --- -## Especificaciones Técnicas +## Especificaciones Tecnicas | ID | Nombre | Componente | Estado | |----|--------|------------|--------| -| ET-PFM-001 | Arquitectura Dashboard | Frontend | ✅ Documentado | -| ET-PFM-002 | Cálculo de Métricas | Backend | ✅ Documentado | -| ET-PFM-003 | Stress Testing | Risk Engine | ✅ Documentado | -| ET-PFM-004 | Motor de Rebalanceo | Backend | ✅ Documentado | -| ET-PFM-005 | Historial y Reportes | Backend | ✅ Documentado | -| ET-PFM-006 | Reportes Fiscales | Tax Engine | ✅ Documentado | -| ET-PFM-007 | Motor de Metas | Goals Engine | ✅ Documentado | +| ET-PFM-001 | Arquitectura Dashboard | Frontend | Documentado | +| ET-PFM-002 | Calculo de Metricas | Backend | Documentado | +| ET-PFM-003 | Stress Testing | Risk Engine | Documentado | +| ET-PFM-004 | Motor de Rebalanceo | Backend | Documentado | +| ET-PFM-005 | Historial y Reportes | Backend | Documentado | +| ET-PFM-006 | Reportes Fiscales | Tax Engine | Documentado | +| ET-PFM-007 | Motor de Metas (Entity) | Goals Engine | Documentado | +| ET-PFM-008 | Frontend Completo | Frontend | Documentado | +| ET-PFM-009 | Custom Charts SVG/Canvas | Frontend | Documentado | +| ET-PFM-010 | **Arquitectura General** | Sistema | **Documentado** | +| ET-PFM-011 | **Sistema de Goals Completo** | Goals Engine | **Documentado** | -**Total:** 7 ET (100% documentados) +**Total:** 11 ET (100% documentados) --- @@ -97,20 +107,22 @@ OQI-008-portfolio-manager/ | ID | Historia | Prioridad | SP | Estado | |----|----------|-----------|-----|--------| -| US-PFM-001 | Ver resumen del portfolio | P0 | 5 | ✅ Documentado | -| US-PFM-002 | Ver posiciones detalladas | P0 | 8 | ✅ Documentado | -| US-PFM-003 | Ver métricas de riesgo | P0 | 5 | ✅ Documentado | -| US-PFM-004 | Ejecutar stress test | P0 | 5 | ✅ Documentado | -| US-PFM-005 | Configurar asignación target | P0 | 8 | ✅ Documentado | -| US-PFM-006 | Ver desviación de targets | P1 | 5 | ✅ Documentado | -| US-PFM-007 | Ejecutar rebalanceo | P1 | 5 | ✅ Documentado | -| US-PFM-008 | Ver historial de transacciones | P1 | 3 | ✅ Documentado | -| US-PFM-009 | Exportar historial | P2 | 5 | ✅ Documentado | -| US-PFM-010 | Comparar con benchmark | P2 | 3 | ✅ Documentado | -| US-PFM-011 | Métricas de benchmark | P1 | 5 | ✅ Documentado | -| US-PFM-012 | Generar reporte fiscal | P2 | 8 | ✅ Documentado | +| US-PFM-001 | Ver resumen del portfolio | P0 | 5 | Documentado | +| US-PFM-002 | Ver posiciones detalladas | P0 | 8 | Documentado | +| US-PFM-003 | Ver metricas de riesgo | P0 | 5 | Documentado | +| US-PFM-004 | Ejecutar stress test | P0 | 5 | Documentado | +| US-PFM-005 | Configurar asignacion target | P0 | 8 | Documentado | +| US-PFM-006 | Ver desviacion de targets | P1 | 5 | Documentado | +| US-PFM-007 | Ejecutar rebalanceo | P1 | 5 | Documentado | +| US-PFM-008 | Ver historial de transacciones | P1 | 3 | Documentado | +| US-PFM-009 | Exportar historial | P2 | 5 | Documentado | +| US-PFM-010 | Comparar con benchmark | P2 | 3 | Documentado | +| US-PFM-011 | Metricas de benchmark | P1 | 5 | Documentado | +| US-PFM-012 | Generar reporte fiscal | P2 | 8 | Documentado | +| US-PFM-013 | Alerta de rebalanceo | P2 | 5 | Documentado | +| US-PFM-014 | Generar reporte PDF | P0 | 5 | Documentado | -**Total:** 65 SP (100% documentados) +**Total:** 75 SP (100% documentados) --- @@ -240,6 +252,18 @@ OQI-008-portfolio-manager/ ## Referencias - [README Principal](./README.md) +- [ET-PFM-010: Arquitectura General](./especificaciones/ET-PFM-010-architecture.md) +- [ET-PFM-011: Sistema de Goals](./especificaciones/ET-PFM-011-goals-system.md) - [OQI-004: Investment Accounts](../OQI-004-investment-accounts/) - [OQI-005: Payments](../OQI-005-payments-stripe/) - [Modern Portfolio Theory](https://en.wikipedia.org/wiki/Modern_portfolio_theory) + +--- + +## Historial de Cambios + +| Fecha | Version | Descripcion | +|-------|---------|-------------| +| 2025-12-05 | 1.0.0 | Documentacion inicial | +| 2026-01-25 | 1.0.1 | Agregados ET-PFM-008, ET-PFM-009, US-PFM-013, US-PFM-014 | +| 2026-01-28 | 1.1.0 | Agregados ET-PFM-010 (Arquitectura), ET-PFM-011 (Goals System) | diff --git a/docs/02-definicion-modulos/OQI-008-portfolio-manager/especificaciones/ET-PFM-010-architecture.md b/docs/02-definicion-modulos/OQI-008-portfolio-manager/especificaciones/ET-PFM-010-architecture.md new file mode 100644 index 0000000..3a15937 --- /dev/null +++ b/docs/02-definicion-modulos/OQI-008-portfolio-manager/especificaciones/ET-PFM-010-architecture.md @@ -0,0 +1,409 @@ +--- +id: "ET-PFM-010" +title: "Arquitectura General del Sistema Portfolio Manager" +type: "Technical Specification" +status: "Done" +priority: "Alta" +epic: "OQI-008" +project: "trading-platform" +version: "1.0.0" +created_date: "2026-01-28" +updated_date: "2026-01-28" +--- + +# ET-PFM-010: Arquitectura General del Sistema Portfolio Manager + +**Epica:** OQI-008 - Portfolio Manager +**Version:** 1.0 +**Fecha:** 2026-01-28 +**Estado:** Planificado + +--- + +## 1. Vision General + +El Portfolio Manager es un sistema integral de gestion de carteras de inversion a largo plazo que permite a los usuarios administrar multiples estrategias de inversion, realizar rebalanceo automatico, y proyectar metas financieras. + +### 1.1 Objetivos del Sistema + +| Objetivo | Descripcion | Metrica de Exito | +|----------|-------------|------------------| +| Multi-estrategia | Gestionar diferentes perfiles de riesgo | 5+ perfiles predefinidos | +| Optimizacion | Portfolio basado en Modern Portfolio Theory | Sharpe > benchmark | +| Rebalanceo | Automatizacion inteligente | Drift < 5% mantenido | +| Proyecciones | Simulaciones Monte Carlo | 10,000 escenarios | +| Reportes | Documentacion profesional | PDF, CSV, Excel | + +--- + +## 2. Arquitectura de Alto Nivel + +``` ++--------------------------------------------------------------------------------+ +| PORTFOLIO MANAGER SYSTEM | ++--------------------------------------------------------------------------------+ +| | +| +---------------------------------------------------------------------------+ | +| | PRESENTATION LAYER | | +| | +------------------+ +------------------+ +------------------------+ | | +| | | Portfolio | | Rebalance | | Goals & | | | +| | | Dashboard | | Interface | | Projections | | | +| | +------------------+ +------------------+ +------------------------+ | | +| | | | +| | +------------------+ +------------------+ +------------------------+ | | +| | | Risk Metrics | | Reports | | Stress Test | | | +| | | Panel | | Generator | | Simulator | | | +| | +------------------+ +------------------+ +------------------------+ | | +| +---------------------------------------------------------------------------+ | +| | | +| | REST API + WebSocket | +| v | +| +---------------------------------------------------------------------------+ | +| | BUSINESS LAYER | | +| | | | +| | +-------------------+ +-------------------+ +------------------+ | | +| | | Portfolio Service | | Metrics Service | | Goals Service | | | +| | | | | | | | | | +| | | - Summary | | - TWR/MWR | | - Create | | | +| | | - Positions | | - Sharpe/Sortino | | - Project | | | +| | | - History | | - VaR/CVaR | | - Track | | | +| | | - Snapshots | | - Drawdown | | - Simulate | | | +| | +-------------------+ +-------------------+ +------------------+ | | +| | | | +| | +-------------------+ +-------------------+ +------------------+ | | +| | | Rebalance Engine | | Stress Test | | Report Service | | | +| | | | | Engine | | | | | +| | | - Drift Detection | | - Scenarios | | - PDF Generator | | | +| | | - Plan Generator | | - Impact Calc | | - Tax Reports | | | +| | | - Executor | | - Monte Carlo | | - Export | | | +| | +-------------------+ +-------------------+ +------------------+ | | +| +---------------------------------------------------------------------------+ | +| | | +| | TypeORM / Prisma | +| v | +| +---------------------------------------------------------------------------+ | +| | DATA LAYER | | +| | | | +| | +-------------------+ +-------------------+ +------------------+ | | +| | | PostgreSQL | | Redis | | External APIs | | | +| | | | | | | | | | +| | | - portfolios | | - Session cache | | - Market Data | | | +| | | - positions | | - Metrics cache | | - Prices | | | +| | | - transactions | | - Rate limiting | | - Benchmarks | | | +| | | - goals | | - Real-time data | | - Economic | | | +| | | - risk_metrics | +-------------------+ +------------------+ | | +| | +-------------------+ | | +| +---------------------------------------------------------------------------+ | +| | ++--------------------------------------------------------------------------------+ +``` + +--- + +## 3. Componentes Principales + +### 3.1 Frontend (React + TypeScript) + +| Componente | Descripcion | Archivo | +|------------|-------------|---------| +| PortfolioDashboard | Vista principal del portfolio | `Portfolio.tsx` | +| PositionsTable | Tabla de posiciones | `PositionsTable.tsx` | +| AllocationChart | Grafico donut de asignacion | `AllocationChart.tsx` | +| PerformanceChart | Grafico de rendimiento | `PerformanceChart.tsx` | +| RiskMetricsPanel | Panel de metricas de riesgo | `RiskMetricsPanel.tsx` | +| RebalanceModal | Modal de rebalanceo | `RebalanceModal.tsx` | +| StressTestSimulator | Simulador de stress test | `StressTestSimulator.tsx` | +| GoalTracker | Seguimiento de metas | `GoalTracker.tsx` | +| ReportGenerator | Generador de reportes | `ReportGenerator.tsx` | + +### 3.2 Backend (Express.js + TypeScript) + +| Servicio | Responsabilidad | Endpoints | +|----------|-----------------|-----------| +| PortfolioService | CRUD de portfolios | `/api/portfolio/*` | +| PositionService | Gestion de posiciones | `/api/portfolio/positions/*` | +| MetricsService | Calculo de metricas | `/api/portfolio/metrics/*` | +| RebalanceService | Motor de rebalanceo | `/api/portfolio/rebalance/*` | +| GoalService | Gestion de metas | `/api/goals/*` | +| StressTestService | Stress testing | `/api/portfolio/stress-test/*` | +| ReportService | Generacion de reportes | `/api/portfolio/reports/*` | +| TaxReportService | Reportes fiscales | `/api/portfolio/tax/*` | + +### 3.3 Database (PostgreSQL) + +| Tabla | Descripcion | Relaciones | +|-------|-------------|------------| +| `portfolios` | Portfolios de usuarios | 1:N positions | +| `positions` | Posiciones activas | N:1 portfolio | +| `transactions` | Historial de transacciones | N:1 portfolio | +| `portfolio_snapshots` | Snapshots diarios | N:1 portfolio | +| `investment_goals` | Metas de inversion | N:1 user | +| `goal_contributions` | Contribuciones a metas | N:1 goal | +| `target_allocations` | Asignaciones objetivo | N:1 portfolio | +| `rebalance_history` | Historial de rebalanceo | N:1 portfolio | +| `risk_metrics` | Metricas de riesgo calculadas | N:1 portfolio | +| `stress_test_results` | Resultados de stress tests | N:1 portfolio | +| `reports` | Reportes generados | N:1 portfolio | + +--- + +## 4. Flujos de Datos + +### 4.1 Flujo de Carga del Dashboard + +``` +Usuario accede /portfolio + | + v +[Frontend] GET /api/portfolio/{id} + | + v +[PortfolioService] getPortfolioSummary() + | + +---> [PositionService] getPositions() + | + +---> [MetricsService] calculateMetrics() + | + +---> [Cache] Redis (TTL: 15s para precios) + | + v +[Response] PortfolioSummary + Positions + Metrics + | + v +[Frontend] Renderiza Dashboard + | + v +[WebSocket] Suscripcion a updates de precios +``` + +### 4.2 Flujo de Rebalanceo + +``` +Usuario solicita rebalanceo + | + v +[Frontend] GET /api/portfolio/rebalance/suggestions + | + v +[RebalanceService] calculateDeviation() + | + +---> Compara currentAllocation vs targetAllocation + | + +---> Calcula drift por cada activo + | + v +[RebalanceService] generatePlan() + | + +---> Determina ordenes: BUY/SELL + | + +---> Ordena: ventas primero (genera liquidez) + | + +---> Calcula costos estimados + | + v +[Response] RebalancePlan con ordenes sugeridas + | + v +[Frontend] Muestra preview al usuario + | + v +Usuario confirma + | + v +[Frontend] POST /api/portfolio/rebalance/execute + | + v +[RebalanceService] executePlan() + | + +---> [OrderService] createOrder() x N + | + v +[TransactionService] recordTransactions() + | + v +[Response] RebalanceResult (success/fail por orden) +``` + +### 4.3 Flujo de Proyeccion Monte Carlo + +``` +Usuario solicita proyeccion de meta + | + v +[Frontend] POST /api/goals/{id}/projection + | + v +[GoalProjectionService] calculateProjection() + | + +---> Obtiene parametros: + | - current_amount + | - monthly_contribution + | - expected_return + | - target_date + | + +---> Ejecuta simulacion Monte Carlo + | - 10,000 escenarios + | - Distribucion normal de retornos + | - Random walk + | + v +[Response] GoalProjection + | + +---> projectedValue + +---> probability_of_success + +---> percentiles (P10, P50, P90) + +---> requiredContribution (para alcanzar meta) + | + v +[Frontend] Renderiza grafico de proyeccion +``` + +--- + +## 5. Integraciones Externas + +### 5.1 Market Data Providers + +| Proveedor | Uso | Frecuencia | +|-----------|-----|------------| +| Binance API | Precios crypto | Real-time | +| Alpha Vantage | Datos fundamentales | Diario | +| Yahoo Finance | Benchmarks | Diario | +| TradingView (futuro) | Charts avanzados | Real-time | + +### 5.2 Servicios Internos + +| Servicio | Puerto | Integracion | +|----------|--------|-------------| +| MCP-Investment | 3093 | Cuentas de inversion | +| MCP-Wallet | 3090 | Balance de wallet | +| MCP-Auth | 3095 | Autenticacion | +| ML-Engine | 3083 | Predicciones (futuro) | + +--- + +## 6. Seguridad + +### 6.1 Autenticacion y Autorizacion + +- JWT Bearer tokens +- Refresh token rotation +- Rate limiting: 100 req/min por usuario +- Verificacion de ownership en cada request + +### 6.2 Validacion de Datos + +```typescript +// Ejemplo: validacion de orden de rebalanceo +const RebalanceOrderSchema = z.object({ + portfolioId: z.string().uuid(), + orders: z.array(z.object({ + symbol: z.string().min(1).max(10), + action: z.enum(['BUY', 'SELL']), + amount: z.number().positive().max(1000000), + })), + dryRun: z.boolean().default(false), +}); +``` + +### 6.3 Audit Trail + +- Todas las transacciones registradas +- Logs de acceso a datos sensibles +- Historial de cambios de configuracion + +--- + +## 7. Escalabilidad + +### 7.1 Caching Strategy + +| Dato | TTL | Estrategia | +|------|-----|------------| +| Precios | 15s | Write-through | +| Metricas basicas | 1 min | Lazy load | +| Metricas avanzadas | 1 hora | Background job | +| Snapshots | 24 horas | Scheduled job | + +### 7.2 Background Jobs + +| Job | Frecuencia | Descripcion | +|-----|------------|-------------| +| SnapshotJob | Diario 00:00 UTC | Captura estado del portfolio | +| MetricsJob | Cada 1 hora | Recalcula metricas avanzadas | +| AlertsJob | Cada 5 min | Verifica drift y envia alertas | +| ReportJob | Bajo demanda | Genera reportes PDF | + +--- + +## 8. Metricas de Rendimiento + +### 8.1 SLAs + +| Operacion | Target | Max | +|-----------|--------|-----| +| Dashboard load | < 1s | 2s | +| Calculo de metricas | < 500ms | 1s | +| Simulacion Monte Carlo | < 3s | 5s | +| Generacion de PDF | < 10s | 30s | + +### 8.2 Limites del Sistema + +| Recurso | Limite | Razon | +|---------|--------|-------| +| Posiciones por portfolio | 100 | Performance de calculos | +| Escenarios Monte Carlo | 10,000 | Balance precision/tiempo | +| Historial de transacciones | 10,000 | Paginacion requerida | +| Tamanio de reporte PDF | 10 MB | Limite de descarga | + +--- + +## 9. Stack Tecnologico Detallado + +### 9.1 Frontend + +| Tecnologia | Version | Uso | +|------------|---------|-----| +| React | 18.x | Framework UI | +| TypeScript | 5.x | Tipado estatico | +| Zustand | 4.x | State management | +| TanStack Query | 5.x | Data fetching | +| Recharts | 2.x | Graficos | +| TailwindCSS | 3.x | Estilos | +| Zod | 3.x | Validacion schemas | + +### 9.2 Backend + +| Tecnologia | Version | Uso | +|------------|---------|-----| +| Node.js | 20.x LTS | Runtime | +| Express.js | 5.x | Framework HTTP | +| TypeScript | 5.x | Tipado estatico | +| TypeORM | 0.3.x | ORM | +| Bull | 4.x | Job queues | +| Node-cron | 3.x | Scheduled jobs | +| PDFKit | 0.14.x | Generacion PDF | + +### 9.3 Infraestructura + +| Tecnologia | Version | Uso | +|------------|---------|-----| +| PostgreSQL | 16.x | Database principal | +| Redis | 7.x | Cache + queues | +| Docker | 24.x | Contenedores | +| Nginx | 1.25.x | Reverse proxy | + +--- + +## 10. Referencias + +- [ET-PFM-001: Arquitectura Dashboard](./ET-PFM-001-arquitectura-dashboard.md) +- [ET-PFM-002: Calculo de Metricas](./ET-PFM-002-calculo-metricas.md) +- [ET-PFM-003: Stress Testing](./ET-PFM-003-stress-testing.md) +- [ET-PFM-004: Motor de Rebalanceo](./ET-PFM-004-motor-rebalanceo.md) +- [ET-PFM-007: Motor de Metas](./ET-PFM-007-motor-metas.md) +- [TRACEABILITY.yml](../implementacion/TRACEABILITY.yml) + +--- + +*Especificacion tecnica - Sistema NEXUS* diff --git a/docs/02-definicion-modulos/OQI-008-portfolio-manager/especificaciones/ET-PFM-011-goals-system.md b/docs/02-definicion-modulos/OQI-008-portfolio-manager/especificaciones/ET-PFM-011-goals-system.md new file mode 100644 index 0000000..b8624e5 --- /dev/null +++ b/docs/02-definicion-modulos/OQI-008-portfolio-manager/especificaciones/ET-PFM-011-goals-system.md @@ -0,0 +1,874 @@ +--- +id: "ET-PFM-011" +title: "Sistema de Goals (Metas de Inversion)" +type: "Technical Specification" +status: "Done" +priority: "Alta" +epic: "OQI-008" +project: "trading-platform" +version: "1.0.0" +created_date: "2026-01-28" +updated_date: "2026-01-28" +--- + +# ET-PFM-011: Sistema de Goals (Metas de Inversion) + +**Epica:** OQI-008 - Portfolio Manager +**Version:** 1.0 +**Fecha:** 2026-01-28 +**Estado:** Planificado + +--- + +## 1. Vision General + +El Sistema de Goals permite a los usuarios definir, seguir y proyectar metas financieras a largo plazo como retiro, compra de casa, educacion de hijos, etc. Integra simulaciones Monte Carlo para proyectar probabilidades de exito. + +### 1.1 Tipos de Metas Soportadas + +| Tipo | Icono | Descripcion | Horizonte Tipico | +|------|-------|-------------|------------------| +| `retirement` | 🏖️ | Retiro/Jubilacion | 10-30 anos | +| `home` | 🏠 | Compra de casa/enganche | 2-10 anos | +| `education` | 🎓 | Educacion de hijos | 5-18 anos | +| `emergency` | 🚨 | Fondo de emergencia | 1-2 anos | +| `travel` | ✈️ | Viaje mayor | 1-5 anos | +| `vehicle` | 🚗 | Compra de vehiculo | 1-5 anos | +| `wedding` | 💍 | Boda/evento | 1-3 anos | +| `custom` | 🎯 | Meta personalizada | Variable | + +--- + +## 2. Modelo de Datos + +### 2.1 Entity: InvestmentGoal + +```typescript +@Entity('investment_goals') +export class InvestmentGoal { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ name: 'user_id' }) + @Index() + userId: string; + + @Column({ length: 100 }) + name: string; + + @Column({ length: 500, nullable: true }) + description: string; + + @Column({ + type: 'enum', + enum: GoalType, + default: GoalType.CUSTOM, + }) + type: GoalType; + + @Column('decimal', { precision: 18, scale: 2, name: 'target_amount' }) + targetAmount: number; + + @Column('decimal', { precision: 18, scale: 2, name: 'current_amount', default: 0 }) + currentAmount: number; + + @Column('decimal', { precision: 18, scale: 2, name: 'initial_amount', default: 0 }) + initialAmount: number; + + @Column('decimal', { precision: 18, scale: 2, name: 'monthly_contribution', default: 0 }) + monthlyContribution: number; + + @Column({ name: 'target_date', type: 'date' }) + targetDate: Date; + + @Column('decimal', { precision: 5, scale: 2, name: 'expected_return', default: 7.0 }) + expectedReturn: number; // Annual return % + + @Column('decimal', { precision: 5, scale: 2, name: 'expected_volatility', default: 15.0 }) + expectedVolatility: number; // Annual volatility % + + @Column({ + type: 'enum', + enum: GoalStatus, + default: GoalStatus.ON_TRACK, + }) + status: GoalStatus; + + @Column({ + type: 'enum', + enum: GoalPriority, + default: GoalPriority.MEDIUM, + }) + priority: GoalPriority; + + @Column({ name: 'linked_account_id', type: 'uuid', nullable: true }) + linkedAccountId: string | null; + + @Column({ name: 'is_active', default: true }) + isActive: boolean; + + @Column('jsonb', { name: 'risk_profile', nullable: true }) + riskProfile: GoalRiskProfile | null; + + @Column('jsonb', { name: 'last_projection', nullable: true }) + lastProjection: GoalProjection | null; + + @CreateDateColumn({ name: 'created_at' }) + createdAt: Date; + + @UpdateDateColumn({ name: 'updated_at' }) + updatedAt: Date; + + @OneToMany(() => GoalContribution, (c) => c.goal) + contributions: GoalContribution[]; + + @OneToMany(() => GoalMilestone, (m) => m.goal) + milestones: GoalMilestone[]; +} +``` + +### 2.2 Enums + +```typescript +enum GoalType { + RETIREMENT = 'retirement', + HOME = 'home', + EDUCATION = 'education', + EMERGENCY = 'emergency', + TRAVEL = 'travel', + VEHICLE = 'vehicle', + WEDDING = 'wedding', + CUSTOM = 'custom', +} + +enum GoalStatus { + ON_TRACK = 'on_track', + AHEAD = 'ahead', + BEHIND = 'behind', + AT_RISK = 'at_risk', + ACHIEVED = 'achieved', + PAUSED = 'paused', +} + +enum GoalPriority { + HIGH = 'high', + MEDIUM = 'medium', + LOW = 'low', +} +``` + +### 2.3 Entity: GoalContribution + +```typescript +@Entity('goal_contributions') +export class GoalContribution { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ name: 'goal_id' }) + goalId: string; + + @ManyToOne(() => InvestmentGoal, (g) => g.contributions) + @JoinColumn({ name: 'goal_id' }) + goal: InvestmentGoal; + + @Column('decimal', { precision: 18, scale: 2 }) + amount: number; + + @Column({ + type: 'enum', + enum: ContributionType, + default: ContributionType.DEPOSIT, + }) + type: ContributionType; + + @Column({ nullable: true }) + source: string; // 'manual', 'automatic', 'dividend', 'interest' + + @Column({ type: 'text', nullable: true }) + notes: string; + + @Column({ name: 'transaction_id', nullable: true }) + transactionId: string; + + @CreateDateColumn({ name: 'contributed_at' }) + contributedAt: Date; +} + +enum ContributionType { + DEPOSIT = 'deposit', + WITHDRAWAL = 'withdrawal', + INTEREST = 'interest', + DIVIDEND = 'dividend', + ADJUSTMENT = 'adjustment', +} +``` + +### 2.4 Entity: GoalMilestone + +```typescript +@Entity('goal_milestones') +export class GoalMilestone { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ name: 'goal_id' }) + goalId: string; + + @ManyToOne(() => InvestmentGoal, (g) => g.milestones) + @JoinColumn({ name: 'goal_id' }) + goal: InvestmentGoal; + + @Column({ length: 100 }) + name: string; + + @Column('decimal', { precision: 18, scale: 2, name: 'target_amount' }) + targetAmount: number; + + @Column('decimal', { precision: 5, scale: 2, name: 'target_percentage' }) + targetPercentage: number; // % of goal + + @Column({ name: 'target_date', type: 'date', nullable: true }) + targetDate: Date | null; + + @Column({ name: 'achieved_at', type: 'timestamp', nullable: true }) + achievedAt: Date | null; + + @Column({ default: false }) + isAchieved: boolean; + + @CreateDateColumn({ name: 'created_at' }) + createdAt: Date; +} +``` + +--- + +## 3. Interfaces de Proyeccion + +### 3.1 GoalProjection + +```typescript +interface GoalProjection { + // Metadata + goalId: string; + calculatedAt: Date; + + // Current State + currentAmount: number; + targetAmount: number; + progressPercent: number; + monthsRemaining: number; + + // Projections + projectedValue: number; + projectedProgress: number; + shortfall: number; + + // Probability Analysis + probabilityOfSuccess: number; + confidenceInterval: { + low: number; // P10 + mid: number; // P50 (median) + high: number; // P90 + }; + + // Scenarios + scenarios: GoalScenarios; + + // Recommendations + requiredMonthlyContribution: number; + suggestedActions: string[]; +} + +interface GoalScenarios { + optimistic: ScenarioResult; + base: ScenarioResult; + pessimistic: ScenarioResult; +} + +interface ScenarioResult { + projectedValue: number; + endDate: Date; + returnRate: number; + probabilityOfSuccess: number; +} +``` + +### 3.2 MonteCarloParams + +```typescript +interface MonteCarloParams { + initialAmount: number; + monthlyContribution: number; + expectedReturn: number; // Annual, e.g., 0.07 for 7% + volatility: number; // Annual, e.g., 0.15 for 15% + months: number; + numSimulations: number; // Default: 10000 + targetAmount: number; +} + +interface MonteCarloResult { + simulations: number[][]; // [sim][month] + finalValues: number[]; // Final value per simulation + percentiles: { + p10: number; + p25: number; + p50: number; + p75: number; + p90: number; + p95: number; + }; + probabilityOfSuccess: number; + averageFinalValue: number; + medianFinalValue: number; +} +``` + +--- + +## 4. Servicio de Goals + +### 4.1 GoalService + +```typescript +@Injectable() +export class GoalService { + constructor( + @InjectRepository(InvestmentGoal) + private goalRepo: Repository, + @InjectRepository(GoalContribution) + private contributionRepo: Repository, + private projectionService: GoalProjectionService, + private eventEmitter: EventEmitter2, + ) {} + + async createGoal(dto: CreateGoalDto): Promise { + const goal = this.goalRepo.create({ + ...dto, + status: GoalStatus.ON_TRACK, + currentAmount: dto.initialAmount || 0, + }); + + // Create default milestones + goal.milestones = this.createDefaultMilestones(goal); + + const saved = await this.goalRepo.save(goal); + + // Calculate initial projection + const projection = await this.projectionService.calculateProjection(saved); + saved.lastProjection = projection; + saved.status = this.determineStatus(projection); + + await this.goalRepo.save(saved); + this.eventEmitter.emit('goal.created', saved); + + return saved; + } + + async addContribution( + goalId: string, + dto: AddContributionDto + ): Promise { + const goal = await this.getGoalById(goalId); + + const contribution = this.contributionRepo.create({ + goalId, + ...dto, + }); + + await this.contributionRepo.save(contribution); + + // Update goal current amount + const delta = dto.type === ContributionType.WITHDRAWAL + ? -dto.amount + : dto.amount; + + goal.currentAmount = Number(goal.currentAmount) + delta; + + // Recalculate projection + const projection = await this.projectionService.calculateProjection(goal); + goal.lastProjection = projection; + goal.status = this.determineStatus(projection); + + // Check milestones + await this.checkMilestones(goal); + + await this.goalRepo.save(goal); + this.eventEmitter.emit('goal.contribution.added', { goal, contribution }); + + return contribution; + } + + async getGoalsByUser(userId: string): Promise { + return this.goalRepo.find({ + where: { userId, isActive: true }, + relations: ['contributions', 'milestones'], + order: { priority: 'ASC', targetDate: 'ASC' }, + }); + } + + async getGoalProgress(goalId: string): Promise { + const goal = await this.getGoalById(goalId); + const projection = await this.projectionService.calculateProjection(goal); + + const contributions = await this.contributionRepo.find({ + where: { goalId }, + order: { contributedAt: 'DESC' }, + take: 12, // Last 12 contributions + }); + + return { + goal, + projection, + contributions, + milestones: goal.milestones.map(m => ({ + ...m, + progress: (goal.currentAmount / m.targetAmount) * 100, + })), + }; + } + + private createDefaultMilestones(goal: InvestmentGoal): GoalMilestone[] { + return [ + { name: '25% alcanzado', targetPercentage: 25, targetAmount: goal.targetAmount * 0.25 }, + { name: '50% alcanzado', targetPercentage: 50, targetAmount: goal.targetAmount * 0.50 }, + { name: '75% alcanzado', targetPercentage: 75, targetAmount: goal.targetAmount * 0.75 }, + { name: 'Meta completada', targetPercentage: 100, targetAmount: goal.targetAmount }, + ].map(m => this.milestoneRepo.create({ ...m, goalId: goal.id })); + } + + private determineStatus(projection: GoalProjection): GoalStatus { + if (projection.probabilityOfSuccess >= 95) return GoalStatus.AHEAD; + if (projection.probabilityOfSuccess >= 75) return GoalStatus.ON_TRACK; + if (projection.probabilityOfSuccess >= 50) return GoalStatus.BEHIND; + return GoalStatus.AT_RISK; + } +} +``` + +--- + +## 5. Servicio de Proyeccion + +### 5.1 GoalProjectionService + +```typescript +@Injectable() +export class GoalProjectionService { + + async calculateProjection(goal: InvestmentGoal): Promise { + const monthsRemaining = this.getMonthsRemaining(goal.targetDate); + + // Deterministic projection (Future Value formula) + const projectedValue = this.calculateFutureValue( + goal.currentAmount, + goal.monthlyContribution, + goal.expectedReturn / 100 / 12, // Monthly rate + monthsRemaining + ); + + // Monte Carlo simulation + const mcResult = await this.runMonteCarloSimulation({ + initialAmount: Number(goal.currentAmount), + monthlyContribution: Number(goal.monthlyContribution), + expectedReturn: goal.expectedReturn / 100, + volatility: goal.expectedVolatility / 100, + months: monthsRemaining, + numSimulations: 10000, + targetAmount: Number(goal.targetAmount), + }); + + const progressPercent = (goal.currentAmount / goal.targetAmount) * 100; + const projectedProgress = (projectedValue / goal.targetAmount) * 100; + + return { + goalId: goal.id, + calculatedAt: new Date(), + + currentAmount: Number(goal.currentAmount), + targetAmount: Number(goal.targetAmount), + progressPercent, + monthsRemaining, + + projectedValue, + projectedProgress, + shortfall: Math.max(0, Number(goal.targetAmount) - projectedValue), + + probabilityOfSuccess: mcResult.probabilityOfSuccess, + confidenceInterval: { + low: mcResult.percentiles.p10, + mid: mcResult.percentiles.p50, + high: mcResult.percentiles.p90, + }, + + scenarios: this.calculateScenarios(goal, monthsRemaining), + + requiredMonthlyContribution: this.calculateRequiredContribution(goal), + suggestedActions: this.generateSuggestions(goal, mcResult.probabilityOfSuccess), + }; + } + + /** + * Future Value with regular deposits + * FV = PV(1+r)^n + PMT × ((1+r)^n - 1) / r + */ + private calculateFutureValue( + presentValue: number, + monthlyPayment: number, + monthlyRate: number, + months: number + ): number { + if (monthlyRate === 0) { + return presentValue + monthlyPayment * months; + } + + const growthFactor = Math.pow(1 + monthlyRate, months); + const fvOfPresentValue = presentValue * growthFactor; + const fvOfPayments = monthlyPayment * ((growthFactor - 1) / monthlyRate); + + return fvOfPresentValue + fvOfPayments; + } + + /** + * Monte Carlo Simulation + * Geometric Brownian Motion: S(t+1) = S(t) * exp((mu - sigma^2/2)*dt + sigma*sqrt(dt)*Z) + */ + async runMonteCarloSimulation(params: MonteCarloParams): Promise { + const { initialAmount, monthlyContribution, expectedReturn, volatility, months, numSimulations, targetAmount } = params; + + const monthlyReturn = expectedReturn / 12; + const monthlyVolatility = volatility / Math.sqrt(12); + const dt = 1; // 1 month + + const simulations: number[][] = []; + const finalValues: number[] = []; + + for (let sim = 0; sim < numSimulations; sim++) { + const path: number[] = [initialAmount]; + let value = initialAmount; + + for (let month = 1; month <= months; month++) { + // Random normal (Box-Muller transform) + const z = this.randomNormal(); + + // GBM step + const drift = (monthlyReturn - 0.5 * monthlyVolatility ** 2) * dt; + const diffusion = monthlyVolatility * Math.sqrt(dt) * z; + value = value * Math.exp(drift + diffusion) + monthlyContribution; + + path.push(Math.max(0, value)); // No negative values + } + + simulations.push(path); + finalValues.push(path[path.length - 1]); + } + + // Sort for percentile calculation + const sorted = [...finalValues].sort((a, b) => a - b); + + const percentile = (p: number) => sorted[Math.floor(p * numSimulations)]; + + const successCount = finalValues.filter(v => v >= targetAmount).length; + + return { + simulations, + finalValues, + percentiles: { + p10: percentile(0.10), + p25: percentile(0.25), + p50: percentile(0.50), + p75: percentile(0.75), + p90: percentile(0.90), + p95: percentile(0.95), + }, + probabilityOfSuccess: (successCount / numSimulations) * 100, + averageFinalValue: finalValues.reduce((a, b) => a + b, 0) / numSimulations, + medianFinalValue: percentile(0.50), + }; + } + + /** + * Box-Muller transform for normal distribution + */ + private randomNormal(): number { + const u1 = Math.random(); + const u2 = Math.random(); + return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2); + } + + /** + * Calculate required monthly contribution to reach target + * PMT = (FV - PV(1+r)^n) × r / ((1+r)^n - 1) + */ + calculateRequiredContribution(goal: InvestmentGoal): number { + const months = this.getMonthsRemaining(goal.targetDate); + const monthlyRate = goal.expectedReturn / 100 / 12; + + if (months <= 0) return 0; + if (monthlyRate === 0) { + return (Number(goal.targetAmount) - Number(goal.currentAmount)) / months; + } + + const growthFactor = Math.pow(1 + monthlyRate, months); + const fvOfCurrent = Number(goal.currentAmount) * growthFactor; + const remaining = Number(goal.targetAmount) - fvOfCurrent; + + if (remaining <= 0) return 0; + + const factor = (growthFactor - 1) / monthlyRate; + return remaining / factor; + } + + private calculateScenarios(goal: InvestmentGoal, months: number): GoalScenarios { + return { + optimistic: this.projectWithReturn(goal, months, goal.expectedReturn + 3), + base: this.projectWithReturn(goal, months, goal.expectedReturn), + pessimistic: this.projectWithReturn(goal, months, goal.expectedReturn - 3), + }; + } + + private projectWithReturn(goal: InvestmentGoal, months: number, annualReturn: number): ScenarioResult { + const monthlyRate = annualReturn / 100 / 12; + const projectedValue = this.calculateFutureValue( + Number(goal.currentAmount), + Number(goal.monthlyContribution), + monthlyRate, + months + ); + + return { + projectedValue, + endDate: goal.targetDate, + returnRate: annualReturn, + probabilityOfSuccess: projectedValue >= Number(goal.targetAmount) ? 100 : (projectedValue / Number(goal.targetAmount)) * 100, + }; + } + + private generateSuggestions(goal: InvestmentGoal, probability: number): string[] { + const suggestions: string[] = []; + + if (probability < 50) { + const required = this.calculateRequiredContribution(goal); + const increase = required - Number(goal.monthlyContribution); + if (increase > 0) { + suggestions.push(`Incrementar aportacion mensual en $${increase.toFixed(0)} para alcanzar meta`); + } + suggestions.push('Considerar extender la fecha objetivo'); + suggestions.push('Evaluar perfil de riesgo para mayor rendimiento esperado'); + } else if (probability < 75) { + suggestions.push('Meta en riesgo. Considerar aumentar aportaciones'); + } else if (probability < 95) { + suggestions.push('Meta en buen camino. Mantener aportaciones actuales'); + } else { + suggestions.push('Excelente progreso! Meta muy probable de alcanzar'); + } + + return suggestions; + } + + private getMonthsRemaining(targetDate: Date): number { + const now = new Date(); + const target = new Date(targetDate); + return Math.max(0, (target.getFullYear() - now.getFullYear()) * 12 + + (target.getMonth() - now.getMonth())); + } +} +``` + +--- + +## 6. API Endpoints + +### 6.1 Goals CRUD + +| Method | Endpoint | Descripcion | +|--------|----------|-------------| +| GET | `/api/goals` | Lista de metas del usuario | +| POST | `/api/goals` | Crear nueva meta | +| GET | `/api/goals/:id` | Detalle de meta | +| PUT | `/api/goals/:id` | Actualizar meta | +| DELETE | `/api/goals/:id` | Eliminar meta | +| PATCH | `/api/goals/:id/pause` | Pausar meta | +| PATCH | `/api/goals/:id/resume` | Reanudar meta | + +### 6.2 Contributions + +| Method | Endpoint | Descripcion | +|--------|----------|-------------| +| GET | `/api/goals/:id/contributions` | Historial de contribuciones | +| POST | `/api/goals/:id/contributions` | Agregar contribucion | + +### 6.3 Projections & Analytics + +| Method | Endpoint | Descripcion | +|--------|----------|-------------| +| GET | `/api/goals/:id/progress` | Progreso con proyeccion | +| GET | `/api/goals/:id/projection` | Proyeccion Monte Carlo | +| POST | `/api/goals/:id/simulate` | Simular escenarios custom | +| GET | `/api/goals/:id/milestones` | Estado de milestones | + +--- + +## 7. Componentes Frontend + +### 7.1 GoalDashboard + +```typescript +interface GoalDashboardProps { + userId: string; +} + +// Componentes hijos: +// - GoalSummaryCard: Resumen de todas las metas +// - GoalList: Lista de metas con progreso +// - AddGoalButton: Crear nueva meta +``` + +### 7.2 GoalCard + +```typescript +interface GoalCardProps { + goal: InvestmentGoal; + onEdit: () => void; + onContribute: () => void; +} + +// Muestra: +// - Nombre e icono del tipo +// - Barra de progreso visual +// - Monto actual / objetivo +// - Fecha objetivo +// - Estado (on_track, behind, etc.) +// - Probabilidad de exito +``` + +### 7.3 GoalProjectionChart + +```typescript +interface GoalProjectionChartProps { + projection: GoalProjection; + height?: number; +} + +// Grafico que muestra: +// - Linea de progreso actual +// - Bandas de confianza (P10, P50, P90) +// - Linea objetivo +// - Fecha objetivo +``` + +### 7.4 GoalWizard + +```typescript +interface GoalWizardProps { + onComplete: (goal: InvestmentGoal) => void; +} + +// Pasos: +// 1. Seleccionar tipo de meta +// 2. Definir nombre y monto objetivo +// 3. Fecha objetivo +// 4. Aportacion mensual inicial +// 5. Perfil de riesgo (conservador/moderado/agresivo) +// 6. Confirmar y ver proyeccion inicial +``` + +--- + +## 8. Configuraciones por Tipo de Meta + +### 8.1 Defaults por Tipo + +```typescript +const GOAL_DEFAULTS: Record = { + retirement: { + expectedReturn: 7.0, + expectedVolatility: 12.0, + suggestedHorizon: '20+ years', + riskProfile: 'moderate', + }, + home: { + expectedReturn: 5.0, + expectedVolatility: 8.0, + suggestedHorizon: '3-7 years', + riskProfile: 'conservative', + }, + education: { + expectedReturn: 6.0, + expectedVolatility: 10.0, + suggestedHorizon: '5-18 years', + riskProfile: 'moderate', + }, + emergency: { + expectedReturn: 2.0, + expectedVolatility: 2.0, + suggestedHorizon: '6-12 months', + riskProfile: 'conservative', + }, + travel: { + expectedReturn: 4.0, + expectedVolatility: 5.0, + suggestedHorizon: '1-3 years', + riskProfile: 'conservative', + }, + vehicle: { + expectedReturn: 4.0, + expectedVolatility: 6.0, + suggestedHorizon: '1-5 years', + riskProfile: 'conservative', + }, + wedding: { + expectedReturn: 3.0, + expectedVolatility: 4.0, + suggestedHorizon: '1-3 years', + riskProfile: 'conservative', + }, + custom: { + expectedReturn: 5.0, + expectedVolatility: 10.0, + suggestedHorizon: 'Variable', + riskProfile: 'moderate', + }, +}; +``` + +--- + +## 9. Notificaciones y Alertas + +### 9.1 Eventos de Notificacion + +| Evento | Trigger | Canal | +|--------|---------|-------| +| `goal.milestone.reached` | Progreso >= milestone % | Push, Email | +| `goal.status.changed` | Status cambia a behind/at_risk | Push, Email | +| `goal.achieved` | Monto actual >= objetivo | Push, Email, Celebracion UI | +| `goal.contribution.reminder` | Dia de aportacion programada | Push | +| `goal.review.monthly` | Primer dia del mes | Email digest | + +### 9.2 Configuracion de Alertas + +```typescript +interface GoalAlertSettings { + goalId: string; + milestoneAlerts: boolean; + statusChangeAlerts: boolean; + contributionReminders: boolean; + reminderDayOfMonth: number; // 1-28 + channels: ('push' | 'email' | 'sms')[]; +} +``` + +--- + +## 10. Referencias + +- [ET-PFM-007: Motor de Metas](./ET-PFM-007-motor-metas.md) +- [RF-PFM-007: Metas de Inversion](../requerimientos/RF-PFM-007-metas-inversion.md) +- [US-PFM-012: Reporte Fiscal](../historias-usuario/US-PFM-012-reporte-fiscal.md) +- [TRACEABILITY.yml](../implementacion/TRACEABILITY.yml) + +--- + +*Especificacion tecnica - Sistema NEXUS* diff --git a/docs/02-definicion-modulos/OQI-008-portfolio-manager/implementacion/TRACEABILITY.yml b/docs/02-definicion-modulos/OQI-008-portfolio-manager/implementacion/TRACEABILITY.yml index 7f24f6d..831d21a 100644 --- a/docs/02-definicion-modulos/OQI-008-portfolio-manager/implementacion/TRACEABILITY.yml +++ b/docs/02-definicion-modulos/OQI-008-portfolio-manager/implementacion/TRACEABILITY.yml @@ -1,21 +1,35 @@ # TRACEABILITY.yml - OQI-008 Portfolio Manager -# Mapeo de requerimientos a implementación +# Mapeo de requerimientos a implementacion -version: "1.0.0" +version: "1.1.0" epic: OQI-008 name: "Portfolio Manager Avanzado" -updated: "2025-12-05" +updated: "2026-01-28" status: planned # Resumen de trazabilidad summary: total_requirements: 7 - total_specs: 7 - total_user_stories: 12 - total_files_to_implement: 50 + total_specs: 11 + total_user_stories: 14 + total_files_to_implement: 55 test_coverage: "TBD" - story_points: 65 + 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: