Quant500 Academy

6. Errores, reintentos y reconexión en producción

Nivel 13: Conectar con Brokers Reales

Un sistema de trading en vivo pasa la mayor parte de su vida gestionando cosas que no salen como esperaba. La calidad de un sistema no se mide por lo que hace cuando todo va bien, sino por cómo se comporta cuando falla la red.

Los códigos de respuesta y qué hacer con cada uno

No todos los errores se tratan igual, y esta es la clasificación que necesitas:

import random

def peticion_con_reintentos(func, intentos=5):
    for i in range(intentos):
        try:
            r = func()
            if r.status_code == 429 or r.status_code >= 500:
                espera = (2 ** i) + random.random()
                time.sleep(espera)
                continue
            return r
        except requests.exceptions.RequestException:
            espera = (2 ** i) + random.random()
            time.sleep(espera)
    raise RuntimeError('Peticion fallida tras agotar los reintentos')

El caso peligroso: el timeout al enviar una orden

Aquí está la trampa más seria de todo el nivel. Si envías una orden y la petición expira por timeout, no sabes qué ha pasado. Puede que la orden nunca llegara al exchange. Pero también puede que llegara, se aceptara perfectamente, y lo que se perdiera fuera solo la respuesta de vuelta. Los dos escenarios son indistinguibles desde tu lado.

Reintentar a ciegas en esa situación puede duplicar tu posición. La respuesta correcta tiene dos partes:

1. Consultar antes de reintentar. Ante un timeout en un envío de orden, no reenvíes: pregunta. Consulta GET /orders y las ejecuciones recientes para averiguar si la orden existe. Solo si confirmas que no llegó, reenvía.

2. Usar un identificador de cliente. La mayoría de APIs permiten adjuntar un client_oid: un identificador único que tú generas para esa orden concreta. Si reenvías con el mismo identificador, el exchange reconoce que es la misma orden y no la duplica. Eso convierte el envío en una operación idempotente: repetirla no cambia el resultado.

La regla general: las operaciones de lectura son seguras de reintentar; las de escritura solo lo son si son idempotentes.

Reconexión del canal de datos

Una conexión WebSocket se cae. Siempre. Un cliente serio implementa:

Y la pregunta que cierra el módulo: si pierdes la conexión con una posición abierta, ¿qué debe hacer el sistema? La respuesta razonable es dejar de generar señales nuevas, intentar reconectar, y al recuperar la conexión resincronizar el estado real antes de tomar ninguna decisión. Operar a ciegas con datos obsoletos es peor que no operar.

El resto de Quant500

Lo que estás aprendiendo, aplicado al índice todos los días:

La cartera del modelo, cada semana en tu correo

Cada sábado, su semana en un minuto: cómo fue, lo mejor y lo peor, y qué directivos compraron con su dinero. Y el día que el modelo se rehace, qué entra y qué sale. Es una simulación, no un consejo. Como mucho un correo a la semana, sin publicidad y sin cuenta; te das de baja con un clic. Lo hace una persona: Pol Gracia.

Cartera modelo con resultados simulados, no una recomendación personalizada. Tu correo se usa solo para esto: privacidad.

Detrás de la Academia y del resto de Quant500 hay una sola persona: Pol Gracia Serrahima.