DEDUPLICACIÓN Y COOLDOWNS
Deduplicar alertas de caída de Pinnacle.
Un solo precio en caída puede producir varias alertas de la API de cuotas de Pinnacle: el motor informa de cada caída que cruza tu umbral, los mercados en vivo se mueven cada pocos segundos, y un reinicio puede entregarte un lote que ya habías gestionado. Tres claves, una regla de cooldown y un pequeño almacén de estado convierten eso en una alerta por decisión.
Por qué una selección alerta más de una vez
El stream envía cada caída igual o superior a min_drop dentro de su propia ventana de detección. Un precio local que pasa a 2.10, luego a 1.98 y luego a 1.87 en veinte minutos cruza el 5% dos veces desde dos puntos de partida distintos, y ambos cruces son reales. En juego, la misma selección puede cambiar de precio en cada punto de un partido de tenis, así que una regla del 5% se dispara una y otra vez mientras el favorito se escapa en el set.
Los reinicios añaden una tercera fuente. Si tu proceso guarda su posición antes de terminar de gestionar un lote, las alertas de ese lote se gestionan otra vez cuando vuelve. La solución es el orden, no el filtrado: marca una alerta como hecha solo después de que haya salido el mensaje que depende de ella.
Tres claves, tres preguntas
Cada clave responde a una pregunta distinta, y un relay normalmente necesita las tres.
- La clave de la alerta es el campo
id. Dos alertas con el mismo id son la misma alerta; guarda durante un día los ids que ya has gestionado y omite las repeticiones. Esto cubre exactamente el caso del reinicio. - La clave de la selección es el partido más el mercado más el lado:
home,away,league,sect,outcomey el periodo, cuando el mercado tiene uno. Dos alertas con la misma clave de selección describen el mismo precio cayendo aún más. Sobre esta clave corre el cooldown. - La clave del evento es solo el partido. Úsala cuando basta un mensaje por partido, para un canal que quiere saber qué partidos se están moviendo y no qué lado.
La regla del cooldown
Después de que salga una alerta de una selección, ignora las siguientes alertas de esa selección hasta que termine un cooldown o el precio haya caído otro umbral completo desde el precio que informaste por última vez, lo que ocurra primero. La segunda cláusula importa: un cooldown por sí solo escondería un desplome de 2.10 a 1.70 detrás de un mensaje de 2.10 a 1.98 enviado un minuto antes.
state[key] = {last_price, alerted_at}
on alert for key:
seen = state.get(key)
if seen is None: send; store; return
fresh = now - seen.alerted_at < COOLDOWN
further = (seen.last_price - to_price)
/ seen.last_price >= MIN_DROP
if fresh and not further: return
send; store
Diez minutos van bien para los mercados prepartido, donde una línea deriva a lo largo de una tarde. Sesenta segundos van bien para los mercados en vivo, donde la misma regla se tragaría un set entero de tenis. Usa valores separados para en vivo y prepartido, ya que de todos modos llegan por streams separados. Para ver qué significa un porcentaje en términos de probabilidad antes de elegir un umbral, la calculadora de cuotas a la baja en pnclDATA convierte cualquier par de precios en el cambio que hizo el mercado.
Un almacén que sobrevive a los reinicios
El estado es diminuto: un pequeño registro por cada selección sobre la que has alertado, y un conjunto de ids de alerta. Redis con una caducidad de 24 horas sirve, y también una tabla SQLite con una columna expires_at que se barre una vez por hora. Cárgalo al arrancar, antes de abrir el stream, para que las primeras alertas tras un reinicio se juzguen contra los mensajes de ayer y no contra una memoria en blanco. Una cartelera prepartido en un día cargado produce unos pocos miles de selecciones, muy por debajo de cualquier cosa que necesite ajuste.
Agrupar lo que llega junto
Las alertas llegan en listas, y un evento suele aparecer con dos o tres resultados en la misma lista cuando un mercado cambia de precio en conjunto. Agrupa por la clave del evento dentro de cada lote y envía un mensaje que liste cada lado que se movió. Entre lotes, un buffer de cinco segundos recoge a los rezagados sin retrasar a nadie de forma apreciable. La parte de la entrega, incluido lo que hacen las plataformas de chat cuando publicas demasiado rápido, está en la página del relay por webhook.
Mide el efecto
Cuenta las alertas leídas y las alertas enviadas, por stream y por día. Un relay que envía una quinta parte de lo que lee se está comportando; uno que envía casi todo tiene un cooldown que nunca actúa, y uno que casi no envía nada tiene un umbral demasiado alto para los deportes que vigila. Registra los dos recuentos una vez por hora y los ajustes correctos aparecen en una semana.
Preguntas que plantea esta regla
¿El stream deduplica algo por sí mismo?
No repite una alerta con el mismo id, pero cada nuevo cruce del umbral es una alerta nueva con un id nuevo. La deduplicación por selección es tarea tuya.
¿Y los precios que suben?
El stream de caídas solo informa de caídas. Una selección cuyo precio vuelve a subir después de una caída no hace ruido; si necesitas ambas direcciones, consulta el mercado por REST o toma los frames en bruto del WebSocket.
¿El cooldown debería ser por deporte?
Por fase primero, por deporte después. En vivo y prepartido difieren mucho más que el tenis y el fútbol. Empieza con un valor para en vivo y otro para prepartido, y ajusta un deporte solo cuando su registro muestre un problema.
El comportamiento del stream sigue la documentación publicada por el proveedor, revisada el 26 de septiembre de 2026. Publicado el .