- FASE-0: Diagnostic audit of 500+ files, 33 findings cataloged (7P0/8P1/12P2/6P3) - FASE-1: Resolved 7 P0 critical conflicts (ports, paths, dedup OQI-010/ADR-002, orphan schemas) - FASE-2: Resolved 8 P1 issues (traces, README/CLAUDE.md, DEPENDENCY-GRAPH v2.0, DDL drift, stack versions, DoR/DoD) - FASE-3: Resolved 12 P2 issues (archived tasks indexed, RNFs created, OQI-010 US/RF/ET, AGENTS v2.0) - FASE-4: Purged 3 obsolete docs to _archive/, fixed MODELO-NEGOCIO.md broken ref - FASE-5: Cross-layer validation (DDL→OQI 66%, OQI→BE 72%, BE→FE 78%, Inventories 95%) - FASE-6: INFORME-FINAL, SA-INDEX (18 subagents), METADATA COMPLETED 27/33 findings resolved (82%), 6 P3 deferred to backlog. 18 new files created, 40+ modified, 4 archived. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
687 lines
15 KiB
Markdown
687 lines
15 KiB
Markdown
---
|
|
id: "ET-MT4-001"
|
|
title: "Especificacion Tecnica: MT4 Gateway Service"
|
|
type: "Technical Specification"
|
|
project: "trading-platform"
|
|
epic: "OQI-010"
|
|
version: "0.1.0"
|
|
created_date: "2026-01-28"
|
|
updated_date: "2026-01-28"
|
|
status: "DRAFT"
|
|
---
|
|
|
|
# ET-MT4-001: MT4 Gateway Service
|
|
|
|
## 1. Resumen
|
|
|
|
Esta especificacion define los requisitos tecnicos para el servicio MT4 Gateway, el componente intermedio que conecta el MCP MT4 Connector con el Expert Advisor ejecutandose en MetaTrader 4.
|
|
|
|
---
|
|
|
|
## 2. Alcance
|
|
|
|
### 2.1 Incluido
|
|
- API REST para comunicacion con MCP Connector
|
|
- WebSocket server para streaming de datos
|
|
- Socket server para comunicacion con Expert Advisor
|
|
- Autenticacion y autorizacion
|
|
- Queue de comandos
|
|
- Logging y monitoring
|
|
|
|
### 2.2 Excluido
|
|
- Desarrollo del Expert Advisor (ver ET-MT4-002)
|
|
- Logica de trading/estrategia
|
|
- Interfaz de usuario
|
|
|
|
---
|
|
|
|
## 3. Arquitectura
|
|
|
|
### 3.1 Diagrama de Componentes
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ MT4 GATEWAY SERVICE │
|
|
│ (Node.js/TypeScript) │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌───────────────────┐ ┌───────────────────┐ │
|
|
│ │ HTTP/REST API │ │ WebSocket Server │ │
|
|
│ │ (Express.js) │ │ (ws library) │ │
|
|
│ │ │ │ │ │
|
|
│ │ Port: 8081 │ │ Path: /ws/* │ │
|
|
│ └─────────┬─────────┘ └─────────┬─────────┘ │
|
|
│ │ │ │
|
|
│ └───────────┬────────────┘ │
|
|
│ │ │
|
|
│ ┌───────────▼───────────┐ │
|
|
│ │ Command Processor │ │
|
|
│ │ │ │
|
|
│ │ - Request Validation │ │
|
|
│ │ - Rate Limiting │ │
|
|
│ │ - Auth Verification │ │
|
|
│ └───────────┬───────────┘ │
|
|
│ │ │
|
|
│ ┌───────────▼───────────┐ │
|
|
│ │ Command Queue │ │
|
|
│ │ │ │
|
|
│ │ - Priority Queue │ │
|
|
│ │ - Timeout Handling │ │
|
|
│ │ - Retry Logic │ │
|
|
│ └───────────┬───────────┘ │
|
|
│ │ │
|
|
│ ┌───────────▼───────────┐ │
|
|
│ │ EA Socket Server │ │
|
|
│ │ │ │
|
|
│ │ Port: 8082 │ │
|
|
│ │ Protocol: TCP/JSON │ │
|
|
│ └───────────┬───────────┘ │
|
|
│ │ │
|
|
└────────────────────────┼────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────┐
|
|
│ Expert Advisor │
|
|
│ (MT4 Terminal) │
|
|
└─────────────────────┘
|
|
```
|
|
|
|
### 3.2 Stack Tecnologico
|
|
|
|
| Componente | Tecnologia | Version |
|
|
|------------|------------|---------|
|
|
| Runtime | Node.js | >= 20.x |
|
|
| Language | TypeScript | >= 5.0 |
|
|
| HTTP Server | Express.js | >= 4.18 |
|
|
| WebSocket | ws | >= 8.x |
|
|
| Validation | Zod | >= 3.x |
|
|
| Logging | Winston | >= 3.x |
|
|
| Testing | Jest | >= 29.x |
|
|
|
|
---
|
|
|
|
## 4. API REST
|
|
|
|
### 4.1 Base URL
|
|
```
|
|
http://localhost:8081/api/v1
|
|
```
|
|
|
|
### 4.2 Autenticacion
|
|
|
|
Todas las rutas (excepto `/health`) requieren autenticacion via Bearer token.
|
|
|
|
```http
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Token de desarrollo:** Configurar en `.env`
|
|
|
|
### 4.3 Endpoints
|
|
|
|
#### 4.3.1 Health Check
|
|
|
|
```http
|
|
GET /health
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"status": "ok",
|
|
"service": "mt4-gateway",
|
|
"version": "0.1.0",
|
|
"timestamp": "2026-01-28T10:00:00Z",
|
|
"dependencies": {
|
|
"ea": "connected",
|
|
"mt4": "connected"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 4.3.2 Account Info
|
|
|
|
```http
|
|
GET /api/v1/account
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"login": 12345678,
|
|
"name": "Demo Account",
|
|
"server": "ICMarkets-Demo",
|
|
"currency": "USD",
|
|
"balance": 10000.00,
|
|
"equity": 10250.50,
|
|
"margin": 500.00,
|
|
"freeMargin": 9750.50,
|
|
"marginLevel": 2050.10,
|
|
"leverage": 100
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 4.3.3 Positions
|
|
|
|
```http
|
|
GET /api/v1/positions
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Query Parameters:**
|
|
| Param | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| symbol | string | No | Filtrar por simbolo |
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"positions": [
|
|
{
|
|
"ticket": 12345678,
|
|
"symbol": "XAUUSD",
|
|
"type": "buy",
|
|
"lots": 0.10,
|
|
"openPrice": 2650.50,
|
|
"currentPrice": 2655.00,
|
|
"stopLoss": 2640.00,
|
|
"takeProfit": 2680.00,
|
|
"profit": 45.00,
|
|
"swap": -2.50,
|
|
"commission": -5.00,
|
|
"openTime": "2026-01-28T08:00:00Z",
|
|
"comment": "MCP Trade"
|
|
}
|
|
],
|
|
"count": 1
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 4.3.4 Quote
|
|
|
|
```http
|
|
GET /api/v1/quote/:symbol
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"symbol": "XAUUSD",
|
|
"bid": 2654.50,
|
|
"ask": 2655.00,
|
|
"spread": 0.50,
|
|
"time": "2026-01-28T10:00:00Z",
|
|
"digits": 2
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 4.3.5 Execute Order
|
|
|
|
```http
|
|
POST /api/v1/orders
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
```
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"symbol": "XAUUSD",
|
|
"action": "buy",
|
|
"lots": 0.10,
|
|
"type": "market",
|
|
"stopLoss": 2640.00,
|
|
"takeProfit": 2680.00,
|
|
"comment": "MCP Trade",
|
|
"magicNumber": 12345
|
|
}
|
|
```
|
|
|
|
**Parameters:**
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| symbol | string | Yes | Trading symbol |
|
|
| action | enum | Yes | "buy" or "sell" |
|
|
| lots | number | Yes | Lot size (0.01 - 10.0) |
|
|
| type | enum | Yes | "market", "limit", "stop" |
|
|
| price | number | No* | Price for limit/stop orders |
|
|
| stopLoss | number | No | Stop loss price |
|
|
| takeProfit | number | No | Take profit price |
|
|
| comment | string | No | Order comment |
|
|
| magicNumber | number | No | Magic number for EA |
|
|
|
|
**Response (Success):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"ticket": 12345679,
|
|
"symbol": "XAUUSD",
|
|
"action": "buy",
|
|
"lots": 0.10,
|
|
"openPrice": 2655.00,
|
|
"openTime": "2026-01-28T10:00:05Z",
|
|
"stopLoss": 2640.00,
|
|
"takeProfit": 2680.00
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response (Error):**
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": {
|
|
"code": "INSUFFICIENT_MARGIN",
|
|
"message": "Not enough free margin to open position",
|
|
"details": {
|
|
"required": 2500.00,
|
|
"available": 1000.00
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 4.3.6 Close Position
|
|
|
|
```http
|
|
DELETE /api/v1/orders/:ticket
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"ticket": 12345678,
|
|
"closePrice": 2660.00,
|
|
"closeTime": "2026-01-28T10:30:00Z",
|
|
"profit": 95.00,
|
|
"swap": -2.50,
|
|
"commission": -5.00
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 4.3.7 Modify Position
|
|
|
|
```http
|
|
PATCH /api/v1/positions/:ticket
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
```
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"stopLoss": 2645.00,
|
|
"takeProfit": 2685.00
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"ticket": 12345678,
|
|
"stopLoss": 2645.00,
|
|
"takeProfit": 2685.00,
|
|
"modifiedTime": "2026-01-28T10:15:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 5. WebSocket API
|
|
|
|
### 5.1 Connection
|
|
|
|
```javascript
|
|
const ws = new WebSocket('ws://localhost:8081/ws/stream');
|
|
ws.onopen = () => {
|
|
ws.send(JSON.stringify({
|
|
type: 'auth',
|
|
token: '<bearer_token>'
|
|
}));
|
|
};
|
|
```
|
|
|
|
### 5.2 Subscribe to Quotes
|
|
|
|
```json
|
|
// Request
|
|
{
|
|
"type": "subscribe",
|
|
"channel": "quotes",
|
|
"symbols": ["XAUUSD", "EURUSD"]
|
|
}
|
|
|
|
// Response (streaming)
|
|
{
|
|
"type": "quote",
|
|
"data": {
|
|
"symbol": "XAUUSD",
|
|
"bid": 2654.55,
|
|
"ask": 2655.05,
|
|
"time": "2026-01-28T10:00:01Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 5.3 Subscribe to Positions
|
|
|
|
```json
|
|
// Request
|
|
{
|
|
"type": "subscribe",
|
|
"channel": "positions"
|
|
}
|
|
|
|
// Response (on change)
|
|
{
|
|
"type": "position_update",
|
|
"data": {
|
|
"ticket": 12345678,
|
|
"profit": 50.00,
|
|
"currentPrice": 2656.00
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 6. EA Communication Protocol
|
|
|
|
### 6.1 TCP Socket
|
|
|
|
- **Puerto:** 8082
|
|
- **Protocolo:** TCP
|
|
- **Formato:** JSON delimitado por newline
|
|
|
|
### 6.2 Handshake
|
|
|
|
```json
|
|
// EA -> Gateway
|
|
{
|
|
"type": "handshake",
|
|
"version": "1.0",
|
|
"accountLogin": 12345678
|
|
}
|
|
|
|
// Gateway -> EA
|
|
{
|
|
"type": "handshake_ack",
|
|
"status": "connected",
|
|
"sessionId": "uuid"
|
|
}
|
|
```
|
|
|
|
### 6.3 Heartbeat
|
|
|
|
```json
|
|
// Cada 5 segundos
|
|
// EA -> Gateway
|
|
{
|
|
"type": "heartbeat",
|
|
"timestamp": 1706436000
|
|
}
|
|
|
|
// Gateway -> EA
|
|
{
|
|
"type": "heartbeat_ack"
|
|
}
|
|
```
|
|
|
|
### 6.4 Command Format
|
|
|
|
```json
|
|
// Gateway -> EA (Request)
|
|
{
|
|
"id": "uuid-request-id",
|
|
"type": "command",
|
|
"command": "EXECUTE_ORDER",
|
|
"params": {
|
|
"symbol": "XAUUSD",
|
|
"action": "OP_BUY",
|
|
"lots": 0.10,
|
|
"stopLoss": 2640.00,
|
|
"takeProfit": 2680.00
|
|
},
|
|
"timeout": 30000
|
|
}
|
|
|
|
// EA -> Gateway (Response)
|
|
{
|
|
"id": "uuid-request-id",
|
|
"type": "response",
|
|
"success": true,
|
|
"data": {
|
|
"ticket": 12345679,
|
|
"openPrice": 2655.00
|
|
}
|
|
}
|
|
|
|
// EA -> Gateway (Error)
|
|
{
|
|
"id": "uuid-request-id",
|
|
"type": "response",
|
|
"success": false,
|
|
"error": {
|
|
"code": 134,
|
|
"message": "ERR_NOT_ENOUGH_MONEY"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 6.5 Commands Supported
|
|
|
|
| Command | Description | Params |
|
|
|---------|-------------|--------|
|
|
| GET_ACCOUNT | Get account info | - |
|
|
| GET_POSITIONS | List open positions | symbol? |
|
|
| GET_QUOTE | Get current quote | symbol |
|
|
| EXECUTE_ORDER | Execute trade | symbol, action, lots, ... |
|
|
| CLOSE_ORDER | Close position | ticket |
|
|
| MODIFY_ORDER | Modify SL/TP | ticket, sl?, tp? |
|
|
|
|
---
|
|
|
|
## 7. Error Codes
|
|
|
|
### 7.1 Gateway Errors
|
|
|
|
| Code | HTTP | Description |
|
|
|------|------|-------------|
|
|
| AUTH_FAILED | 401 | Invalid or missing token |
|
|
| FORBIDDEN | 403 | Insufficient permissions |
|
|
| NOT_FOUND | 404 | Resource not found |
|
|
| VALIDATION_ERROR | 400 | Invalid request parameters |
|
|
| EA_DISCONNECTED | 503 | EA not connected |
|
|
| MT4_ERROR | 502 | MT4 returned error |
|
|
| TIMEOUT | 504 | Request timeout |
|
|
| RATE_LIMITED | 429 | Too many requests |
|
|
|
|
### 7.2 MT4 Error Mapping
|
|
|
|
| MT4 Code | Gateway Code | Description |
|
|
|----------|--------------|-------------|
|
|
| 0 | - | Success |
|
|
| 2 | MT4_COMMON_ERROR | Common error |
|
|
| 3 | MT4_INVALID_PARAMS | Invalid trade parameters |
|
|
| 4 | MT4_SERVER_BUSY | Server busy |
|
|
| 6 | MT4_NO_CONNECTION | No connection |
|
|
| 134 | INSUFFICIENT_MARGIN | Not enough margin |
|
|
| 148 | MT4_TOO_MANY_ORDERS | Too many orders |
|
|
|
|
---
|
|
|
|
## 8. Security Requirements
|
|
|
|
### 8.1 Authentication
|
|
- Bearer token authentication
|
|
- Token rotation each 24 hours
|
|
- Rate limiting per token
|
|
|
|
### 8.2 Rate Limiting
|
|
|
|
| Endpoint | Limit | Window |
|
|
|----------|-------|--------|
|
|
| GET /account | 60 | 1 min |
|
|
| GET /positions | 60 | 1 min |
|
|
| GET /quote | 120 | 1 min |
|
|
| POST /orders | 10 | 1 min |
|
|
| DELETE /orders | 10 | 1 min |
|
|
| PATCH /positions | 20 | 1 min |
|
|
|
|
### 8.3 Input Validation
|
|
- All inputs validated with Zod schemas
|
|
- SQL injection protection (N/A, no SQL)
|
|
- Symbol whitelist validation
|
|
|
|
### 8.4 Logging
|
|
- All requests logged with timestamp
|
|
- All trades logged for audit
|
|
- No sensitive data in logs (tokens masked)
|
|
|
|
---
|
|
|
|
## 9. Configuration
|
|
|
|
### 9.1 Environment Variables
|
|
|
|
```env
|
|
# Server
|
|
PORT=8081
|
|
EA_SOCKET_PORT=8082
|
|
NODE_ENV=development
|
|
|
|
# Auth
|
|
AUTH_TOKEN=your-secret-token
|
|
TOKEN_EXPIRY_HOURS=24
|
|
|
|
# EA Connection
|
|
EA_HEARTBEAT_INTERVAL=5000
|
|
EA_RECONNECT_DELAY=5000
|
|
EA_MAX_RECONNECT_ATTEMPTS=10
|
|
|
|
# Timeouts
|
|
REQUEST_TIMEOUT=30000
|
|
EA_COMMAND_TIMEOUT=30000
|
|
|
|
# Rate Limiting
|
|
RATE_LIMIT_WINDOW_MS=60000
|
|
RATE_LIMIT_MAX_REQUESTS=60
|
|
|
|
# Logging
|
|
LOG_LEVEL=info
|
|
LOG_FILE=./logs/gateway.log
|
|
|
|
# Risk Limits
|
|
MAX_LOTS_PER_ORDER=1.0
|
|
MAX_OPEN_POSITIONS=5
|
|
MIN_FREE_MARGIN_PERCENT=50
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Monitoring
|
|
|
|
### 10.1 Health Metrics
|
|
- Gateway uptime
|
|
- EA connection status
|
|
- Request latency (p50, p95, p99)
|
|
- Error rate
|
|
- Active WebSocket connections
|
|
|
|
### 10.2 Trading Metrics
|
|
- Orders executed
|
|
- Orders failed
|
|
- Average execution time
|
|
- P&L tracking
|
|
|
|
### 10.3 Alerts
|
|
- EA disconnection
|
|
- High error rate (>5%)
|
|
- High latency (>5s)
|
|
- Risk limit breach
|
|
|
|
---
|
|
|
|
## 11. Testing Requirements
|
|
|
|
### 11.1 Unit Tests
|
|
- Command processor
|
|
- Validation schemas
|
|
- Error handling
|
|
- Rate limiting
|
|
|
|
### 11.2 Integration Tests
|
|
- EA mock communication
|
|
- Full request flow
|
|
- WebSocket subscriptions
|
|
|
|
### 11.3 E2E Tests (with demo account)
|
|
- Order execution
|
|
- Position modification
|
|
- Account queries
|
|
|
|
**Coverage Target:** >70%
|
|
|
|
---
|
|
|
|
## 12. Deployment
|
|
|
|
### 12.1 Docker (Recomendado)
|
|
|
|
```dockerfile
|
|
FROM node:20-alpine
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
RUN npm ci --only=production
|
|
COPY dist ./dist
|
|
EXPOSE 8081 8082
|
|
CMD ["node", "dist/index.js"]
|
|
```
|
|
|
|
### 12.2 PM2 (Alternativo)
|
|
|
|
```json
|
|
{
|
|
"name": "mt4-gateway",
|
|
"script": "dist/index.js",
|
|
"instances": 1,
|
|
"autorestart": true,
|
|
"max_memory_restart": "500M"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 13. Referencias
|
|
|
|
- [README.md](../README.md) - Vision general
|
|
- [STATUS.md](../STATUS.md) - Estado actual
|
|
- [ROADMAP-MT4.md](../ROADMAP-MT4.md) - Plan de implementacion
|
|
- [MCP MT4 Connector](../../../../mcp-mt4-connector/README.md)
|
|
- [MCP Protocol](https://modelcontextprotocol.io)
|
|
- [MetaTrader 4 Documentation](https://www.mql4.com/docs)
|
|
|
|
---
|
|
|
|
*Documento creado: 2026-01-28*
|
|
*Estado: DRAFT - Pendiente implementacion*
|