Publicado originalmente en medium.com

Las buenas decisiones nacen de buenos datos. Las malas decisiones nacen de un CSV que scrapeaste de una web que cambió de diseño hace tres semanas.
Eso es lo que nadie te cuenta cuando empiezas a construir algo relacionado con precios de acciones: conseguir los números es fácil. Conseguir números en los que puedas confiar de verdad, a escala, con años de histórico, sin que tu script se rompa cada vez que una web actualiza su frontend, es un problema distinto.
Si estás:
esta es la parte de tu stack que decide si el resto tiene algún sentido.
El instinto es comprensible. Yahoo Finance muestra el precio ahí mismo, en el navegador. ¿Por qué no simplemente scrapearlo?
Porque ese precio en la página no está pensado para ti. Está pensado para una persona leyendo un gráfico, y en el momento en que intentas automatizarlo, heredas todos los problemas que vienen con scrapear un sitio que nunca fue diseñado para funcionar como una API.
El diseño cambia sin aviso. Tu parser se rompe un martes cualquiera y no te enteras hasta que tu backtest devuelve números sin sentido. Los rate limits y los bloqueos por IP aparecen sin previo aviso y sin documentación que consultar. Y fuentes gratuitas como Yahoo Finance no garantizan que obtengas el mismo precio ajustado dos veces: pides la misma fecha histórica en dos días distintos y puedes obtener dos números diferentes, porque el ajuste se recalcula cada vez que ocurren nuevos splits o dividendos.
Nada de esto es un inconveniente menor. Si tu backtest está usando silenciosamente closes sin ajustar en la mitad de tu rango de fechas, tu Sharpe ratio es pura ficción.
Hay tres errores que comete casi todo el mundo la primera vez que toca datos bursátiles de forma programática:
**close** con **adjusted_close**. El close en bruto no tiene en cuenta splits ni dividendos. Si calculas retornos a partir del close sin ajustar, una acción que hizo un split 4:1 aparece como una caída del 75% en tu gráfico. No cayó. Tus datos sí.Conseguir precios de acciones nunca fue lo difícil. Conseguir precios consistentes, correctamente ajustados y bien documentados, con histórico suficiente para construir algo real, es lo que de verdad importa.
Aquí es donde una API de datos como es debido se gana su sitio.
EODHD cubre más de 150.000 tickers entre acciones, ETFs, fondos, índices, forex y cripto, con histórico de más de 30 años para muchos símbolos de EE. UU. (los datos de Ford empiezan en junio de 1972). Las barras están disponibles a nivel diario, semanal o mensual, y cada petición devuelve la serie de precios completa de un símbolo, o un rango de fechas recortado si defines uno.
Puedes probarla ahora mismo sin registrarte. La clave DEMO da acceso completo y sin restricciones a un puñado de tickers: AAPL.US, TSLA.US, VTI.US, AMZN.US, BTC-USD.CC y EURUSD.FOREX.
Si ya estás probando algo con un cliente, este es el empujón:
Pruébala antes de construir sobre ella
Prueba la API End-of-Day ahora mismo con la clave DEMO gratuita, sin necesidad de registro.
→ Consigue tu token de API
Una API REST con parámetros documentados, precios ajustados consistentes y 30 años de profundidad para los principales tickers de EE. UU.
A favor
adjusted_close consistente, calculado de la misma forma cada vez que lo consultasEn contra
Ideal para: cualquier cosa que necesite correr sin supervisión: backtests, dashboards, agentes, y que no pueda permitirse errores de datos silenciosos.
Parsear HTML de un sitio financiero en lugar de llamar a una API que no fue construida para exponerse así.
A favor
En contra
Ideal para: una comprobación manual puntual. Nada que pienses ejecutar dos veces.
El fallback gratuito más habitual, normalmente accedido a través de wrappers no oficiales en lugar de una API con soporte real.
A favor
En contra
Ideal para: prototipar rápido cuando la corrección de los datos todavía no importa.
Hay dos formas de hacerlo. requests en crudo, o la librería oficial eodhd.
import requests
url = "https://eodhd.com/api/eod/MCD.US"
params = {
"api_token": "YOUR_TOKEN",
"from": "2024-01-02",
"to": "2024-01-05",
"period": "d",
"fmt": "json"
}
response = requests.get(url, params=params)
data = response.json()
print(data)
Salida:
[
{
"date": "2024-01-02",
"open": 295.05,
"high": 297.28,
"low": 295.05,
"close": 297.04,
"adjusted_close": 279.9221,
"volume": 4458400
},
{
"date": "2024-01-03",
"open": 297,
"high": 297.99,
"low": 294.25,
"close": 294.39,
"adjusted_close": 277.4248,
"volume": 3114800
}
]
Fíjate en la diferencia entre close y adjusted_close. No es un bug, es el historial de dividendos de McDonald's incorporado al precio. close es el precio de mercado en bruto. adjusted_close tiene en cuenta tanto splits como dividendos, y volume está ajustado por splits. Si necesitas OHLC ajustado solo por splits (sin dividendos), es una llamada aparte al endpoint de Technical Indicators con function=splitadjusted.
Parámetros clave que conviene conocer:
period: d, w o m para barras diarias, semanales o mensualesorder: a para más antiguo primero, d para más reciente primerofilter: se salta toda la serie y devuelve un único valor suelto en su lugar; existen opciones como last_close, last_volume y similares. Útil si solo necesitas el número de hoy para una función de hoja de cálculo y no quieres parsear un array para ellopip install eodhd -U
from eodhd import APIClient
api = APIClient("YOUR_TOKEN")
resp = api.get_eod_historical_stock_market_data(
symbol="MCD.US",
period="d",
from_date="2024-01-02",
to_date="2024-01-05",
order="a"
)
print(resp)
Los mismos datos, con menos código repetitivo. La librería también envuelve fundamentales, datos intradía, splits, dividendos, consultas al screener e indicadores técnicos bajo un mismo cliente, así que si este es el primero de varios endpoints de EODHD que vas a tocar, merece la pena instalarla desde el principio.
Un array JSON en bruto está bien para un script. Para cualquier cosa que vayas a analizar, quieres tenerlo en pandas.
import pandas as pd
import requests
url = "https://eodhd.com/api/eod/AAPL.US"
params = {
"api_token": "YOUR_TOKEN",
"from": "2025-01-01",
"period": "d",
"fmt": "json"
}
data = requests.get(url, params=params).json()
df = pd.DataFrame(data)
df["date"] = pd.to_datetime(df["date"])
df.set_index("date", inplace=True)
annual_return = (df["adjusted_close"].iloc[-1] / df["adjusted_close"].iloc[0]) - 1
print(f"AAPL return: {annual_return:.2%}")
Nueve líneas, y ya tienes un DataFrame indexado por fecha, como es debido, con un cálculo de retorno que sí tiene en cuenta los eventos corporativos. Prueba lo mismo con un close en bruto sacado de una página scrapeada y observa cómo tu número se desvía en silencio cada vez que hay un split.
A partir de aquí puedes construir:
El endpoint EOD por sí solo es una simple extracción de datos. Conéctalo a un servidor MCP o a una API de conector, y se convierte en algo que un agente de IA puede consultar por su cuenta, sin que tengas que escribir una integración nueva cada vez que quieres hacer una pregunta distinta.
EODHD ofrece un servidor MCP oficial con dos versiones: v1 se autentica con una clave de API en la URL y funciona con ChatGPT, Claude Code y agentes personalizados. v2 corre sobre OAuth 2.1 con registro dinámico de clientes, pensado para Claude Desktop y otros clientes MCP con soporte nativo de OAuth. Cualquiera de las dos versiones expone 72 herramientas de solo lectura entre datos de mercado, fundamentales, noticias y técnicos, además de más de 100 páginas de documentación de la API incrustadas como recursos MCP, para que un agente pueda consultar nombres de parámetros y planificar su cobertura sin gastar una llamada a la API en ello.
En la práctica, eso significa que puedes apuntar a un agente al servidor y hacerle una pregunta en lenguaje natural en lugar de escribir una integración nueva para ella. Así se ve, llamando directamente a Claude con el servidor MCP de EODHD conectado:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
mcp_servers=[
{
"type": "url",
"url": "https://mcp.eodhd.com/v2/mcp",
"name": "eodhd-mcp"
}
],
messages=[
{
"role": "user",
"content": "Pull McDonald's daily closes for Q1 2024 and flag any day where volume was 3x the 30-day average."
}
]
)
print(response.content)
Sin lógica de tickers hardcodeada, sin script aparte para picos de volumen. El agente llama a la herramienta EOD, extrae la ventana que necesita, calcula la media móvil y marca los valores atípicos, todo dentro de una sola petición. Cambia la pregunta la semana que viene ("haz lo mismo con AAPL y TSLA, compáralos") y no hay código nuevo que escribir, solo un prompt distinto.
Ese es el cambio que la IA agéntica trae a los datos financieros: la API deja de responder solo a una pregunta fija y pasa a ser algo sobre lo que un agente puede razonar.
Si estás construyendo o asesorando sobre este tipo de stack, esto merece la pena probarlo directamente:
¿Estás construyendo un agente de IA que necesita datos financieros?
El servidor MCP de EODHD le da a tu agente acceso estructurado a más de 30 años de histórico de precios, sin necesidad de un wrapper de API personalizado.
→ Explora el servidor MCP
adjusted_close es el número que quieres para calcular retornos, no close. Confundir ambos es el error más común en este terreno.filter (last_close, last_volume, etc.) evita parsear la serie completa cuando solo necesitas un número._¿Existe una API gratuita de datos bursátiles end-of-day?
_Sí. El plan gratuito de EODHD incluye la API End-of-Day con 20 llamadas al día, limitada al último año de histórico. La clave DEMO da acceso ilimitado a seis tickers de prueba sin necesidad de registro.
_¿Cuál es la diferencia entre close y adjusted_close?
_close es el precio de mercado en bruto de ese día. adjusted_close incorpora cada split y dividendo posterior, de modo que los precios históricos se mantienen comparables a lo largo del tiempo. Usa siempre adjusted_close para calcular retornos y hacer gráficos.
_¿Puede un agente de IA consultar estos datos directamente?
_Sí, a través del servidor MCP oficial de EODHD. Expone 72 herramientas mediante el Model Context Protocol para que agentes como Claude puedan pedir datos de mercado, fundamentales y técnicos directamente en una conversación, sin una integración de API personalizada.
¿Buscas contenido técnico para tu empresa? Puedo ayudarte — LinkedIn · kevinmenesesgonzalez@gmail.com
¿Quieres ver más análisis como este?
Escribo sobre APIs fintech, Python y herramientas de agentes de IA.
→ Visita kevinmeneses.com