Skip to content
← Volver al BlogIA y Agentes

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 < 20evita pagar de más por el crecimiento.
  • Deuda/Patrimonio < 100%descarta ROE inflado por apalancamiento.
  • RSI > 30excluye sobreventa, sin techo para no penalizar el momentum.
  • Precio > media móvil de 50 díasconfirma 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 next

Eso 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.

Share this article