Changes include: - Updated architecture documentation - Enhanced module definitions (OQI-001 to OQI-008) - ML integration documentation updates - Trading strategies documentation - Orchestration and inventory updates - Docker configuration updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
311 lines
8.6 KiB
Markdown
311 lines
8.6 KiB
Markdown
---
|
|
id: "RF-DATA-001"
|
|
title: "Sincronizacion Batch de Datos de Activos con Priorizacion"
|
|
type: "Requirement"
|
|
status: "To Do"
|
|
priority: "Alta"
|
|
epic: "Transversal"
|
|
project: "trading-platform"
|
|
version: "1.0.0"
|
|
created_date: "2026-01-04"
|
|
updated_date: "2026-01-04"
|
|
---
|
|
|
|
# RF-DATA-001: Sincronizacion Batch de Datos de Activos con Priorizacion
|
|
|
|
**Version:** 1.0.0
|
|
**Fecha:** 2026-01-04
|
|
**Modulo:** Data Service
|
|
**Prioridad:** P0
|
|
**Story Points:** 13
|
|
|
|
---
|
|
|
|
## Descripcion
|
|
|
|
El sistema debe implementar un proceso batch automatizado que actualice los datos de activos financieros desde la API de Polygon.io/Massive.com hacia la base de datos PostgreSQL cada 5 minutos, respetando el rate limit de 5 llamadas API por minuto (cuenta gratuita) y priorizando la actualizacion de activos criticos (Oro/XAU, EUR/USD, Bitcoin/BTC).
|
|
|
|
---
|
|
|
|
## Requisitos Funcionales
|
|
|
|
### RF-DATA-001.1: Ejecucion Programada del Batch
|
|
|
|
El sistema debe:
|
|
- Ejecutar un proceso batch cada 5 minutos
|
|
- Iniciar automaticamente al arrancar el Data Service
|
|
- Permitir ejecucion manual via API endpoint
|
|
- Registrar logs de cada ejecucion
|
|
|
|
**Configuracion:**
|
|
```yaml
|
|
batch:
|
|
interval_minutes: 5
|
|
auto_start: true
|
|
retry_on_failure: true
|
|
max_retries: 3
|
|
```
|
|
|
|
### RF-DATA-001.2: Priorizacion de Activos
|
|
|
|
El sistema debe actualizar primero los activos prioritarios antes que cualquier otro:
|
|
|
|
| Prioridad | Simbolo | Tipo | Ticker Polygon |
|
|
|-----------|---------|------|----------------|
|
|
| 1 | XAU/USD | Commodity | C:XAUUSD |
|
|
| 2 | EUR/USD | Forex | C:EURUSD |
|
|
| 3 | BTC/USD | Crypto | X:BTCUSD |
|
|
|
|
**Comportamiento:**
|
|
- Los 3 activos prioritarios se actualizan en CADA ciclo de 5 minutos
|
|
- Utilizan 3 de las 5 llamadas API disponibles por minuto
|
|
- No pueden ser omitidos por ningun motivo
|
|
|
|
### RF-DATA-001.3: Rate Limiting
|
|
|
|
El sistema debe:
|
|
- Respetar el limite de 5 llamadas API por minuto
|
|
- Distribuir las llamadas de manera uniforme (espaciado de ~12 segundos)
|
|
- Esperar automaticamente si se alcanza el limite
|
|
- Registrar metricas de uso de API
|
|
|
|
**Distribucion de Llamadas por Ciclo:**
|
|
```
|
|
Minuto 0:
|
|
- 0s: Llamada 1 - XAU/USD (Priority)
|
|
- 12s: Llamada 2 - EUR/USD (Priority)
|
|
- 24s: Llamada 3 - BTC/USD (Priority)
|
|
- 36s: Llamada 4 - Asset de cola
|
|
- 48s: Llamada 5 - Asset de cola
|
|
```
|
|
|
|
### RF-DATA-001.4: Sistema de Cola para Activos Secundarios
|
|
|
|
El sistema debe:
|
|
- Mantener una cola de prioridad para activos no prioritarios
|
|
- Procesar activos encolados con las 2 llamadas API restantes por minuto
|
|
- Implementar deduplicacion (no encolar duplicados)
|
|
- Soportar reintentos con backoff exponencial
|
|
|
|
**Activos Secundarios (ejemplos):**
|
|
- ETH/USDT (Crypto)
|
|
- GBP/USD (Forex)
|
|
- USD/JPY (Forex)
|
|
- XAG/USD (Plata)
|
|
- Indices (SPX, NDX)
|
|
|
|
### RF-DATA-001.5: Actualizacion de Base de Datos
|
|
|
|
El sistema debe actualizar las siguientes tablas:
|
|
|
|
**Tabla `trading.symbols`:**
|
|
- `updated_at`: Timestamp de ultima actualizacion
|
|
- `metadata`: JSON con precios actuales (bid, ask, last_price)
|
|
|
|
**Tabla `data_sources.data_sync_status`:**
|
|
- `last_sync_timestamp`: Cuando se sincronizo
|
|
- `sync_status`: success | failed | pending
|
|
- `last_sync_rows`: Cantidad de datos actualizados
|
|
|
|
### RF-DATA-001.6: Notificacion de Actualizaciones
|
|
|
|
El sistema debe:
|
|
- Publicar eventos via Redis Pub/Sub al actualizar un activo
|
|
- Formato del canal: `asset:update:{SYMBOL}`
|
|
- Incluir en el mensaje: symbol, bid, ask, last_price, timestamp
|
|
- Permitir a otros servicios suscribirse a actualizaciones
|
|
|
|
---
|
|
|
|
## Datos de Entrada
|
|
|
|
| Campo | Tipo | Descripcion | Requerido |
|
|
|-------|------|-------------|-----------|
|
|
| symbol | string | Simbolo del activo (ej: XAUUSD) | Si |
|
|
| polygon_ticker | string | Ticker en formato Polygon (ej: C:XAUUSD) | Si |
|
|
| asset_type | enum | forex, crypto, index, commodity | Si |
|
|
| priority | enum | CRITICAL, HIGH, MEDIUM, LOW | No (default: MEDIUM) |
|
|
|
|
---
|
|
|
|
## Datos de Salida
|
|
|
|
### Respuesta de Snapshot por Activo
|
|
|
|
```typescript
|
|
interface AssetSnapshot {
|
|
symbol: string;
|
|
bid: number;
|
|
ask: number;
|
|
spread: number;
|
|
last_price: number;
|
|
daily_open: number;
|
|
daily_high: number;
|
|
daily_low: number;
|
|
daily_close: number;
|
|
daily_volume: number;
|
|
timestamp: string; // ISO 8601
|
|
}
|
|
```
|
|
|
|
### Resultado del Batch Job
|
|
|
|
```typescript
|
|
interface BatchResult {
|
|
started_at: string;
|
|
completed_at: string;
|
|
duration_ms: number;
|
|
priority_assets: {
|
|
updated: string[];
|
|
failed: Array<{ symbol: string; error: string }>;
|
|
};
|
|
queued_assets: {
|
|
processed: number;
|
|
remaining: number;
|
|
};
|
|
api_calls_used: number;
|
|
rate_limit_waits: number;
|
|
}
|
|
```
|
|
|
|
**Ejemplo:**
|
|
```json
|
|
{
|
|
"started_at": "2026-01-04T18:00:00.000Z",
|
|
"completed_at": "2026-01-04T18:00:48.250Z",
|
|
"duration_ms": 48250,
|
|
"priority_assets": {
|
|
"updated": ["XAUUSD", "EURUSD", "BTCUSD"],
|
|
"failed": []
|
|
},
|
|
"queued_assets": {
|
|
"processed": 2,
|
|
"remaining": 15
|
|
},
|
|
"api_calls_used": 5,
|
|
"rate_limit_waits": 0
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Reglas de Negocio
|
|
|
|
1. **Activos Prioritarios Obligatorios:** XAU, EURUSD y BTCUSD SIEMPRE se actualizan primero
|
|
2. **Rate Limit Estricto:** Nunca exceder 5 llamadas por minuto
|
|
3. **Reintentos:** Maximo 3 reintentos por activo fallido
|
|
4. **Timeout:** 30 segundos maximo por llamada API
|
|
5. **Datos Stale:** Marcar activo como stale si no se actualiza en 15 minutos
|
|
6. **Cache:** Las llamadas exitosas actualizan cache Redis (TTL: 5 min)
|
|
|
|
---
|
|
|
|
## Criterios de Aceptacion
|
|
|
|
```gherkin
|
|
Escenario: Actualizacion exitosa de activos prioritarios
|
|
DADO que el servicio Data Service esta corriendo
|
|
Y la API de Polygon.io esta disponible
|
|
CUANDO el batch job se ejecuta
|
|
ENTONCES los activos XAU, EURUSD y BTCUSD se actualizan
|
|
Y la tabla trading.symbols tiene datos recientes
|
|
Y se publica un evento por cada activo actualizado
|
|
|
|
Escenario: Respeto del rate limit
|
|
DADO que el rate limit es de 5 llamadas/minuto
|
|
CUANDO el batch intenta hacer mas de 5 llamadas
|
|
ENTONCES espera hasta que el minuto reinicie
|
|
Y registra la espera en los logs
|
|
|
|
Escenario: Activos secundarios en cola
|
|
DADO que hay 10 activos secundarios pendientes
|
|
Y quedan 2 llamadas API disponibles en el minuto
|
|
CUANDO el batch procesa la cola
|
|
ENTONCES solo se procesan 2 activos
|
|
Y los 8 restantes permanecen en cola para el siguiente ciclo
|
|
|
|
Escenario: Fallo de API
|
|
DADO que la API de Polygon.io retorna error 500
|
|
CUANDO el batch intenta actualizar un activo
|
|
ENTONCES registra el error en data_sources.data_sync_status
|
|
Y reintenta hasta 3 veces con backoff exponencial
|
|
Y notifica si todos los reintentos fallan
|
|
|
|
Escenario: Ejecucion manual del batch
|
|
DADO que el usuario tiene permisos de admin
|
|
CUANDO hace POST /api/data/batch/run
|
|
ENTONCES se ejecuta el batch inmediatamente
|
|
Y retorna el resultado del batch job
|
|
```
|
|
|
|
---
|
|
|
|
## Dependencias
|
|
|
|
### Tecnicas:
|
|
- **PolygonClient** (existente): `apps/data-service/src/providers/polygon_client.py`
|
|
- **APScheduler 3.x:** Programacion de jobs
|
|
- **asyncpg:** Conexion a PostgreSQL
|
|
- **aioredis:** Publicacion de eventos
|
|
- **aiohttp:** Cliente HTTP async
|
|
|
|
### Funcionales:
|
|
- **INT-DATA-001:** Integracion base de Data Service
|
|
- **OQI-006 ML Signals:** Consume datos actualizados
|
|
|
|
---
|
|
|
|
## Notas Tecnicas
|
|
|
|
### API Key
|
|
|
|
```
|
|
POLYGON_API_KEY=f09bA2V7OG7bHn4HxIT6Xs45ujg_pRXk
|
|
```
|
|
|
|
**Nota:** Esta key es para cuenta gratuita. Para produccion, considerar upgrade a plan Starter ($47/mes) para rate limit ilimitado.
|
|
|
|
### Endpoints de Polygon.io Utilizados
|
|
|
|
| Endpoint | Uso |
|
|
|----------|-----|
|
|
| `/v2/snapshot/locale/global/markets/forex/tickers/{ticker}` | Snapshot Forex/Commodities |
|
|
| `/v2/snapshot/locale/global/markets/crypto/tickers/{ticker}` | Snapshot Crypto |
|
|
| `/v3/snapshot?ticker.any_of={tickers}` | Universal snapshot (multiple) |
|
|
|
|
### Consideraciones de Performance
|
|
|
|
- Usar conexiones HTTP persistentes (connection pooling)
|
|
- Implementar circuit breaker para fallos de API
|
|
- Mantener metricas de latencia para monitoreo
|
|
- Considerar batch de snapshots cuando se tenga plan de pago
|
|
|
|
---
|
|
|
|
## Historias de Usuario Relacionadas
|
|
|
|
| ID | Titulo | SP |
|
|
|----|--------|-----|
|
|
| US-DATA-001 | Como sistema, quiero actualizar precios de XAU cada 5 min | 3 |
|
|
| US-DATA-002 | Como sistema, quiero actualizar precios de EURUSD cada 5 min | 3 |
|
|
| US-DATA-003 | Como sistema, quiero actualizar precios de BTC cada 5 min | 3 |
|
|
| US-DATA-004 | Como sistema, quiero encolar activos secundarios | 5 |
|
|
| US-DATA-005 | Como admin, quiero ejecutar batch manualmente | 2 |
|
|
| US-DATA-006 | Como sistema, quiero publicar eventos de actualizacion | 3 |
|
|
|
|
**Total Story Points: 19**
|
|
|
|
---
|
|
|
|
## Referencias
|
|
|
|
- [Polygon.io Documentation](https://polygon.io/docs)
|
|
- [INT-DATA-001: Data Service Base](../integraciones/INT-DATA-001-data-service.md)
|
|
- [INT-DATA-003: Batch Actualizacion Activos](../integraciones/INT-DATA-003-batch-actualizacion-activos.md)
|
|
|
|
---
|
|
|
|
**Creado por:** Orquestador Agent
|
|
**Fecha:** 2026-01-04
|
|
**Ultima actualizacion:** 2026-01-04
|