
Energy Market Data: ingesta energética con datos que se puedan defender
Descargar una cifra de una API es una operación pequeña. Convertirla en una referencia que otra aplicación pueda utilizar exige responder preguntas más difíciles: de qué día es, en qué unidad está expresada, si es definitiva y qué ocurrirá cuando repitamos la descarga.
En IXATU, Energy Market Data nace para construir un histórico propio y homogéneo de referencias energéticas. Reúne electricidad, almacenamiento de gas y referencias de mercados mediante adaptadores Python, y persiste las medidas en Supabase/PostgreSQL.
Este artículo recoge el diseño y las lecciones documentadas el 3 de septiembre de 2026, cuando el recolector estaba en validación contra fuentes reales. La integración con Operations y la verificación de la programación automática seguían pendientes. Conviene conservar ese contexto para entender qué decisiones estaban implementadas y qué quedaba por demostrar.
Un productor con una responsabilidad concreta
El recolector se mantiene independiente de Operations. Su responsabilidad es conocer las fuentes externas, interpretar sus respuestas y guardar medidas válidas. Una aplicación consumidora debería recibir un contrato comprensible sin tener que reproducir las particularidades de cada proveedor.
OMIE · ESIOS · GIE · Yahoo Finance
↓
Adaptadores Python
↓
Normalización y validación
↓
Persistencia común
↓
Supabase / PostgreSQL
Esa separación permite trabajar sobre la fiabilidad de la captura antes de añadir una pantalla. También mantiene la ingesta fuera de la lógica de clientes, contratos y suministros del sistema operativo.
La implementación descrita utiliza la API REST de datos de Supabase. Las credenciales privilegiadas pertenecen al proceso servidor. La futura integración con Operations se plantea a través de su API y un modelo de lectura propio, sin entregar esas credenciales al navegador.
Una forma común sin borrar el significado
Las fuentes llegan con estructuras diferentes, pero convergen en un formato largo: cada fila representa una medida. Sus campos básicos son fecha, variable, valor, unidad y fuente, junto con el momento de inserción.
| Origen | Referencias recogidas | Distinción que debemos conservar |
|---|---|---|
| OMIE | Precio de España por periodo y media diaria derivada | El dato solicitado corresponde al día siguiente |
| ESIOS / REE | PVPC y una referencia spot | La respuesta debe contener valores del día objetivo |
| GIE, AGSI y ALSI | Almacenamiento de gas, inyección, extracción y llenado de GNL | La política del recolector exige registros confirmados |
| Yahoo Finance | TTF, Brent y Henry Hub | Se utiliza el último cierre disponible en la ventana consultada |
La homogeneidad de almacenamiento no hace intercambiables esas cifras. Un precio eléctrico, un porcentaje de llenado y un futuro sobre una materia prima mantienen unidades y calendarios distintos. Incluso dos variables expresadas en EUR/MWh pueden representar referencias diferentes.
La fecha del dato forma parte del contrato
En el adaptador OMIE descrito, la descarga busca el resultado day-ahead para mañana. Si todavía no está publicado, la ejecución falla. Sustituirlo silenciosamente por el día actual haría que el proceso pareciese funcionar mientras cambia el significado de su salida.
En un día ordinario, el conjunto recogido contiene 96 periodos de quince minutos y una media diaria calculada por el adaptador. Esa media es un dato derivado: debe distinguirse de los valores leídos del fichero de origen. El comportamiento en cambios de hora y días de estructura temporal excepcional estaba pendiente de validación; 96 periodos no debe elevarse sin más a una regla universal.
Con las referencias de mercados ocurre otra cosa: el último cierre disponible puede pertenecer a un día anterior. La fecha de la observación debe viajar con el valor. Ejecutar hoy un proceso no convierte todas sus medidas en datos de hoy.
Idempotencia para poder repetir
La identidad elegida por el proyecto es (fecha, variable). La persistencia realiza un upsert: si ya existe la medida, la actualiza; si no existe, la inserta. Repetir una descarga no debería acumular duplicados del mismo dato.
La elección implica que cada variable tiene un significado definido dentro de ese contrato. La fuente se conserva como procedencia, aunque no forme parte de la clave. Si en el futuro se quisieran almacenar versiones o varias observaciones equivalentes de distintos proveedores, habría que revisar esa identidad explícitamente.
El upsert resuelve la repetición de escrituras, pero no demuestra que el valor sea correcto ni conserva por sí mismo todas sus versiones históricas. La calidad se comprueba antes de llegar a esa frontera.
Para trabajo local existe una salida CSV cuando faltan ambas variables de configuración de Supabase. Una configuración parcial produce un error. Es una distinción útil: un entorno local deliberadamente desconectado tiene un comportamiento definido; una configuración incompleta necesita corregirse. Es el mismo criterio de explicitud que aplicamos a la configuración por entornos.
Rechazar una cifra imposible
Una de las lecciones más concretas surgió con un porcentaje de almacenamiento que llegaba fuera de rango. Dividirlo por cien producía un número plausible. Pero una cifra plausible no es evidencia de que hayamos interpretado bien la fuente.
El workaround se revocó. La política adoptada fue seleccionar el registro confirmado, comprobar que el valor sea numérico y finito, y validar su rango. Si continúa siendo incoherente, la ingesta debe fallar de forma visible.
En ALSI, el porcentaje se deriva de inventario y capacidad. Antes de calcularlo hay que comprobar la calidad del registro, que ambos operandos sean finitos y que el denominador sea positivo. Después se valida el resultado. Un cálculo que no provoca una excepción puede seguir produciendo una medida inaceptable.
La nota operativa también identificaba una fila histórica afectada por la transformación descartada, pendiente de corrección. Cambiar el adaptador protege las próximas ejecuciones; reparar los datos ya persistidos requiere una acción separada y evidencia del valor correcto.
Esta distinción conecta con la Legacy Discovery Pipeline: observar una anomalía, explicar su significado y decidir cómo tratarla son pasos distintos. Automatizarlos sin esa separación puede convertir una suposición en un dato de negocio.
Probar el código y comprobar la fuente
Los tests offline permiten comprobar parsers, validaciones, respuestas vacías y reglas de persistencia. No demuestran que una fuente externa haya publicado el dato esperado ni que acepte una petición desde el entorno donde se ejecutará el proceso.
Durante la validación se observó, por ejemplo, una respuesta 403 de ESIOS desde un runner alojado y después una ejecución correcta desde ese mismo tipo de entorno. La observación justificaba seguimiento; no bastaba para atribuir una causa definitiva ni diseñar un workaround permanente.
La automatización también debe respetar ventanas de publicación diferentes. La configuración propuesta separaba la captura de electricidad y mercados de la captura posterior de GIE. En el estado documentado aún faltaba verificar esa programación desde la rama por defecto y contrastar muestras de varios días con las fuentes.
Lo que debe recibir el consumidor
Antes de añadir un dashboard o integrar el recolector con Operations, necesitamos poder explicar cada medida: qué representa, a qué fecha corresponde, de dónde procede y qué comprobaciones superó. También debemos distinguir una ausencia, un dato atrasado y un error de captura.
El objetivo práctico de Energy Market Data es construir esa base pequeña y auditable. Su fiabilidad depende tanto de aceptar un dato correcto como de rechazar uno que no podemos justificar. Cuando llegue la integración, ese contrato permitirá que Operations use referencias energéticas sin heredar las incertidumbres que el productor todavía debe resolver.