Saltar al contenido

Guía · Python · pandas

Dividendos y cuentas de la bolsa española en Python

El calendario de dividendos, diez años de cuentas anuales y los ratios de cualquier cotizada española, en un DataFrame, con la fuente de cada cifra.

1. Pide tu clave gratis

En la documentación, al momento y sin tarjeta: 100 peticiones al día. La clave va siempre en la cabecera Authorization: Bearer, nunca en la URL.

2. Un cliente de diez líneas

Sólo hace falta requests (y pandas para las tablas). Guarda la clave en la variable de entorno DIVR_API_KEY.

import os
import requests
import pandas as pd

API = "https://api.divr.es"
SESION = requests.Session()
SESION.headers["Authorization"] = f"Bearer {os.environ['DIVR_API_KEY']}"

def divr(ruta, **params):
    r = SESION.get(API + ruta, params=params, timeout=30)
    if r.status_code != 200:
        raise RuntimeError(r.json()["error"])
    return r.json()

3. El calendario de dividendos en un DataFrame

d = divr("/v1/events", **{"from": "2026-11-01", "to": "2026-12-31"})
pagos = pd.DataFrame([{
    "empresa": m["security"]["company"],
    "isin": m["security"]["isin"],
    "bruto": m["amount_gross"]["value"],
    "ex_date": m["ex_date"]["value"],
    "pago": m["payment_date"]["value"],
} for m in d["market"]]).sort_values("pago")
print(pagos)

Una petición trae todos los pagos de la bolsa española entre dos fechas (hasta 400 días).

4. Diez años de beneficio de una empresa

d = divr("/v1/issuers/TEF.MC/annual")
beneficio = pd.Series({
    y["year"]: y["fields"].get("net_income", {}).get("value")
    for y in d["years"]
}, name="net_income")
print(beneficio)

Las cuentas anuales salen del XBRL que cada empresa deposita en la CNMV, desde 2016. Si un año no tiene la cifra, value es None y reason dice por qué.

5. Ratios con su fórmula

d = divr("/v1/issuers/TEF.MC/ratios")
for y in d["years"]:
    r = y["ratios"]["payout_ratio"]
    print(y["year"], r["value"], r.get("reason", ""))

Cada cifra de la respuesta es un objeto: el número está en value, y al lado va de dónde sale (origin, quote) o por qué falta (reason). Lo explica la documentación.

Errores y cupo

Un 404 issuer_not_ingested es transitorio; issuer_no_source, permanente. Con el plan gratuito, la respuesta 101 del día es 429 rate_limited, y X-RateLimit-Remaining dice cuántas quedan. Todos los códigos, en la documentación. Para generar un cliente tipado, la spec está en /openapi.json.

Sigue