ML Engine Updates: - Updated BTCUSD with Polygon API data (2024-2025): 215,699 new records - Re-trained all ML models: Attention (R²: 0.223), Base, Metamodel (87.3% confidence) - Backtest results: +176.71R profit with aggressive_filter strategy Documentation Consolidation: - Created docs/99-analisis/_MAP.md index with 13 new analysis documents - Consolidated inventories: removed duplicates from orchestration/inventarios/ - Updated ML_INVENTORY.yml with BTCUSD metrics and training results - Added execution reports: FASE11-BTCUSD, correction issues, alignment validation Architecture & Integration: - Updated all module documentation with NEXUS v3.4 frontmatter - Fixed _MAP.md indexes across all folders - Updated orchestration plans and traces Files: 229 changed, 5064 insertions(+), 1872 deletions(-) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
384 lines
12 KiB
Markdown
384 lines
12 KiB
Markdown
# DIRECTIVA: Arquitectura Híbrida Express.js + FastAPI
|
|
|
|
**ID**: DOQ-001
|
|
**Tipo**: Arquitectura
|
|
**Alcance**: Trading Platform (trading-platform)
|
|
**Versión**: 2.0
|
|
**Fecha**: 2025-12-07
|
|
**Actualizado desde**: trading (NestJS -> Express.js)
|
|
|
|
## Propósito
|
|
|
|
Definir la arquitectura híbrida que combina Express.js (TypeScript) para la API principal y FastAPI (Python) para los servicios de Machine Learning.
|
|
|
|
## Arquitectura General
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ FRONTEND │
|
|
│ React + TypeScript │
|
|
│ (Puerto 5173) │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ API GATEWAY │
|
|
│ Express.js (Puerto 3000) │
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
│ │ Auth │ │ Users │ │ Courses │ │ Payments │ │
|
|
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │
|
|
│ │ Trading │ │ Admin │ │ ML Proxy (Gateway) │ │
|
|
│ └──────────┘ └──────────┘ └──────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
│ │
|
|
│ │ HTTP/WebSocket
|
|
▼ ▼
|
|
┌─────────────────────┐ ┌─────────────────────────────────────┐
|
|
│ PostgreSQL │ │ ML ENGINE │
|
|
│ (Puerto 5432) │ │ FastAPI (Puerto 8000) │
|
|
│ │ │ ┌──────────┐ ┌──────────┐ │
|
|
│ - public │ │ │ Predict │ │ Signals │ │
|
|
│ - education │ │ └──────────┘ └──────────┘ │
|
|
│ - trading │ │ ┌──────────┐ ┌──────────┐ │
|
|
│ - investment │ │ │ Models │ │Backtest │ │
|
|
│ - financial │ │ └──────────┘ └──────────┘ │
|
|
│ - ml │ │ │ │
|
|
│ - audit │ │ ▼ │
|
|
└─────────────────────┘ │ ┌──────────────┐ │
|
|
│ │ MySQL │ │
|
|
│ │ (Puerto 3306)│ │
|
|
│ │ Trading Data │ │
|
|
│ └──────────────┘ │
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
## Responsabilidades por Servicio
|
|
|
|
### Express.js Backend (API Principal)
|
|
**Responsable de:**
|
|
- Autenticación y autorización (JWT + OAuth + 2FA)
|
|
- Gestión de usuarios y perfiles
|
|
- Sistema de educación (cursos, lecciones, progreso)
|
|
- Pagos e integración con Stripe
|
|
- Panel de administración
|
|
- Proxy/Gateway hacia ML Engine
|
|
- CRUD de entidades de negocio
|
|
- Validación de datos de entrada (Zod)
|
|
- Logging y auditoría (Winston)
|
|
|
|
**NO responsable de:**
|
|
- Ejecución de modelos ML
|
|
- Procesamiento de datos de trading
|
|
- Cálculo de indicadores técnicos
|
|
- Generación de predicciones
|
|
|
|
### FastAPI ML Engine
|
|
**Responsable de:**
|
|
- Carga y ejecución de modelos ML (XGBoost, GRU, Transformer)
|
|
- Predicción de precios (multi-horizonte)
|
|
- Generación de señales de trading
|
|
- Cálculo de indicadores técnicos
|
|
- WebSocket streaming de predicciones
|
|
- Backtesting de estrategias
|
|
- Acceso a datos históricos (MySQL)
|
|
|
|
**NO responsable de:**
|
|
- Autenticación de usuarios
|
|
- Gestión de permisos
|
|
- Lógica de negocio de la aplicación
|
|
- Persistencia de datos de usuario
|
|
|
|
## Comunicación entre Servicios
|
|
|
|
### HTTP (Request/Response)
|
|
```typescript
|
|
// Express.js -> FastAPI
|
|
// Endpoint: GET /api/ml/predict/:symbol
|
|
|
|
// routes/ml.routes.ts
|
|
router.get('/predict/:symbol', authenticate, async (req, res, next) => {
|
|
try {
|
|
const { symbol } = req.params;
|
|
const prediction = await mlGatewayService.predict(symbol);
|
|
res.json(prediction);
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
// services/ml-gateway.service.ts
|
|
import axios from 'axios';
|
|
|
|
class MLGatewayService {
|
|
private mlServiceUrl = process.env.ML_SERVICE_URL || 'http://localhost:8000';
|
|
|
|
async predict(symbol: string): Promise<PredictionDto> {
|
|
const response = await axios.get(
|
|
`${this.mlServiceUrl}/api/predict/${symbol}`,
|
|
{ timeout: 30000 }
|
|
);
|
|
return response.data;
|
|
}
|
|
}
|
|
```
|
|
|
|
### WebSocket (Streaming)
|
|
```typescript
|
|
// Frontend conecta directamente a FastAPI para streaming
|
|
// ws://localhost:8000/ws/{symbol}
|
|
|
|
// O mediante proxy en Express.js con socket.io:
|
|
import { Server } from 'socket.io';
|
|
|
|
const io = new Server(server, {
|
|
cors: { origin: 'http://localhost:5173' }
|
|
});
|
|
|
|
io.on('connection', (socket) => {
|
|
socket.on('subscribe', (symbol: string) => {
|
|
// Proxy a FastAPI WebSocket
|
|
});
|
|
});
|
|
```
|
|
|
|
## Reglas de Diseño
|
|
|
|
### 1. Separación de Concerns
|
|
- Express.js maneja TODO lo relacionado con usuarios y negocio
|
|
- FastAPI maneja EXCLUSIVAMENTE ML y datos de trading
|
|
- Frontend NUNCA accede directamente a MySQL
|
|
|
|
### 2. Autenticación
|
|
- JWT generado por Express.js (Passport.js)
|
|
- FastAPI valida tokens mediante endpoint interno de Express.js
|
|
- O FastAPI confía en requests desde Express.js (red interna)
|
|
|
|
### 3. Base de Datos
|
|
- PostgreSQL: Fuente de verdad para entidades de negocio (7 schemas)
|
|
- MySQL: Solo datos históricos de trading (OHLCV, indicadores)
|
|
- NO replicar datos entre bases de datos
|
|
|
|
### 4. Contratos de API
|
|
- Definir tipos compartidos en `shared/types/`
|
|
- Pydantic schemas en FastAPI deben coincidir con tipos TypeScript
|
|
- Documentar con OpenAPI/Swagger en ambos servicios
|
|
|
|
### 5. Manejo de Errores
|
|
```typescript
|
|
// Express.js captura errores de ML Engine
|
|
// middleware/error-handler.ts
|
|
import { Request, Response, NextFunction } from 'express';
|
|
|
|
export const errorHandler = (
|
|
error: Error,
|
|
req: Request,
|
|
res: Response,
|
|
next: NextFunction
|
|
) => {
|
|
if (error.name === 'MLServiceUnavailableError') {
|
|
return res.status(503).json({
|
|
error: 'ML service unavailable',
|
|
message: 'Please try again later'
|
|
});
|
|
}
|
|
|
|
// Default error handling
|
|
res.status(500).json({
|
|
error: 'Internal server error',
|
|
message: error.message
|
|
});
|
|
};
|
|
```
|
|
|
|
## Estructura de Directorios
|
|
|
|
### Express.js Backend
|
|
```
|
|
apps/backend/src/
|
|
├── modules/
|
|
│ ├── auth/
|
|
│ │ ├── auth.routes.ts
|
|
│ │ ├── auth.controller.ts
|
|
│ │ ├── services/
|
|
│ │ │ ├── oauth.service.ts
|
|
│ │ │ ├── email.service.ts
|
|
│ │ │ ├── phone.service.ts
|
|
│ │ │ ├── token.service.ts
|
|
│ │ │ └── twofa.service.ts
|
|
│ │ └── validators/
|
|
│ ├── users/
|
|
│ ├── education/
|
|
│ ├── trading/
|
|
│ │ ├── trading.routes.ts
|
|
│ │ ├── trading.controller.ts
|
|
│ │ └── services/
|
|
│ │ └── ml-gateway.service.ts # Comunicación con FastAPI
|
|
│ ├── investment/
|
|
│ ├── payments/
|
|
│ └── admin/
|
|
├── middleware/
|
|
│ ├── authenticate.ts
|
|
│ ├── error-handler.ts
|
|
│ └── rate-limiter.ts
|
|
├── config/
|
|
│ └── index.ts
|
|
└── index.ts
|
|
```
|
|
|
|
### FastAPI ML Engine
|
|
```
|
|
apps/ml-engine/src/
|
|
├── api/
|
|
│ ├── main.py # FastAPI app
|
|
│ ├── routes/
|
|
│ │ ├── predict.py
|
|
│ │ ├── signals.py
|
|
│ │ ├── indicators.py
|
|
│ │ └── backtest.py
|
|
│ └── schemas/ # Pydantic models
|
|
├── models/
|
|
│ ├── base/
|
|
│ ├── ensemble/
|
|
│ └── predictors/
|
|
│ ├── range_predictor.py
|
|
│ ├── tpsl_classifier.py
|
|
│ └── signal_generator.py
|
|
├── data/
|
|
│ ├── pipeline.py
|
|
│ ├── database.py
|
|
│ ├── features.py
|
|
│ └── indicators.py
|
|
└── config/
|
|
├── trading.yaml
|
|
└── models.yaml
|
|
```
|
|
|
|
## Endpoints ML Engine (FastAPI)
|
|
|
|
```yaml
|
|
# Predicciones
|
|
GET /api/predict/{symbol}
|
|
?horizon=all|scalping|intraday|swing|position
|
|
|
|
# Señales
|
|
GET /api/signals/{symbol}
|
|
?timeframe=5m|15m|1h
|
|
|
|
# Indicadores
|
|
GET /api/indicators/{symbol}
|
|
?indicators=rsi,macd,atr
|
|
|
|
# Datos históricos
|
|
GET /api/history/{symbol}
|
|
?limit=500&timeframe=5m
|
|
|
|
# Backtesting
|
|
POST /api/backtest
|
|
Body: { strategy, symbol, start_date, end_date }
|
|
|
|
# Health
|
|
GET /health
|
|
GET /api/stats
|
|
|
|
# WebSocket
|
|
WS /ws/{symbol}
|
|
```
|
|
|
|
## Configuración de Puertos
|
|
|
|
| Servicio | Puerto | Protocolo |
|
|
|----------|--------|-----------|
|
|
| Frontend | 5173 | HTTP |
|
|
| Express.js API | 3000 | HTTP |
|
|
| FastAPI ML | 8000 | HTTP |
|
|
| FastAPI WS | 8000 | WebSocket |
|
|
| PostgreSQL | 5432 | TCP |
|
|
| MySQL | 3306 | TCP |
|
|
| Redis | 6379 | TCP |
|
|
|
|
## Variables de Entorno
|
|
|
|
### Express.js (.env)
|
|
```env
|
|
# Server
|
|
PORT=3000
|
|
NODE_ENV=development
|
|
|
|
# Database
|
|
DATABASE_URL=postgresql://user:pass@localhost:5432/trading
|
|
|
|
# JWT
|
|
JWT_SECRET=your-secret-key
|
|
JWT_EXPIRES_IN=15m
|
|
JWT_REFRESH_SECRET=your-refresh-secret
|
|
JWT_REFRESH_EXPIRES_IN=7d
|
|
|
|
# ML Services
|
|
ML_SERVICE_URL=http://localhost:8000
|
|
ML_SERVICE_TIMEOUT=30000
|
|
|
|
# OAuth
|
|
GOOGLE_CLIENT_ID=
|
|
GOOGLE_CLIENT_SECRET=
|
|
FACEBOOK_APP_ID=
|
|
FACEBOOK_APP_SECRET=
|
|
GITHUB_CLIENT_ID=
|
|
GITHUB_CLIENT_SECRET=
|
|
|
|
# Twilio (Phone Auth)
|
|
TWILIO_ACCOUNT_SID=
|
|
TWILIO_AUTH_TOKEN=
|
|
TWILIO_PHONE_NUMBER=
|
|
|
|
# Stripe
|
|
STRIPE_SECRET_KEY=
|
|
STRIPE_WEBHOOK_SECRET=
|
|
|
|
# Redis
|
|
REDIS_URL=redis://localhost:6379
|
|
```
|
|
|
|
### FastAPI (.env)
|
|
```env
|
|
# API Configuration
|
|
API_HOST=0.0.0.0
|
|
API_PORT=8000
|
|
|
|
# MySQL Trading Data
|
|
MYSQL_HOST=localhost
|
|
MYSQL_PORT=3306
|
|
MYSQL_DATABASE=trading_trading
|
|
MYSQL_USER=trading_user
|
|
MYSQL_PASSWORD=secure_password
|
|
|
|
# Models
|
|
MODEL_PATH=./models
|
|
MODEL_VERSION=1.0.0
|
|
|
|
# GPU
|
|
CUDA_VISIBLE_DEVICES=0
|
|
USE_GPU=true
|
|
|
|
# Internal Auth (opcional)
|
|
EXPRESS_INTERNAL_URL=http://localhost:3000
|
|
INTERNAL_API_KEY=shared_secret_key
|
|
|
|
# Logging
|
|
LOG_LEVEL=INFO
|
|
```
|
|
|
|
## Validaciones Obligatorias
|
|
|
|
1. [ ] Express.js puede alcanzar FastAPI en `/health`
|
|
2. [ ] Tokens JWT son validados correctamente
|
|
3. [ ] Timeouts configurados apropiadamente
|
|
4. [ ] Errores de ML Engine se manejan gracefully
|
|
5. [ ] WebSocket streaming funciona end-to-end
|
|
6. [ ] Tipos TypeScript coinciden con Pydantic schemas
|
|
7. [ ] Rate limiting configurado en ambos servicios
|
|
8. [ ] CORS configurado correctamente
|
|
|
|
---
|
|
*Migrado desde trading y actualizado para Express.js*
|