/simular_indexado
📈 Simulador Indexado
Simula el coste de un contrato indexado para un rango de fechas
arbitrario. Soporta 4 modos de consumo (cups,
total, periodos, curva_carga) y
cualquier geografía (PENINSULA, CANARIAS, BALEARES, CEUTA, MELILLA).
Devuelve energía y potencia desglosadas por periodo P1..P6.
📝 Descripción
A partir de un rango temporal y un tipo de consumo, el simulador:
- Recupera los perfiles horarios y componentes indexados para
(tarifa, geo_zone)en el rango pedido. - Aplica la fórmula del producto indexado hora a hora usando el
fee de campaña
(tarifa, tipo_campania)más el margen extra que se aporte. - Calcula el precio de potencia por periodo (€/kW·día), promediado con los tramos BOE que caigan dentro del rango (soporta rangos que crucen año natural).
- Devuelve el desglose de energía y potencia por periodo, y opcionalmente la curva horaria completa.
🔐 Autenticación
Cabecera Authorization: Bearer <TOKEN>. Acepta token
estático API_SECUR_TOKEN o JWT firmado con
JWT_SECRET / JWT_SECRET_1.
📥 Cuerpo de la petición
Campos requeridos
| Campo | Tipo | Descripción |
|---|---|---|
fecha_inicio |
string (YYYY-MM-DD) | Inicio del rango de simulación (inclusive). |
fecha_fin |
string (YYYY-MM-DD) | Fin del rango de simulación (inclusive). |
tipo_consumo |
string | Uno de: 'cups', 'total',
'periodos', 'curva_carga'
(este último aún no implementado: devuelve 501). |
Campos condicionales (dependen de tipo_consumo)
| Campo | Tipo | Cuándo aplica | Descripción |
|---|---|---|---|
cups |
string | si tipo_consumo='cups' |
CUPS del que leer datos técnicos y consumos desde SIPS.
tarifa_atr, geo_zone y
potencias_kw se leen automáticamente. |
tarifa_atr |
string | si tipo_consumo != 'cups' |
'2.0TD'..'6.4TD' o códigos '018'..'023'. |
potencias_kw |
object {P1..P6: number} | si tipo_consumo != 'cups' |
Potencias contratadas por periodo (kW). |
consumo_total_kwh |
number | si tipo_consumo='total' |
Consumo total del rango, se perfila proporcionalmente
al latest_profile del rango. |
consumo_periodos_kwh |
object {P1..P6: number} | si tipo_consumo='periodos' |
Consumo desglosado por periodo, se perfila dentro de cada periodo según el perfil horario. |
Campos opcionales
| Campo | Tipo | Default | Descripción |
|---|---|---|---|
geo_zone |
string | 'PENINSULA' |
Uno de 'PENINSULA', 'CANARIAS',
'BALEARES', 'CEUTA',
'MELILLA'. |
tipo_campania |
string | 'campaña' |
Valor aceptado por
prices.precios_campania_index_b2b
(habitualmente 'campaña' o 'Zero'). |
coste_financiero |
number | 0.25 |
% aplicado como (1 + cf/100) al final del
precio indexado horario. |
extra_margen_energia |
number | 0.0 |
€/MWh sumados al fee base antes de pérdidas. |
extra_margen_potencia |
object {P1..P6: number} | number | 0 |
€/kW·día sumados al precio BOE diario por periodo. Puede ser un dict o un escalar (aplicado a todos). |
incluir_curva_horaria |
boolean | false |
Si es true, añade la clave
curva_horaria a la respuesta con una lista
de records hora a hora. Aumenta mucho el tamaño de la
respuesta. |
Ejemplos de petición
Por CUPS (rango de 1 mes):
{
"fecha_inicio": "2026-02-01",
"fecha_fin": "2026-02-28",
"tipo_consumo": "cups",
"cups": "ES0021000013654684FH",
"tipo_campania": "campaña"
}
Sin CUPS, consumo total:
{
"fecha_inicio": "2026-02-01",
"fecha_fin": "2026-02-28",
"tipo_consumo": "total",
"geo_zone": "PENINSULA",
"tarifa_atr": "2.0TD",
"potencias_kw": {"P1": 4.4, "P2": 4.4},
"consumo_total_kwh": 200.0,
"tipo_campania": "campaña"
}
Sin CUPS, consumo por periodos con márgenes extra y curva horaria:
{
"fecha_inicio": "2026-02-01",
"fecha_fin": "2026-02-28",
"tipo_consumo": "periodos",
"geo_zone": "PENINSULA",
"tarifa_atr": "3.0TD",
"potencias_kw": {"P1": 15, "P2": 15, "P3": 15, "P4": 15, "P5": 15, "P6": 15},
"consumo_periodos_kwh": {
"P1": 1200, "P2": 900, "P3": 800, "P4": 700, "P5": 600, "P6": 500
},
"extra_margen_energia": 1.5,
"extra_margen_potencia": {"P1": 0.001, "P2": 0.001, "P3": 0.001,
"P4": 0.001, "P5": 0.001, "P6": 0.001},
"incluir_curva_horaria": true
}
📤 Respuesta exitosa (200 OK)
Estructura general:
{
"geo_zone": "PENINSULA",
"tarifa_atr": "3.0TD",
"num_dias": 28,
"tipo_campania": "campaña",
"coste_financiero": 0.25,
"fee_indexado_aplicado_eur_mwh": 13.55,
"energia": [
{
"periodo": "P1",
"consumo_kwh": 1200.0,
"coste_eur": 187.42,
"precio_medio_eur_mwh": 156.18,
"omie_md_avg": 68.35,
"ree_segmentos_avg": 8.20
},
{ "periodo": "P2", ... }, { "periodo": "P3", ... },
{ "periodo": "P4", ... }, { "periodo": "P5", ... }, { "periodo": "P6", ... }
],
"potencia": [
{"periodo": "P1", "potencia_kw": 15.0, "precio_eur_kw_dia": 0.063,
"coste_eur": 26.46},
...
],
"total_energia_eur": 812.34,
"total_potencia_eur": 132.28,
"total_eur": 944.62,
"curva_horaria": [ /* solo si incluir_curva_horaria=true — records hora a hora */ ]
}
curva_horaria es una lista de dicts (uno
por hora) con columnas market_date, market_hour,
periodo, consumo_kwh, precios y componentes
horarios (OMIE, REE segmentos, peajes, pagos por capacidad, fee, pérdidas,
factor de tasa municipal, precio horario). Útil para auditoría; puede
aumentar la respuesta a MB.
❌ Errores
| Código | Causa |
|---|---|
400 |
Validación: tipo_consumo inválido, faltan
tarifa_atr / potencias_kw sin CUPS,
falta consumo_* según el tipo,
tipo_campania inválido, rango de fechas
invertido, etc. |
401 |
Falta token o token inválido. |
501 |
tipo_consumo='curva_carga' (pendiente de
implementar). |
500 |
Error inesperado (traza en logs). |
💻 Ejemplos
cURL
curl -X POST "https://api.imaginaenergia.com/simular_indexado" \
-H "Authorization: Bearer <JWT>" \
-H "Content-Type: application/json" \
-d '{
"fecha_inicio": "2026-02-01",
"fecha_fin": "2026-02-28",
"tipo_consumo": "total",
"tarifa_atr": "2.0TD",
"potencias_kw": {"P1": 4.4, "P2": 4.4},
"consumo_total_kwh": 200,
"tipo_campania": "campaña"
}'
Python (requests)
import requests
body = {
"fecha_inicio": "2026-02-01",
"fecha_fin": "2026-02-28",
"tipo_consumo": "cups",
"cups": "ES0021000013654684FH",
"tipo_campania": "campaña",
}
r = requests.post(
"https://api.imaginaenergia.com/simular_indexado",
headers={"Authorization": f"Bearer {jwt}"},
json=body,
timeout=60,
)
data = r.json()
print("total €:", data["total_eur"])
for p in data["energia"]:
print(p["periodo"], p["consumo_kwh"], "kWh →", p["coste_eur"], "€")