| # FINNHUB.md β Modulo de noticias financieras |
|
|
| Fuente de titulares financieros para el pipeline de IA. Consulta la API REST de Finnhub (free tier) y proporciona noticias filtradas por relevancia al mercado analizado. |
|
|
| **No expone endpoints REST publicos.** Es un modulo interno consumido unicamente por `signals/aiPipeline.js` durante la generacion de senales (cada 5 min). |
|
|
| --- |
|
|
| ## Variables de entorno |
|
|
| | Variable | Obligatoria | Descripcion | |
| |---|---|---| |
| | `FINNHUB_API_KEY` | No | API key de Finnhub (finnhub.io). Sin ella el modulo devuelve array vacio y el pipeline usa rule-based. | |
|
|
| --- |
|
|
| ## API interna |
|
|
| ### `getMarketNews(category, limit)` |
|
|
| **Archivo:** `src/finnhub/finnhub.client.js` |
|
|
| Obtiene noticias generales del mercado por categoria. |
|
|
| **Parametros** |
|
|
| | Param | Tipo | Default | Descripcion | |
| |---|---|---|---| |
| | `category` | string | `"general"` | Categoria: `general`, `forex`, `crypto`, `merger` | |
| | `limit` | int | `50` | Maximo de noticias a devolver | |
|
|
| **Retorno:** `Promise<Object[]>` β array de noticias normalizadas. |
|
|
| **Noticia normalizada:** |
|
|
| ```json |
| { |
| "id": 12345, |
| "headline": "Fed signals potential rate cut...", |
| "summary": "The Federal Reserve hinted at...", |
| "url": "https://example.com/news/12345", |
| "source": "Reuters", |
| "related": "AAPL", |
| "datetime": "2026-05-15T14:30:00.000Z" |
| } |
| ``` |
|
|
| --- |
|
|
| ### `getCompanyNews(symbol, daysBack)` |
|
|
| **Archivo:** `src/finnhub/finnhub.client.js` |
|
|
| Obtiene noticias de una empresa especifica en un rango de fechas. |
|
|
| **Parametros** |
|
|
| | Param | Tipo | Default | Descripcion | |
| |---|---|---|---| |
| | `symbol` | string | β | Simbolo bursatil (ej. `AAPL`, `TSLA`, `BTC`) | |
| | `daysBack` | int | `7` | Dias hacia atras desde hoy | |
|
|
| **Retorno:** `Promise<Object[]>` β noticias normalizadas de la empresa. |
|
|
| --- |
|
|
| ### `fetchFinancialNews(daysBack)` |
|
|
| **Archivo:** `src/finnhub/finnhub.service.js` |
|
|
| Agrega noticias de multiples categorias (`general`, `forex`, `crypto`) para el pipeline de IA. |
|
|
| **Parametros** |
|
|
| | Param | Tipo | Default | Descripcion | |
| |---|---|---|---| |
| | `daysBack` | int | `7` | No aplica directamente; se usa el rango por defecto de Finnhub | |
|
|
| **Retorno:** `Promise<Object[]>` β hasta 90 noticias agregadas (50 general + 20 forex + 20 crypto). |
|
|
| --- |
|
|
| ### `filterNewsByRelevance(news, question)` |
|
|
| **Archivo:** `src/finnhub/finnhub.service.js` |
|
|
| Filtra noticias por keywords extraidas de la pregunta del mercado. Elimina stop words en ingles y espanol; matching case-insensitive. |
|
|
| **Parametros** |
|
|
| | Param | Tipo | Descripcion | |
| |---|---|---| |
| | `news` | Object[] | Array de noticias normalizadas | |
| | `question` | string | Pregta del mercado (ej. "Will Bitcoin reach $100k?") | |
|
|
| **Retorno:** `Object[]` β noticias que contienen al menos una keyword en `headline` o `summary`. |
|
|
| --- |
|
|
| ### `fetchHeadlinesForPipeline({ symbols, daysBack, limitPerSymbol })` |
|
|
| **Archivo:** `src/finnhub/finnhub.service.js` |
|
|
| Obtiene noticias de multiples simbolos en paralelo, truncando a maximo 5 simbolos para respetar el rate limit. |
|
|
| **Parametros** |
|
|
| | Param | Tipo | Default | Descripcion | |
| |---|---|---|---| |
| | `symbols` | string[] | `[]` | Lista de simbolos bursatiles | |
| | `daysBack` | int | `7` | Dias hacia atras | |
| | `limitPerSymbol` | int | `20` | Maximo de noticias por simbolo | |
|
|
| **Retorno:** `Promise<Object[]>` β noticias agregadas con campo `symbol` anadido. |
|
|
| **Limitacion:** si `symbols.length > 5`, se trunca a 5 y se emite warning en logs. |
|
|
| --- |
|
|
| ## Pipeline de noticias dentro de la generacion de senales |
|
|
| ``` |
| scheduler.js (cada 5 min) |
| β |
| aiPipeline.run(market) |
| β Paso 1: Obtener noticias |
| fetchFinancialNews() β general + forex + crypto |
| β Paso 2: Filtrar por relevancia |
| filterNewsByRelevance(news, market.question) |
| β Paso 3: Filtrar por sentimiento (FinBERT) |
| filterWithFinBERT(headlines) |
| β Paso 4: Generar senal (Qwen3-8B / OpenRouter / rule-based) |
| ``` |
|
|
| **Nota:** si Finnhub no esta configurado o falla, los pasos 1-2 devuelven array vacio y el pipeline continua con rule-based usando el precio del mercado. |
|
|
| --- |
|
|
| ## Rate limiter y restricciones |
|
|
| | Restriccion | Implementacion | |
| |---|---| |
| | **Free tier: 60 llamadas/min** | Rate limiter en memoria en `finnhub.client.js`. Si se excede, devuelve `[]`. | |
| | **Sin API key** | `ensureApiKey()` devuelve `false`; todas las funciones retornan `[]` sin lanzar error. | |
| | **Sin endpoints REST** | El modulo es puramente interno; no se expone via HTTP. | |
| | **Limite de 5 simbolos** | `fetchHeadlinesForPipeline` trunca `symbols` a 5 para no saturar el rate limit. | |
| | **Errores de red** | Capturados internamente; se loguean como `warn` y se retorna `[]`. | |
|
|
| **Calculo de uso tipico:** |
| - `fetchFinancialNews()` = 3 llamadas (general + forex + crypto) |
| - Top 20 mercados cada 5 min = 20 x 3 = 60 llamadas/5min (en el limite exacto del free tier) |
|
|
| --- |
|
|
| ## Ejemplo de uso interno |
|
|
| ```js |
| // Desde aiPipeline.js |
| import { fetchFinancialNews, filterNewsByRelevance } from '../finnhub/finnhub.service.js'; |
| |
| async function run(market) { |
| // 1. Obtener noticias |
| const allNews = await fetchFinancialNews(30); |
| |
| // 2. Filtrar por relevancia respecto al mercado |
| const relevant = filterNewsByRelevance(allNews, market.question); |
| |
| // 3. Continuar con FinBERT + Qwen3-8B... |
| } |
| ``` |
|
|
| --- |
|
|
| ## Logs esperados |
|
|
| ``` |
| # Sin API key configurada |
| [DEBUG] Finnhub API key not configured, returning empty array |
| |
| # Rate limit excedido |
| [WARN] Finnhub rate limit exceeded (60 calls/min), returning empty array |
| |
| # Pipeline continua sin noticias |
| [WARN] news fetch failed, continuing without news |
| ``` |
|
|
| --- |
|
|
| ## Archivos del modulo |
|
|
| ``` |
| backend/src/finnhub/ |
| βββ finnhub.client.js # Cliente HTTP + rate limiter |
| βββ finnhub.service.js # Logica de negocio y filtrado |
| ``` |
|
|
| --- |
|
|
| *Ultima actualizacion: mayo 2026* |
|
|