PythonSistemasMáquinas de estadoSeñales

Cuando tu clasificador parpadea: histéresis para señales que oscilan

Publicado el 2026-07-17 · Xiliux

Tienes una señal que a cada observación te dice en qué estado estás: un monitor de salud que dice OK o CAÍDO, un detector de conectividad, un clasificador de modo. Y cerca del umbral oscila: OK, CAÍDO, OK, CAÍDO, OK. Cada cambio dispara algo —una alerta, un failover, entrar o salir de una posición— y de repente tu sistema está temblando por ruido, no por una transición real.

Es el mismo problema que resuelve el termostato de tu casa desde hace un siglo, y la solución tiene nombre: histéresis. No cambies de estado hasta que el nuevo se haya sostenido.

La regla, en una frase

Un estado nuevo solo se confirma tras repetirse N observaciones consecutivas. Si el candidato cambia o revierte antes de llegar a N, la cuenta se reinicia. El estado vigente se mantiene estable; los parpadeos se ignoran.

Lo empaqueté como librería —hysteresis-state, Python puro, sin dependencias— porque lo reescribía una y otra vez:

from hysteresis_state import HysteresisState

estado = HysteresisState("OK", confirmations=3)

for lectura in stream:                 # "OK" / "CAIDO"
    actual = estado.update(lectura)    # solo cambia tras 3 lecturas seguidas
    if estado.changed:                 # ¿esta lectura provocó la transición?
        alertar(actual)

Aliméntalo con OK, CAÍDO, OK, CAÍDO, OK y no pasa nada: ningún candidato se sostuvo. Hacen falta tres CAÍDO seguidos para que el cambio se confirme.

El detalle que casi siempre falta: histéresis asimétrica

Un umbral único tiene un problema sutil. Si exiges 3 confirmaciones para entrar en fallo, también tardas 3 en salir — y a veces quieres justo lo contrario: caer rápido a lo seguro, volver despacio a lo arriesgado. Es el comportamiento de un disyuntor eléctrico: salta a la primera, se rearma con cautela.

Se resuelve dejando que el umbral dependa de la transición:

# 1 confirmación para caer a "CAIDO", 5 para volver a "OK"
conf = lambda desde, hacia: 1 if hacia == "CAIDO" else 5
estado = HysteresisState("OK", confirmations=conf)

estado.update("CAIDO")   # cae al instante
# ...ahora hacen falta 5 "OK" seguidos para volver

Por qué no basta con "promediar"

La tentación es suavizar con una media móvil y umbralizar. Funciona para señales numéricas, pero se rompe con estados discretos (no promedias OK y CAÍDO), introduce retardo en todas las transiciones por igual, y no te da la asimetría de arriba. La histéresis por confirmación es la herramienta correcta cuando lo que oscila es una etiqueta, no un número.

De dónde salió

Esto nació dentro de un bot de trading. Su cerebro de régimen clasificaba el mercado en tendencia / rango / caos, y cerca de los umbrales parpadeaba: cada parpadeo congelaba o reactivaba la operativa, que es exactamente lo que no quieres que pase por ruido. La histéresis lo calmó. Pero el mecanismo no sabe nada de mercados —es anti-flapping para cualquier señal discreta—, así que lo liberé.

Es software libre. Desde agosto de 2026 el código no se publica en registros ni en GitHub —trabajamos en seguridad y que nos extraigan el fuente sería un argumento en contra del producto—: se entrega a pedido, con firma y SHA-256, en contacto@xiliux.com.

Código y tests (con los casos límite del conteo y la asimetría, verificados por mutación): **.

Preguntas frecuentes

¿Qué es la histéresis, en una frase?

No cambies de estado hasta que el candidato nuevo se haya repetido N veces seguidas. Si cambia o revierte antes de llegar a N, la cuenta se reinicia. El estado vigente se mantiene estable; el parpadeo se ignora. Es lo que hace el termostato de tu casa desde hace un siglo.

¿Cómo elijo N (las confirmaciones)?

N cambia reactividad por estabilidad: un N alto ignora más ruido pero reacciona más lento a una transición real. Elígelo según cuántas lecturas falsas seguidas ves cerca del umbral; 2–3 mata la mayor parte del parpadeo, más alto para señales muy ruidosas.

¿Dónde sirve además de en monitorización?

En cualquier sitio donde un clasificador ruidoso dispare una acción: health checks (OK/CAÍDO), detectores de conectividad, un cambio de régimen de trading que entra/sale de una posición, un clasificador de modo. Donde un tembleque cerca del umbral no debería disparar algo costoso.

¿Añade retraso a las transiciones reales?

Sí, a propósito: una transición real se confirma N observaciones tarde. Es el precio de ignorar el ruido, y es el trade correcto cuando un cambio en falso cuesta más que reaccionar unas observaciones tarde.

← Ver más artículosCotizar un proyecto