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