Inicio / Artículos

Un agente de trading de LangChain respaldado por datos de mercado EODHD en tiempo real, paso a paso

Por qué los agentes de trading basados en LLM fracasan sin datos reales, cómo funciona el bucle ReAct y cómo crear un agente LangChain con tres herramientas basadas en precios EODHD, fundamentales y RSI.

Editor: REACTAPP.TOP8 min de lectura1769 palabras

Fuentes: Building a Trading Agent with LangChain and the EODHD API

Muchos de los llamados agentes de trading basados en IA que se muestran en videos en realidad no son agentes. Son modelos de lenguaje con instrucciones bien redactadas y números inventados. Un verdadero agente necesita tres cosas: capacidad de razonamiento, herramientas para actuar y datos en tiempo real para no generar ilusiones. Si se omite lo tercero, los dos primeros apenas importan. Está dirigido a quienes crean agentes para análisis financiero, conectan LangChain con datos reales del mercado, o que han probado un “bot de trading” basado en LLM y se dieron cuenta de que, sin datos fiables, no es más que teatro.

En resumen, un agente es un LLM al que se le proporcionan herramientas (funciones) y la libertad de decidir cuándo y cómo utilizarlas, en lugar de responder basándose únicamente en el conocimiento adquirido durante su entrenamiento. LangChain es un framework de Python que conecta el modelo, las herramientas, la memoria y el ciclo de toma de decisiones en una sola unidad ejecutable. EODHD ofrece lo que ningún modelo tiene por defecto: precios en tiempo real, datos fundamentales, indicadores técnicos y noticias financieras recientes, a través de una API REST. Juntos, forman un agente capaz de responder “¿Debería este valor estar en mi radar ahora mismo?” utilizando datos actuales y no información obsoleta.

El modelo no es el punto débil

Pídale a cualquier LLM el precio actual de una acción y producirá un número. Ese número podría estar desactualizado desde hace meses o simplemente ser falso. Los modelos no tienen acceso en tiempo real al mercado, no saben qué ocurrió ayer ni han visto el último informe financiero, y sin embargo muchos proyectos los utilizan como si lo tuvieran. Los resultados son predecibles: recomendaciones basadas en datos antiguos, fundamentales inventados presentados con total confianza, y análisis técnico calculado sobre precios que nunca existieron.

Nada de eso demuestra que el modelo sea malo en finanzas. El problema es que nadie le proporciona las entradas adecuadas. Un modelo sin herramientas es como una biblioteca sin ventanas: abundante conocimiento, pero sin visión del día de hoy. Un modelo más grande no soluciona eso. Lo que sí lo hace es el acceso a datos externos verificables, junto con la posibilidad de permitir que el modelo decida cuándo buscarlos. Para eso sirve un agente.

La tecnología utilizada

LangChain se encarga de la lógica del agente. Toma la pregunta del usuario, elige una herramienta, ejecuta la llamada, interpreta el resultado y escribe una respuesta. No hay nada mágico en ello, solo un bucle de razonamiento con reglas.

EODHD cubre la brecha de datos. A través de su API, el agente puede obtener precios OHLCV en tiempo real e históricos, datos fundamentales de la empresa como ratios, balances y ingresos, indicadores técnicos como RSI, promedios móviles y MACD, además de noticias con el sentimiento del mercado. Las razones para elegirlo para este tipo de automatización son prácticas: su cobertura abarca bolsas de todo el mundo y no solo la NYSE y NASDAQ. Los datos fundamentales, técnicos y las noticias están en endpoints separados, por lo que cada uno puede convertirse en una herramienta independiente. Además, la versión gratuita es lo suficientemente generosa como para prototipar antes de escalar.

Evaluando EODHD como capa de datos

Cualquier proveedor de datos merece una evaluación honesta antes de ser integrado en un agente. Por el lado positivo, los precios, los fundamentales, los indicadores técnicos y las noticias se incluyen bajo un único plan de facturación, por lo que no es necesario combinar tres proveedores diferentes. Muchas alternativas gratuitas, como los scrapers basados en Yahoo y los planes limitados de Alpha Vantage, solo cubren valores estadounidenses, mientras que EODHD accede a decenas de bolsas, lo cual es importante para acciones fuera de Estados Unidos. Las respuestas están estructuradas en JSON con campos predecibles (close, change_p, PERatio, etc.), por lo que las capas de integración son sencillas y nada depende de un análisis HTML frágil. Puede crear y probar todo el agente, incluyendo los precios, los fundamentales y el RSI, antes de realizar el pago. Los límites de uso están documentados y son predecibles, lo cual es crucial cuando un agente puede llamar a una herramienta varias veces para responder a una misma pregunta.

Existen desventajas. La versión gratuita tiene límites diarios en las solicitudes, lo cual es adecuado para una lista de seguimiento personal, pero insuficiente para un servicio de producción con varios usuarios. Las actualizaciones de datos fundamentales se realizan según el horario del proveedor, no en cuanto se publican los resultados financieros, un límite común a todas las APIs de datos fundamentales pero relevante si su agente depende del análisis del mismo día. Además, la descripción de las herramientas sigue siendo responsabilidad suya: una herramienta de LangChain mal escrita seguirá siendo llamada en el momento equivocado o mal interpretada por el modelo, independientemente de la calidad de la API. Para un agente de razonamiento que necesita datos financieros estructurados reales sin un proceso de extracción, los compromisos favorecen una API alojada sobre una capa de datos hecha en casa.

Cómo funciona el bucle de razonamiento

La mayoría de los tutoriales omiten cómo funciona mecánicamente un “agente”. Un agente de LangChain que utiliza el patrón ReAct (Razonamiento más Acción) ejecuta un bucle con cuatro partes.

  1. El LLM, que lee la pregunta y las descripciones de las herramientas y elige el siguiente paso a seguir.
  2. Las herramientas, funciones llamables cada una con un nombre, una descripción y entradas/salidas esperadas, como get_live_price, get_fundamentals y get_rsi.
  3. El ejecutor, que realmente ejecuta la herramienta solicitada, devuelve la salida al modelo y le permite elegir qué hacer a continuación.
  4. El bloc de notas, un registro en tiempo real de los pasos de pensamiento, acción y observación dentro de una misma consulta, para que el modelo recuerde lo que ya ha verificado.

Una pregunta como “¿Deberíamos estar analizando AAPL.US ahora?” genera una cadena como esta. Primero, el modelo solicita el precio:

Thought: I need the current price first.
Action: get_live_price("AAPL.US")
Observation: AAPL.US: current price 227.50, change +0.8%

Luego decide que el precio por sí solo dice poco y pasa a analizar el impulso y la valoración:

Thought: Price alone isn't enough — check momentum.
Action: get_rsi("AAPL.US")
Observation: AAPL.US — RSI(14): 58.3Thought: Not overbought. Check if valuation is reasonable.
Action: get_fundamentals("AAPL.US")
Observation: AAPL.US — PE: 31.2, Market Cap: 3.4T, Dividend Yield: 0.4%Thought: I now have enough data to answer.
Final Answer: [synthesized response]

Ese es el vacío arquitectónico entre un agente y un chatbot con una instrucción de sistema. El modelo elige el orden de las llamadas a las herramientas en tiempo de ejecución según lo que revela cada observación, y no hay un script fijo involucrado. También es por eso que la calidad y la estructura de la fuente de datos son tan importantes. Si get_fundamentals devuelve números defectuosos o obsoletos, todo razonamiento basado en ellos hereda el error sin ninguna advertencia visible. Cada paso del razonamiento depende de la fiabilidad del anterior, lo cual es la razón principal por la cual los agentes financieros necesitan una API real y estructurada en lugar de datos extraídos o almacenados en caché.

Desarrollándolo

El agente cuenta con tres herramientas vinculadas a EODHD: precio en tiempo real, fundamentales e indicadores técnicos. Comience instalando los paquetes:

pip install langchain langchain-openai requests

Las herramientas en sí son funciones sencillas. Cada una se conecta a un único endpoint de EODHD y devuelve una salida estructurada y limpia para que el modelo la lea:

import requests
from langchain.tools import tool
EODHD_API_KEY = "YOUR_API_KEY"
BASE_URL = "https://eodhd.com/api"
@tool
def get_live_price(ticker: str) -> str:
    """Returns the current price of a stock. Example ticker: AAPL.US"""
    url = f"{BASE_URL}/real-time/{ticker}"
    params = {"api_token": EODHD_API_KEY, "fmt": "json"}
    r = requests.get(url, params=params).json()
    return f"{ticker}: current price {r['close']}, change {r['change_p']}%"
@tool
def get_fundamentals(ticker: str) -> str:
    """Returns key fundamental metrics: PE ratio, market cap, dividend yield."""
    url = f"{BASE_URL}/fundamentals/{ticker}"
    params = {"api_token": EODHD_API_KEY}
    r = requests.get(url, params=params).json()
    highlights = r.get("Highlights", {})
    return (
        f"{ticker} - PE: {highlights.get('PERatio')}, "
        f"Market Cap: {highlights.get('MarketCapitalization')}, "
        f"Dividend Yield: {highlights.get('DividendYield')}"
    )
@tool
def get_rsi(ticker: str) -> str:
    """Returns the 14-day RSI to assess overbought or oversold conditions."""
    url = f"{BASE_URL}/technical/{ticker}"
    params = {"api_token": EODHD_API_KEY, "function": "rsi", "period": 14, "fmt": "json"}
    r = requests.get(url, params=params).json()
    latest = r[-1]
    return f"{ticker} - RSI(14): {latest['rsi']} as of {latest['date']}"

Luego, arme el agente a partir de un modelo de chat, las herramientas y una prompt de ReAct:

from langchain_openai import ChatOpenAI
from langchain.agents import create_react_agent, AgentExecutor
from langchain import hub

llm = ChatOpenAI(model="gpt-4o", temperature=0)
tools = [get_live_price, get_fundamentals, get_rsi]

prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

Eso son tres herramientas: un LLM y un bucle que elige entre ellas según la pregunta. Su llamada se ve así:

response = executor.invoke({
    "input": "Should we be looking at AAPL.US right now?"
})
print(response["output"])

El agente no responde basándose en la memoria. Primero llama a get_live_price, luego a get_rsi, y a get_fundamentals cuando es importante la valoración; después combina los resultados de los tres en una respuesta basada en datos reales y no en una alucinación formatada de forma convincente. Las extensiones naturales incluyen un agente para múltiples acciones que compara varias acciones en una sola consulta, un sistema que incorpora noticias a través del endpoint de sentimiento, y un servicio de alertas horarias que revisa una lista de seguimiento.

Qué llevarse como aprendizaje

Un agente sin datos reales es un generador de texto persuasivo, no una herramienta de análisis. LangChain se encarga de la orquestación, y una API de datos fiable se ocupa del problema subyacente, que es la información financiera actual y confiable. En un agente ReAct, cada paso hereda la fiabilidad de los datos del anterior, por lo que la capa de datos es tan importante como el prompt. Además, las herramientas simples con una sola responsabilidad cada una escalan mejor que intentar incluir toda la lógica en un único prompt enorme.

A continuación se presentan algunas preguntas frecuentes. ¿Qué es un agente en un entorno de trading? Es un sistema en el que el LLM elige qué herramientas utilizar, desde precios hasta datos fundamentales y noticias, para completar una tarea con datos reales y no solo conocimientos adquiridos mediante entrenamiento. ¿Por qué LangChain en lugar de llamar directamente a la API? Porque gestiona el ciclo de toma de decisiones, es decir, determina qué herramienta usar, cuándo y cómo combinar varios resultados, algo que de lo contrario tendría que programarse manualmente para cada caso. ¿Se necesita una cuenta pagada de EODHD para probar esto? No, la versión gratuita es suficiente para crear prototipos. ¿Cuál es el principal compromiso al optar por esta solución en lugar de crear su propio pipeline? Se renuncia al control total sobre la obtención de datos a cambio de velocidad y fiabilidad, con una API estructurada que reemplaza a los scrapers o a varias integraciones con proveedores; el límite a considerar es el tope diario de la versión gratuita una vez que se deja atrás la fase de prototipado.

Lecturas relacionadas

  • Entrenar un modelo personalizado en Azure ML y llamarlo desde un agente Foundry — Entrenar, registrar e implementar un modelo de abandono de clientes en un endpoint gestionado por Azure ML, y luego exponerlo a un agente Foundry como FunctionTool, con información sobre autenticación y uso en producción.
  • Notas prácticas: Crear un agente de investigación avanzada con LangChain Deep Agents y — Guía paso a paso de las notas prácticas: Crear un agente de investigación avanzada con LangChain Deep Agents y, que incluye contratos, verificaciones y espacios de código listos para usar por parte de los equipos que implementan este patrón.
  • Un asistente para documentos en dos archivos de Python: ChromaDB, LangChain y Claude — Convierte un PDF de 187 páginas con estándares dbt en un asistente buscable mediante un script de ingestión, embeddings locales de Hugging Face, ChromaDB y respuestas de Claude basadas en los documentos.