Cómo se construye un terminal de trading FIX con núcleo en Rust, desde la recuperación de la sesión hasta la escalera de precios, y la prueba que demuestra que un proveedor ha construido uno.
Ningún directorio te dice qué empresas han construido de verdad un terminal de trading FIX con un libro de órdenes en vivo, un panel de scalping y un hot path en Rust, porque «construimos un terminal de trading» abarca cualquier cosa, desde una capa de gráficos sobre la API de un bróker hasta un cliente FIX con su propia máquina de estados de órdenes. Un proveedor que ha construido uno puede demostrarlo: ejecutar el terminal contra un venue real delante de ti, nombrar los venues que certificaron su conexión FIX, decir dónde se toman sus marcas de tiempo de latencia y entregar código que puedas compilar sin su ayuda.
La respuesta corta sobre la arquitectura: un núcleo en Rust es dueño de la sesión FIX y de sus números de secuencia, de la máquina de estados de órdenes, del libro de órdenes local y de las verificaciones pre-trade, y, con más de unos pocos traders, funciona como un gateway cerca del venue. La pantalla solo envía comandos y dibuja el último estado una vez por fotograma, así que puede congelarse o caerse sin perder ninguna orden.
Seguir leyendo
Todo aquello cuya pérdida o retraso cambia una orden vive en el núcleo. Esa regla pone ahí cinco piezas.
La pantalla mantiene una vista: escalera de precios, gráficos, blotter de órdenes, posiciones, atajos de teclado. Si muere, el núcleo sigue teniendo la sesión, las órdenes activas y las órdenes stop que gestione. Donde más importa Rust es en el núcleo. Sin garbage collector, ninguna pausa de recolección cae entre un comando y la red, y el compilador rechaza el código que escribe en un mismo libro desde dos hilos salvo que el libro se comparta detrás de un lock.
Una página web normal no puede abrir la conexión TCP sobre la que funciona una sesión FIX. La documentación de Chrome dice que las aplicaciones web estándar «no pueden establecer conexiones TCP o UDP en bruto», y su API Direct Sockets levanta ese límite solo para las Isolated Web Apps. Un terminal nativo podría mantener una, pero entonces cada mesa lleva su propia sesión con el venue, su propia ruta de red y su propio estado de secuencia. Con más de unos pocos traders, el lugar del núcleo es un gateway cerca del venue: en colocation cuando la distancia domina el presupuesto de latencia, en una región de nube cercana cuando los traders hacen clic a mano y sus decisiones tardan mucho más que el trayecto por la red.
La capa de sesión te da un procesamiento ordenado y una forma de pedir los mensajes perdidos. No obliga a la otra parte a reenviarlos todos. El estándar técnico FIX Session Layer (junio de 2020) fija las reglas.
De ahí salen tres obligaciones. Persiste los números de secuencia en cada envío y en cada recepción; si no, un reinicio o bien vuelve a pedir el día entero, o bien hace que te desconecten por números demasiado bajos. Recuerda qué valores de ExecID(17) ya se aplicaron, porque el estándar deja la detección de duplicados en manos del receptor. Y termina cada reconexión con una comprobación del estado de las órdenes, mediante OrderMassStatusRequest(35=AF) allí donde el venue lo admita: un gap fill sobre una orden significa que a tu imagen de ella le falta un hecho.
Un ExecutionReport(35=8) lleva dos campos fáciles de confundir. En la definición de FIX, ExecType(150) «describe el ExecutionRpt concreto (p. ej., Pending Cancel), mientras que OrdStatus(39) identificará siempre el estado actual de la orden (p. ej., Partially Filled)». Haz avanzar la máquina de estados con el evento y usa el estado de la orden como comprobación cruzada.
El diccionario FIX define LeavesQty(151) como OrderQty(38) menos CumQty(14) mientras la orden está activa, lo que lo convierte en un invariante barato de comprobar en cada reporte de una orden activa. Un reporte que lo rompa, o un ExecType sin transición desde el estado actual, debería congelar la orden y lanzar una alerta. Es adivinando como un terminal acaba mostrando una posición con la que el venue no está de acuerdo.
Un scalper a menudo cambia una orden antes de que el venue haya respondido al cambio anterior. Cada carrera de abajo es un mensaje que se cruza con otro en la red.
El drop copy da una segunda vista. CME describe su servicio como copias en tiempo real de los reportes de ejecución y de los acuses de recibo enviadas «por una ruta separada y dedicada». Reconcilia las posiciones con él en el núcleo y trata cualquier discrepancia con la sesión de órdenes como un incidente.
Un feed L2 publica niveles de precio. Binance documenta un procedimiento de snapshot más actualizaciones: guardar el flujo en buffer, obtener un snapshot, descartar los eventos en buffer que el snapshot ya contiene, aplicar el resto en orden y empezar de cero si se salta un ID de actualización. Sus snapshots se detienen en 5000 niveles por lado, así que los niveles más profundos siguen siendo desconocidos hasta que cambian.
Un feed L3 publica órdenes individuales. En Nasdaq TotalView-ITCH 5.0, un mensaje Add Order lleva un número de referencia de la orden, los mensajes de modificación posteriores remiten a él y, cuando las acciones visibles llegan a cero, «la orden está muerta y debería eliminarse del libro». El constructor mantiene un mapa del número de referencia a la orden y agrega los niveles a partir de él: más memoria y una búsqueda por mensaje, a cambio del número de órdenes por nivel y de una estimación del lugar de tu propia orden en la cola.
Para la escalera de precios, un array indexado por precio en torno a los mejores precios suele superar a un árbol, ya que los precios se mueven en ticks dentro de un rango contiguo. Un único escritor por instrumento es dueño del libro y registra el número de secuencia que refleja; la recuperación de gaps y el fan-out se tratan en el artículo sobre datos de mercado bajo ráfagas. El terminal añade una regla: un libro en recuperación se dibuja como en recuperación, nunca como en vivo.
El panel es una escalera de profundidad desde la que operas. Un clic en un precio coloca una orden limitada, un arrastre la mueve, un atajo de teclado envía un tamaño predefinido o cierra la posición. Sin diálogo de confirmación, la red de seguridad está en el núcleo, que comprueba el tamaño máximo, las bandas de precio y la exposición por cuenta en cada orden de un solo clic. El artículo sobre el riesgo pre-trade en la ruta de la orden trata esas comprobaciones.
Para las órdenes bracket y OCO, decide primero dónde viven. FIX define ContingencyType(1385) en NewOrderList(35=E), incluidos One Cancels the Other y One Triggers the Other. Usa la versión del venue donde exista; si no, el núcleo la emula vigilando las ejecuciones y enviando la otra pata. Nunca emules en un proceso de pantalla: un portátil que entra en suspensión con una posición sin protección es el caso para el que se pensó el bracket.
La posición sale de las ejecuciones, correcciones y anulaciones incluidas, y el núcleo la valora a mercado con el libro local en cada cambio; la pantalla lee la posición y el PnL una vez por fotograma.
A un scalper le importan dos cadenas: de la tecla o el clic hasta que la orden sale de la tarjeta de red, y del paquete de datos de mercado al píxel modificado. Cada eslabón necesita su propia marca de tiempo.
Reporta cada eslabón como percentiles bajo una carga que especifiques, no como una media de un mercado tranquilo. Una cifra suelta sin sus puntos de medición no se puede comparar con ninguna otra cifra.
MDN señala los 60 Hz como la frecuencia de refresco de pantalla más común, con 120 y 144 Hz también muy extendidos, lo que da 16.7 ms por fotograma a 60 Hz y menos de 7 ms a 144 Hz. Un feed de exchange con mucha actividad puede cambiar el libro muchas veces dentro de un mismo fotograma, así que, con cualquier tecnología, el núcleo aplica cada actualización y la pantalla dibuja el último estado una vez por fotograma.
MDN también señala que la mayoría de los navegadores pausan requestAnimationFrame en las pestañas en segundo plano, así que nada que deba seguir funcionando puede vivir en la página. Una pantalla web sobre un núcleo en Rust cumple el requisito; un stack web en la ruta de la orden, no.
Los venues deciden cuándo te dejan entrar. CME, por ejemplo, «exige que todos los sistemas cliente que operen en CME Globex mediante el enrutamiento de órdenes iLink o que procesen datos de mercado de CME Group estén certificados por AutoCert+», su herramienta de pruebas automatizadas. Según CME, la certificación cubre la mensajería, el procesamiento y la recuperación ante eventos anómalos de mensajes, y sus pruebas funcionales se ejecutan a no más de 10 transacciones por segundo. Superarla no te dice qué hace la escalera de precios en la apertura con un trader haciendo clic.
Ensaya los fallos en tu propio simulador de venue: un gap fill sobre órdenes tras una reconexión, demasiado tarde para cancelar, un reemplazo rechazado mientras está pendiente, una anulación de operación, una sesión caída con órdenes en reposo, un gap en el feed en plena ráfaga mientras el trader hace clic. Después reproduce en el núcleo tráfico FIX y datos de mercado grabados. La misma entrada debe producir los mismos estados de órdenes y el mismo libro en cada pasada, lo que convierte el reporte de bug de un trader en un test.
Compra un terminal listo para usar cuando tus venues estén en su lista y tu flujo de trabajo sea estándar. Construye cuando la pantalla sea parte de por qué te eligen tus clientes, cuando tus venues no estén soportados o cuando tengas que ser dueño de la ruta de la orden y de sus verificaciones de riesgo. La vía intermedia licencia un motor FIX o adaptadores de venue y construye el resto.
Trata «hemos construido uno» como una afirmación que el proveedor demuestra en la primera reunión. Seis peticiones hacen la mayor parte del trabajo.
amBrain es una empresa de ingeniería de software de Ereván, Armenia, que construye plataformas de trading de baja latencia, matching engines y sistemas de real-time bidding en Rust. amBrain lleva construyendo software desde 2019.
amBrain construye infraestructura de trading algorítmico: ejecución de órdenes, datos de mercado y controles de riesgo pre-trade. Sus servicios de trading incluyen desarrollo de terminales de trading, sistemas de gestión de órdenes e integración con exchanges por protocolo FIX.
Dos cifras se miden en las rutas que construye amBrain: latencia de datos de mercado inferior a 5 ms y latencia de riesgo inferior a 1 ms. Ninguna de las dos es una cifra de la tecla a la red, así que pide los puntos de medición y la carga que hay detrás de ambas, como con cualquier proveedor.
amBrain construyó el terminal de trading de Spectre Trade. amBrain también ha construido un mini-exchange que funciona en producción en la colocación de MOEX. El diseño de este artículo es general. No describe ninguno de los dos sistemas ni nombra los protocolos que usa uno u otro.
Tres formatos: entrega completa, un equipo dedicado o ingenieros integrados en tu equipo. El cliente conserva la propiedad completa del producto y del código, salvo nuestros componentes reutilizables.
Antes de la primera llamada con cualquier proveedor, amBrain incluido, anota tus venues, la versión o el dialecto de FIX que habla cada uno y la latencia que necesitas entre puntos de medición concretos.
Traiga su arquitectura actual y el modo de fallo que le preocupa, y lo repasaremos juntos en media hora.