--- id: "ET-ML-008" title: "Especificación Frontend del Módulo ML Signals" type: "Technical Specification" status: "Implementado" priority: "Alta" epic: "OQI-006" project: "trading-platform" version: "1.0.0" created_date: "2025-12-15" updated_date: "2026-01-25" --- # ET-ML-008: Especificación Frontend del Módulo ML Signals ## Metadata | Campo | Valor | |-------|-------| | **ID** | ET-ML-008 | | **Épica** | OQI-006 - Señales ML | | **Tipo** | Especificación Técnica | | **Versión** | 1.0.0 | | **Estado** | Implementado | | **Última actualización** | 2026-01-25 | | **Responsable** | Trading Platform Frontend Team | --- ## Propósito Definir la arquitectura, componentes y servicios del frontend para el módulo de Señales ML (OQI-006). Este documento especifica la interfaz de usuario, estructura de componentes React, integración con el backend ML (puerto 3083) y los flujos de usuario para visualización y análisis de señales de trading. --- ## Visión General ### Objetivo Principal Proporcionar una interfaz intuitiva y responsive que permita a los usuarios: - Visualizar señales ML en tiempo real - Analizar predicciones de rangos de precios - Monitorear indicadores técnicos avanzados - Ejecutar operaciones basadas en señales ### Arquitectura de Frontend ``` ┌─────────────────────────────────────────────────────────────────┐ │ ML DASHBOARD (REACT) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ MLDashboard Container │ │ │ │ - State Management (Zustand) │ │ │ │ - WebSocket Subscriptions (Real-time) │ │ │ │ - Query Management (TanStack Query) │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ Signals │ │ ICT Analysis │ │ Ensemble Signals │ │ │ │ Tab │ │ Tab │ │ Tab │ │ │ └──────────┘ └──────────────┘ └──────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ ML Service Integration │ │ │ │ - Base URL: http://localhost:3083 │ │ │ │ - WebSocket: ws://localhost:3083/ws │ │ │ │ - Rate Limiting per User │ │ │ │ - Error Handling & Retry Logic │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## Componentes Frontend ### 1. MLDashboard (Container Principal) **Ruta:** `apps/frontend/src/pages/MLDashboard.tsx` **Responsabilidades:** - Gestionar estado global de señales ML - Coordinar múltiples tabs (Signals, ICT Analysis, Ensemble) - Manejar conexiones WebSocket - Controlar ciclo de vida de datos **Props:** ```typescript interface MLDashboardProps { userId: string; selectedSymbol?: string; autoRefresh?: boolean; } ``` **Estado Inicial:** ```typescript interface MLDashboardState { activeTab: 'signals' | 'ict-analysis' | 'ensemble'; selectedSymbol: string; // BTCUSDT, ETHUSDT, etc. timeframe: '1h' | '4h' | '1d'; isConnected: boolean; signals: Signal[]; predictions: Prediction[]; indicators: Indicator[]; lastUpdate: Date; loading: boolean; error?: string; } ``` **Features:** - Real-time WebSocket connection - Automatic reconnection with exponential backoff - TanStack Query for data caching - Zustand for state management - Error boundaries --- ### 2. AMDPhaseIndicator (Componente de Fase AMD) **Ruta:** `apps/frontend/src/components/ml/AMDPhaseIndicator.tsx` **Propósito:** Visualizar la fase actual AMD (Accumulation, Manipulation, Distribution) **Props:** ```typescript interface AMDPhaseIndicatorProps { phase: 'accumulation' | 'manipulation' | 'distribution' | 'unknown'; confidence: number; // 0-100 priceLevel: number; volume: number; duration: number; // minutos history?: PhaseTransition[]; } ``` **Estilos y Visualización:** - **Accumulation:** Verde (#10b981) - **Manipulation:** Amarillo (#f59e0b) - **Distribution:** Rojo (#ef4444) - **Unknown:** Gris (#6b7280) **Elementos:** ```jsx
``` --- ### 3. PredictionCard (Tarjeta de Predicción) **Ruta:** `apps/frontend/src/components/ml/PredictionCard.tsx` **Propósito:** Mostrar predicciones de rangos de precios y objetivos **Props:** ```typescript interface PredictionCardProps { prediction: { symbol: string; timeframe: string; predictedLow: number; predictedHigh: number; currentPrice: number; confidence: number; targetPrice: number; stopLoss: number; takeProfit: number[]; direction: 'BULLISH' | 'BEARISH' | 'NEUTRAL'; timestamp: Date; }; onTrade?: (action: TradeAction) => void; } ``` **Componentes Internos:** ``` PredictionCard ├── Header (Symbol, Timeframe) ├── RangeDisplay (Low-High) ├── ConfidenceGauge ├── PriceLevels (SL, TP1, TP2, TP3) ├── DirectionBadge └── ActionButtons (Buy/Sell/Close) ``` **Estilos:** - Card con sombra y border-radius - Gradientes según dirección (BULLISH: verde, BEARISH: rojo) - Animaciones en cambios de precio - Responsive: 1 col mobile, 2 cols tablet, 3 cols desktop --- ### 4. SignalsTimeline (Línea de Tiempo de Señales) **Ruta:** `apps/frontend/src/components/ml/SignalsTimeline.tsx` **Propósito:** Visualizar historial de señales en formato timeline **Props:** ```typescript interface SignalsTimelineProps { signals: Signal[]; symbol: string; timeRange: { from: Date; to: Date; }; onSignalClick?: (signal: Signal) => void; } interface Signal { id: string; timestamp: Date; type: 'BUY' | 'SELL' | 'CLOSE_LONG' | 'CLOSE_SHORT'; price: number; strength: number; // 0-100 reason: string; profitLoss?: number; status: 'PENDING' | 'EXECUTED' | 'CLOSED'; } ``` **Visualización:** ``` 2026-01-25 14:30 ▼ BUY @ 45,230 |████████░░| 85% Strength 2026-01-25 13:15 ─ WAIT |██░░░░░░░░| 25% Confidence 2026-01-25 12:00 ▲ SELL @ 45,100 |██████░░░░| 70% Strength 2026-01-25 10:45 ─ NEUTRAL |████░░░░░░| 45% Confidence ``` **Filtros:** - Por tipo de señal (BUY, SELL, CLOSE) - Por rango temporal - Por fuerza de señal (mínimo %) - Por estado (PENDING, EXECUTED, CLOSED) --- ### 5. AccuracyMetrics (Métricas de Precisión) **Ruta:** `apps/frontend/src/components/ml/AccuracyMetrics.tsx` **Propósito:** Mostrar KPIs de desempeño del modelo ML **Props:** ```typescript interface AccuracyMetricsProps { metrics: { totalSignals: number; successfulTrades: number; failedTrades: number; winRate: number; // % profitFactor: number; sharpeRatio: number; maxDrawdown: number; // % totalProfit: number; periods: { period: 'TODAY' | 'WEEK' | 'MONTH' | '3M' | 'YTD' | 'ALL_TIME'; value: number; }[]; }; period?: 'TODAY' | 'WEEK' | 'MONTH' | '3M' | 'YTD' | 'ALL_TIME'; } ``` **Layout de Métricas:** ``` ┌────────────────────────────────────────────┐ │ ACCURACY METRICS (YTD) │ ├────────────────────────────────────────────┤ │ Win Rate: 68.5% │ Profit Factor: 2.3 │ │ Total Trades: 47 │ Sharpe Ratio: 1.85 │ │ Success: 32/47 │ Max Drawdown: 12.3% │ │ Total Profit: +8,450 USDT │ └────────────────────────────────────────────┘ ``` **Gráficos:** - Equity Curve (línea) - Win/Loss distribution (pie) - Drawdown (area) - Monthly returns (bar) --- ### 6. ICTAnalysisCard (Tarjeta de Análisis ICT) **Ruta:** `apps/frontend/src/components/ml/ICTAnalysisCard.tsx` **Propósito:** Visualizar análisis de Institucionales Context Theory (ICT) **Props:** ```typescript interface ICTAnalysisCardProps { analysis: { symbol: string; timestamp: Date; orderBlock: OrderBlock; fairValueGap: FairValueGap[]; liquidityLevels: LiquidityLevel[]; swingStructure: SwingStructure; breaker: Breaker; disorderedMarket: boolean; }; } interface OrderBlock { level: number; strength: 'weak' | 'moderate' | 'strong'; timeframe: string; confirmed: boolean; } interface FairValueGap { high: number; low: number; timestamp: Date; mitigated: boolean; } ``` **Secciones:** 1. **Order Blocks:** Mostrar niveles de orden bloqueados 2. **Fair Value Gaps:** Visualizar gaps de precio 3. **Liquidity Levels:** Mostrar zonas de liquidez 4. **Swing Structure:** Estructura de oscilaciones 5. **Market State:** Ordenado vs Desordenado **Visualización:** ``` ORDER BLOCKS ├─ Level 45,200 [STRONG] ████████ Confirmed ├─ Level 44,950 [MODERATE] ████░░░░ Pending └─ Level 44,700 [WEAK] ██░░░░░░ Watching FAIR VALUE GAPS ├─ 45,100 - 45,200 [MITIGATED] ✓ └─ 44,900 - 45,000 [ACTIVE] ◆ LIQUIDITY LEVELS ├─ 45,500 [BUY] ▲ High ├─ 44,500 [SELL] ▼ High └─ 43,000 [SUPPORT] ═══ Key Level ``` --- ### 7. EnsembleSignalCard (Tarjeta de Señal de Ensemble) **Ruta:** `apps/frontend/src/components/ml/EnsembleSignalCard.tsx` **Propósito:** Mostrar consenso de múltiples modelos ML **Props:** ```typescript interface EnsembleSignalCardProps { symbol: string; models: ModelSignal[]; ensemble: { direction: 'BULLISH' | 'BEARISH' | 'NEUTRAL'; confidence: number; // 0-100 agreementLevel: number; // % de modelos que concuerdan optimalEntry: number; optimalExit: number; riskRewardRatio: number; }; } interface ModelSignal { name: string; // 'AMD Model', 'ICT Model', 'Neural Network', etc. direction: 'BULLISH' | 'BEARISH' | 'NEUTRAL'; confidence: number; weight: number; // % en ensemble lastUpdate: Date; } ``` **Visualización (Radar Chart):** ``` BULLISH ╱╲ ╱ ╲ 40° ╱ ╲ 40° ╱╱ ╲╲ ╱ ┏━━━━┓ ╲ ╱ ┃ MLP ┃ ╲ ╱ ┗━━━━┛ ╲ ╱ ┏━━━━┓ ╲ ╱ ┃AMD ┃ ╲ ╱ ┗━━━━┛ ╲ BEARISH ICT NEUTRAL ``` **Tabla de Modelos:** | Modelo | Dirección | Confianza | Peso | |--------|-----------|-----------|------| | AMD Model | BULLISH | 85% | 30% | | ICT Model | BULLISH | 78% | 30% | | Neural Net | BEARISH | 45% | 20% | | LSTM | BULLISH | 82% | 20% | | **ENSEMBLE** | **BULLISH** | **81%** | **100%** | --- ### 8. TradeExecutionModal (Modal de Ejecución de Trades) **Ruta:** `apps/frontend/src/components/ml/TradeExecutionModal.tsx` **Propósito:** Interfaz para ejecutar trades basados en señales ML **Props:** ```typescript interface TradeExecutionModalProps { isOpen: boolean; signal: Signal; prediction: Prediction; onExecute: (trade: TradeOrder) => Promise; onCancel: () => void; } interface TradeOrder { symbol: string; side: 'BUY' | 'SELL'; quantity: number; entryPrice: number; stopLoss: number; takeProfit: number[]; leverage?: number; orderType: 'MARKET' | 'LIMIT'; timeInForce: 'GTC' | 'IOC' | 'FOK'; } ``` **Pasos del Formulario:** 1. **Confirmación de Señal:** Mostrar detalles de la señal 2. **Parámetros de Orden:** Cantidad, SL, TP 3. **Risk Management:** Cálculo de riesgo/recompensa 4. **Revisión:** Confirmar todos los parámetros 5. **Ejecución:** Enviar orden **Validaciones:** - Verificar saldo disponible - Validar niveles SL/TP - Confirmar riesgo máximo por operación - Verificar límites de exposición **Forma HTML:** ```jsx
``` --- ## ML Service Integration ### Arquitectura del Servicio **Ruta:** `apps/frontend/src/services/ml/mlService.ts` **Configuración Base:** ```typescript const ML_SERVICE_CONFIG = { baseURL: 'http://localhost:3083', wsURL: 'ws://localhost:3083/ws', timeout: 10000, retryAttempts: 3, retryDelay: 1000, rateLimitPerUser: { requestsPerMinute: 60, concurrent: 5 } }; ``` ### Endpoints Principales #### 1. Obtener Señales **GET** `/api/signals` ```typescript interface SignalsRequest { symbol: string; timeframe?: '1h' | '4h' | '1d'; limit?: number; offset?: number; } interface SignalsResponse { data: Signal[]; total: number; timestamp: Date; } // Uso const signals = await mlService.getSignals({ symbol: 'BTCUSDT', timeframe: '1h', limit: 50 }); ``` --- #### 2. Obtener Predicciones **GET** `/api/predictions` ```typescript interface PredictionsRequest { symbol: string; timeframe?: '1h' | '4h' | '1d'; } interface PredictionsResponse { data: Prediction[]; confidence: number; timestamp: Date; } // Uso const predictions = await mlService.getPredictions({ symbol: 'ETHUSDT', timeframe: '4h' }); ``` --- #### 3. Análisis ICT **GET** `/api/ict-analysis` ```typescript interface ICTAnalysisRequest { symbol: string; timeframe: string; } interface ICTAnalysisResponse { orderBlocks: OrderBlock[]; fairValueGaps: FairValueGap[]; liquidityLevels: LiquidityLevel[]; swingStructure: SwingStructure; timestamp: Date; } // Uso const ictAnalysis = await mlService.getICTAnalysis({ symbol: 'BTCUSDT', timeframe: '1h' }); ``` --- #### 4. Señal de Ensemble **GET** `/api/ensemble-signal` ```typescript interface EnsembleRequest { symbol: string; models?: string[]; } interface EnsembleResponse { direction: 'BULLISH' | 'BEARISH' | 'NEUTRAL'; confidence: number; modelSignals: ModelSignal[]; agreementLevel: number; timestamp: Date; } // Uso const ensemble = await mlService.getEnsembleSignal({ symbol: 'BTCUSDT' }); ``` --- #### 5. Métricas de Precisión **GET** `/api/accuracy-metrics` ```typescript interface MetricsRequest { period?: 'TODAY' | 'WEEK' | 'MONTH' | '3M' | 'YTD' | 'ALL_TIME'; } interface MetricsResponse { winRate: number; profitFactor: number; sharpeRatio: number; totalSignals: number; successfulTrades: number; timestamp: Date; } // Uso const metrics = await mlService.getMetrics({ period: 'MONTH' }); ``` --- ### WebSocket Real-time **Conexión:** ```typescript mlService.connectWebSocket({ symbols: ['BTCUSDT', 'ETHUSDT'], channels: ['signals', 'predictions', 'indicators'], onMessage: handleMessage, onError: handleError, onClose: handleClose }); ``` **Eventos:** ```typescript // Signal Update { type: 'signal', symbol: 'BTCUSDT', data: { ... } } // Prediction Update { type: 'prediction', symbol: 'ETHUSDT', data: { ... } } // Indicator Update { type: 'indicator', symbol: 'BTCUSDT', indicator: 'rsi', value: 65.5 } ``` --- ## Estado Global (Zustand) ### Store Principal **Ruta:** `apps/frontend/src/stores/mlSignalsStore.ts` ```typescript interface MLSignalsStore { // Estado activeTab: 'signals' | 'ict-analysis' | 'ensemble'; selectedSymbol: string; signals: Signal[]; predictions: Prediction[]; indicators: Indicator[]; metrics: Metrics; isConnected: boolean; loading: boolean; error?: string; // Acciones setActiveTab: (tab: string) => void; setSymbol: (symbol: string) => void; updateSignals: (signals: Signal[]) => void; updatePredictions: (predictions: Prediction[]) => void; setConnected: (connected: boolean) => void; setError: (error: string | undefined) => void; reset: () => void; } export const useMlSignalsStore = create((set) => ({ // Implementación })); ``` --- ## Queries de TanStack Query ### Query Configuration ```typescript // Queries export const mlQueries = { all: () => ['ml'], signals: (symbol: string) => [...mlQueries.all(), 'signals', symbol], predictions: (symbol: string) => [...mlQueries.all(), 'predictions', symbol], metrics: (period?: string) => [...mlQueries.all(), 'metrics', period], ictAnalysis: (symbol: string) => [...mlQueries.all(), 'ict', symbol], ensemble: (symbol: string) => [...mlQueries.all(), 'ensemble', symbol], }; // Hook para obtener señales export const useSignals = (symbol: string, options?: UseQueryOptions) => { return useQuery({ queryKey: mlQueries.signals(symbol), queryFn: () => mlService.getSignals({ symbol }), staleTime: 30000, // 30s refetchInterval: 60000, // 60s ...options }); }; ``` --- ## Gestión de Errores y Estado ### Error Boundary ```typescript interface MLErrorBoundaryProps { children: React.ReactNode; fallback?: React.ReactNode; } export const MLErrorBoundary: React.FC = ({ children, fallback }) => { // Implementación return ; }; ``` ### Error Handling ```typescript // Tipos de errores type MLError = | ConnectionError | DataValidationError | RateLimitError | InvalidSignalError | ExecutionError; // Handler global const handleMLError = (error: MLError) => { switch (error.type) { case 'ConnectionError': // Reintentar conexión con backoff exponencial break; case 'RateLimitError': // Mostrar advertencia, esperar cooldown break; case 'ExecutionError': // Mostrar error al usuario, registrar break; } }; ``` --- ## Validaciones de Datos ### Schemas Zod ```typescript import { z } from 'zod'; const SignalSchema = z.object({ id: z.string().uuid(), timestamp: z.date(), type: z.enum(['BUY', 'SELL', 'CLOSE_LONG', 'CLOSE_SHORT']), price: z.number().positive(), strength: z.number().min(0).max(100), status: z.enum(['PENDING', 'EXECUTED', 'CLOSED']) }); const PredictionSchema = z.object({ symbol: z.string().regex(/^[A-Z]{1,10}USDT$/), predictedLow: z.number().positive(), predictedHigh: z.number().positive(), confidence: z.number().min(0).max(100), direction: z.enum(['BULLISH', 'BEARISH', 'NEUTRAL']) }); ``` --- ## Responsive Design ### Breakpoints ```typescript const breakpoints = { mobile: '320px', tablet: '768px', desktop: '1024px', wide: '1440px' }; ``` ### Layout Mobile - **Dashboard:** Stack vertical de tabs - **Signals:** Cards en single column - **Charts:** Fullscreen optimizado - **Modals:** Fullscreen en mobile, centered en desktop --- ## Performance Optimization ### Code Splitting ```typescript // Lazy load ML components const MLDashboard = lazy(() => import('./pages/MLDashboard')); const TradeExecutionModal = lazy(() => import('./components/ml/TradeExecutionModal') ); ``` ### Memoization ```typescript // Memoizar componentes costosos export const AMDPhaseIndicator = React.memo( AMDPhaseIndicatorComponent, (prevProps, nextProps) => { return prevProps.phase === nextProps.phase && prevProps.confidence === nextProps.confidence; } ); ``` ### Virtual Scrolling ```typescript // Para listas grandes de señales } /> ``` --- ## Testing Strategy ### Unit Tests ```typescript // tests/components/ml/AMDPhaseIndicator.test.tsx describe('AMDPhaseIndicator', () => { it('should render accumulation phase', () => { const { getByText } = render( ); expect(getByText(/Accumulation/i)).toBeInTheDocument(); }); }); ``` ### Integration Tests ```typescript // tests/integration/mlDashboard.test.tsx describe('ML Dashboard Integration', () => { it('should load signals and display them', async () => { const { getByText } = render(); await waitFor(() => { expect(getByText(/BUY Signal/)).toBeInTheDocument(); }); }); }); ``` ### E2E Tests ```typescript // tests/e2e/ml-signals.spec.ts describe('ML Signals E2E', () => { it('should execute trade from signal', () => { cy.visit('/dashboard/ml'); cy.contains('BUY Signal').click(); cy.get('[data-testid="execute-btn"]').click(); cy.contains('Trade Executed').should('be.visible'); }); }); ``` --- ## Accesibilidad (WCAG 2.1) ### Requirements - ARIA labels en todos los componentes interactivos - Contraste mínimo 4.5:1 en textos - Navegación por teclado completa - Descripciones de imágenes y gráficos - Announces de cambios dinámicos con aria-live ### Ejemplo ```jsx
``` --- ## Seguridad ### OWASP Top 10 1. **Injection:** Validación de todas las entradas con Zod 2. **Authentication:** JWT tokens en headers 3. **XSS:** Sanitización de datos dinámicos con DOMPurify 4. **CSRF:** Tokens CSRF en forms 5. **Rate Limiting:** Cliente + Servidor ### Ejemplo ```typescript import DOMPurify from 'dompurify'; const sanitizedContent = DOMPurify.sanitize(userContent); ``` --- ## Deployment ### Build Process ```bash # Frontend build cd apps/frontend npm run build # Vite production build npm run lint # ESLint checks npm run typecheck # TypeScript validation # Output dist/ ├── index.html ├── assets/ │ ├── js/ │ ├── css/ │ └── images/ ``` ### Environment Variables ``` VITE_API_BASE_URL=http://localhost:3080 VITE_ML_ENGINE_URL=http://localhost:3083 VITE_WS_URL=ws://localhost:3083/ws VITE_APP_ENV=development ``` --- ## Roadmap Futuro 1. **Dark Mode:** Tema oscuro completo 2. **Custom Indicators:** Permitir usuarios agregar indicadores personalizados 3. **Backtesting UI:** Interfaz para backtesting de estrategias 4. **Mobile App:** React Native para iOS/Android 5. **Voice Commands:** Ejecución de trades por voz 6. **ML Model Marketplace:** Mercado de modelos ML --- ## Referencias - [React Documentation](https://react.dev) - [Zustand Store](https://github.com/pmndrs/zustand) - [TanStack Query](https://tanstack.com/query) - [Vite Guide](https://vitejs.dev) - [TypeScript Handbook](https://www.typescriptlang.org/docs) --- ## Changelog | Versión | Fecha | Cambios | |---------|-------|---------| | 1.0.0 | 2026-01-25 | Especificación inicial completa | | 0.9.0 | 2025-12-15 | Borrador de componentes | --- *ET-ML-008 | ML Signals Frontend Specification v1.0.0 | Trading Platform*