Construyendo mis primeros agentes de IA: los screeners del S&P 500 y el IBEX 35
Septiembre 2026 · 6 min de lectura · Por Javier Audibert
Trabajé como la única persona de finanzas en un par de startups: si un sistema no existía, lo construía yo. Ese mismo instinto es el que me llevó a construir mi primer agente de IA. No fue un proyecto de "quiero aprender machine learning", fue: quiero un informe cada lunes que me diga qué empresas merecen mi tiempo esta semana.
Hoy son dos herramientas que corren solas cada semana: el Quality Screener del S&P 500 y el del IBEX 35. Criban el índice entero por fundamentales y técnicos, y un agente de IA investiga en la web y escribe el informe final. Cero servidor: el repositorio de GitHub es la base de datos y el portal lo lee en directo.
Una aclaración antes de seguir: estos screeners son proyectos personales, construidos en mi tiempo libre para aprender. No son trabajo profesional, no están asociados a ningún empleador ni cliente, y nada de lo que publican es asesoramiento de inversión. Son una herramienta para decidir a qué empresas dedico yo mi propio tiempo de análisis — nada más.
El filtro: 6 criterios antes de tocar la IA
Cada ejecución descarga los componentes del índice desde Wikipedia y los pasa por seis criterios — cuatro fundamentales y dos técnicos, vía yfinance:
- ROE > 20% — el filtro de calidad clásico.
- ROA > 12% — filtro duro en el S&P 500; en el IBEX 35 no, y luego explico por qué.
- P/E < 20 — evita pagar de más por el crecimiento.
- Deuda/Patrimonio < 100% — descarta ROE inflado por apalancamiento.
- RSI > 30 — excluye sobreventa, sin techo para no penalizar el momentum.
- Precio > media móvil de 50 días — confirma tendencia alcista.
De 500 empresas suelen sobrevivir una veintena. Eso importa: el modelo razona mucho mejor sobre 20 empresas preseleccionadas que sobre 500 sin filtrar.
El agente: Groq y un bucle de tool-use
Aquí está lo que convierte esto en un agente y no en un script más. El filtro es determinista: mismos datos, mismo resultado. El agente no — le das un objetivo y unas herramientas, y es él quien decide en cada paso si necesita usarlas. Uso Groq con gpt-oss-120b y le doy una sola herramienta: búsqueda de noticias por ticker, declarada como un esquema JSON de function-calling.
messages = [{"role": "user", "content": prompt_analista}]
while True:
response = client.chat.completions.create(
model="openai/gpt-oss-120b",
messages=messages,
tools=tools,
tool_choice="auto",
)
tool_calls = response.choices[0].message.tool_calls
if not tool_calls:
return response.choices[0].message.content # done — final report
messages.append(response.choices[0].message)
for tool_call in tool_calls:
ticker = json.loads(tool_call.function.arguments)["ticker"]
messages.append({"role": "tool", "tool_call_id": tool_call.id,
"name": "buscar_noticias_web",
"content": buscar_noticias_web(ticker)})
# loop again — the model sees the results and decides what's nextEso es todo. Ese while True de veinte líneas es el agente: un modelo, una herramienta y un bucle que da vueltas hasta que el propio modelo decide que ya no necesita nada más. Sin frameworks, sin orquestadores.
Lo que más me sorprendió al ejecutarlo por primera vez: el modelo no sigue un guion. Decide ticker a ticker cuándo buscar, y encadena varias llamadas antes de escribir. Fue la primera vez que un script mío se sintió menos como código y más como delegar una tarea.
Todo el pipeline vive en GitHub Actions: un cron semanal (0 6 * * 1, lunes 06:00 UTC) que ejecuta el screener y commitea el JSON de vuelta al repositorio. No hay servidor ni base de datos que mantener.
El segundo agente: qué significa «calidad» en cada mercado
Para el IBEX 35 la tentación era copiar el archivo entero. En vez de eso, extraje todo lo que no depende del índice — indicadores, filtro, herramienta y bucle del agente — a un módulo común. Cada screener se quedó en unas 40 líneas: cómo obtener sus tickers y una llamada al runner genérico.
run_pipeline(obtener_tickers_fn=obtener_tickers_sp500, ..., roa_minimo=0.12) # hard filter run_pipeline(obtener_tickers_fn=obtener_tickers_ibex35, ..., roa_minimo=None) # not a filter
La diferencia más interesante no es técnica, es de criterio financiero. El IBEX 35 está lleno de bancos y utilities, sectores donde un ROA bajo es estructural del negocio, no una señal de mala calidad. Aplicar el umbral del S&P 500 habría descartado sectores enteros por razones que no dicen nada sobre esas empresas. El código solo necesitaba un parámetro; el trabajo real fue decidir cuál era el criterio correcto.
Los agentes no son solo para gente de IT
Nunca me he considerado ingeniero. Construyo cosas por necesidad, y por eso creo que este patrón importa fuera del software: un agente no es más que un modelo, unas herramientas bien definidas y un bucle. Un analista de marketing puede montar el mismo patrón para decidir cuándo consultar analíticas antes de redactar un informe; alguien en soporte, para buscar en la base de conocimiento antes de responder un ticket. Cambia la herramienta, no el bucle.
Y lo que más me ha quedado de estos dos proyectos pequeños: la parte difícil nunca fue la IA. Fue tener criterio claro sobre mi propio dominio — qué hace que una empresa sea de calidad, y por qué esa definición cambia entre Wall Street y el Ibex. Eso no lo automatiza nadie por ti, y es justo lo que ya hace a diario cualquier profesional de finanzas, marketing u operaciones. Construir el agente es, comparado con eso, la parte fácil.
Ver los agentes en producción →
Share this article