- Caso de un proyecto personal en el que se construyó con Go un bot de trading minorista que monitorea en tiempo real más de 5,500 acciones listadas en NYSE y NASDAQ y ejecuta operaciones automáticas
- Al inicio apenas servía para perder dinero rápidamente, pero tras años de prueba y error evolucionó hasta alcanzar el punto de equilibrio, e incluso a veces generar ganancias
- Está compuesto por tres componentes clave: proveedor de datos, aplicación en Go y bróker; durante la apertura y el cierre del mercado procesa en memoria más de 60,000 eventos por segundo
- Las lecciones prácticas incluyen pruebas del sistema con compras aleatorias, generación propia de velas basada en tick bars y la migración completa a memoria
- Un ejemplo que muestra la complejidad real y el potencial de construir una plataforma personal de trading en la intersección de finanzas, programación y análisis de datos
Contexto y motivación del proyecto
- La idea surgió de seguir tendencia ejecutando y administrando automáticamente unas 500 operaciones de corto plazo en todo el mercado accionario, buscando pequeñas ganancias en cada una
- Se empezó a automatizar por las limitaciones del trading manual
- Era extremadamente riesgoso invertir todo en una sola acción, pero monitorear al mismo tiempo decenas de apuestas de corto plazo estaba fuera de la capacidad humana
- Solo era posible entrar y salir rápido en acciones con alta liquidez, y para lograr ejecuciones veloces había que comprar cantidades pequeñas
- La gestión de posiciones también era un gran reto: con más de 25 apuestas simultáneas, acertar el momento de entrada y salida era muy complejo
- Había además un problema de escalabilidad: a medida que crecía el capital, también tenía que aumentar el número de apuestas
- Era necesario calcular rápidamente costos de operación como spread, comisiones, slippage, tarifas de API e impuestos para decidir si una operación valía la pena
Arquitectura de la solución
- Durante varios años se desarrolló una herramienta automatizada capaz de monitorear en tiempo real más de 5,500 acciones de NYSE y NASDAQ y tomar decisiones de trading rápidas
- Corre en un sistema Linux de alto rendimiento: 16 núcleos, 128 GB de RAM, 8 TB de almacenamiento NVMe e internet de 1 Gbps
-
Tres componentes clave
- Data Provider (Massive.com): cubre datos históricos y en tiempo real de todo el mercado, con una API y documentación intuitivas y amigables para desarrolladores. Tiene un modelo de precios simple que permite acceder a todos los datos del mercado sin limitaciones artificiales
- Aplicación en Go: el motor principal que recopila e interpreta los feeds de datos, toma decisiones de trading calculadas y envía órdenes de compra y venta a la API del bróker
- Broker (Interactive Brokers): se encarga de ejecutar las órdenes mediante una API sencilla
-
Por qué elegir Go
- Aunque la industria de hedge funds depende de C++ y Python, tras años de usar Go se eligió porque mostró una gran compatibilidad con el procesamiento de streams de datos y la integración con APIs
Funciones principales de la aplicación en Go
-
Data Ingestion Loop
- Recopila de forma continua datos en tiempo real de más de 5,500 acciones a través de Massive.com
- Al principio se intentó almacenar en una base de datos, pero no podía manejar más de 60,000 eventos por segundo durante la apertura y el cierre del mercado, así que se cambió por completo a un enfoque en memoria
-
Build Our View Of The Stock Market
- Construye una vista en memoria en tiempo real de todo el mercado con los datos recopilados, rastreando precio, spread, actividad de trading y más
- Permite detectar y operar oportunidades antes que las noticias convencionales
- Da acceso a la actividad de trading de premarket, mercado regular y after-hours
-
BUY Signal Loop
- Cuando detecta una oportunidad, envía una solicitud de orden de compra a la API del bróker
- No se limita a un disparador simple: realiza cálculos previos como estimación de ganancia basada en spread, definición del número de acciones necesarias e inclusión de comisiones e impuestos
- Incluye lógica para cambios de precio, fills parciales, cancelaciones de órdenes y otros casos
-
Position Tracking System
- Un loop que monitorea continuamente las posiciones abiertas y sigue la ganancia o pérdida comparando en tiempo real la tabla de posiciones con el precio actual
- A través de la GUI se puede ver por qué se activó una operación, su estado actual y cuándo vender
- Cumple un papel clave para refinar la lógica de BUY y SELL
-
SELL Signal Loop
- Ejecuta órdenes de venta vía la API del bróker cuando detecta una buena ganancia o una pérdida excesiva
- Incluye lógica compleja como actualizaciones de precio en acciones de movimiento rápido y manejo de fills parciales
Interfaz web y capturas de pantalla
- La interfaz web integrada permite explorar todas las estructuras de datos, visualizar datos y revisar las razones de activación de las operaciones y su estado actual
- Pantalla de vista general de todo el mercado que muestra precio, spread y más de 5,500 tickers
- Página de un símbolo individual (por ejemplo, Tesla TSLA) con tick bars e información relacionada
- Interfaz que muestra la proporción de ganancias/pérdidas y las posiciones abiertas actuales (en la sesión de ejemplo se registró una pérdida de alrededor de -$900)
- Pantalla con metadatos y gráficos de operaciones en tiempo real (el punto de compra se marca con una línea naranja)
- Pantalla de logs de consola que registra eventos en tiempo real, como órdenes de compra y venta
Desarrollo de estrategia y backtesting
- La aplicación en Go, la estrategia y el backtesting se consideran tres elementos centrales separados
- Aunque la mayoría de las conversaciones se enfocan en la estrategia (mean reversion, seguimiento de tendencia, regresión lineal, etc.) y el backtesting, suele pasarse por alto la implementación práctica y la logística de aplicar estrategias en trading intradía en tiempo real
- Se usan los amplios datos históricos de trades y quotes de Massive.com para explorar estrategias y hacer backtesting en Python (de ahí el uso del almacenamiento NVMe de 8 TB)
- El backtesting se compara con “conducir hacia adelante mirando por el retrovisor”, pero sigue siendo una validación útil para juzgar spread, impuestos, comisiones y puntos de entrada y salida
- Los hallazgos del desarrollo de estrategia y el backtesting se transforman en la lógica del BUY Signal Loop
Ejemplos de código
- Incluye pseudocódigo de alto nivel y muestras de código real en Go (la aplicación real tiene unas 7,000 líneas de código)
- Estructuras de datos principales: TrackedSymbols (mapa de todos los símbolos, bandera de trading habilitado, lock global), Symbol (datos crudos de trades y quotes, Aggregate, Position, etc.), TradeEvent, QuoteEvent, Aggregate y Position
- Estructura del loop principal
- Recopila datos de trades y quotes a través de una conexión WebSocket y parsea los eventos
- Los guarda en el mapa de símbolos y luego fusiona los datos de trades + quotes en Aggregate
- Envía señales a la lógica de compra y venta mediante channels de Go
- Proporciona, mediante un servidor HTTP, funciones para consultar todos los símbolos, posiciones y watchlists personalizadas
Lecciones clave (Lessons Learned)
-
Entender las abstracciones
- NYSE y NASDAQ no son un sistema único, sino un gran sistema distribuido compuesto por más de 19 bolsas
- Los datos de velas son una enorme abstracción construida a partir de datos crudos de trades (ticks), y entender eso a fondo es esencial
- Se aplican reglas distintas según el horario de negociación, como premarket, mercado regular y after-hours
-
Gestión de órdenes
- El trading exitoso no depende solo de enviar órdenes simples de compra y venta; también influyen el position sizing previo, la capacidad de operar rápido, la gestión simultánea de más de 25 posiciones, el cálculo de impuestos y comisiones, el control del slippage y el monitoreo del estado de las órdenes
-
Casos límite
- Existen innumerables casos límite: ejecución, seguimiento, modificación y cancelación de órdenes, fills parciales, halts de mercado, etc.; si se pasan por alto, provocan pérdidas reales
- Es indispensable probar con paper trading (simulación) en vez de usar dinero real
- Hubo una experiencia comprando en el máximo una acción que había subido 40% en premarket y luego se desplomó; por no ajustar bien la orden de venta, se produjo una pérdida del 40% en pocos minutos. En premarket y after-hours las reglas difieren del mercado regular y pueden ocurrir movimientos extremos muy rápido
-
Uso de compras aleatorias
- Más importante que descubrir una estrategia secreta es probar las funciones centrales del sistema
- Si durante una semana se hacen 1,000 compras aleatorias de acciones al día, se puede validar eficazmente la lógica de compra y venta, el manejo de fills parciales, la lógica de cancelación y el sistema de seguimiento de posiciones
- Integrar compras aleatorias en el proceso de prueba dentro de una cuenta de paper trading es una forma eficiente de validar varios aspectos del sistema al mismo tiempo
-
Tick bars vs time bars
- Las velas que entrega el bróker cubren marcos temporales fijos (por ejemplo, 30 segundos), pero cuando el mercado se mueve con fuerza se mezclan 100 operaciones y miles de operaciones dentro del mismo periodo
- Al construir barras propias basadas en número de operaciones usando datos crudos de ticks y quotes, se obtiene mucha mayor resolución en momentos de alta actividad como la apertura y el cierre del mercado, además de poder agregar métricas personalizadas como el spread
-
Migración a memoria
- El enfoque inicial basado en base de datos no podía soportar los picos masivos de actividad al abrir y cerrar el mercado
- Se migró completamente a un enfoque en memoria usando un mapa grande con locks mutex, resolviendo el problema de escalabilidad
- Se almacenan dumps de las estructuras con todos los datos en archivos
gobcomprimidos, que pueden recargarse al reiniciar. En un solo día crecen a más de 40 GB, y para soportar dumpsgobde ese tamaño fue necesario aplicar un parche al build de Go - Después de perder todos los datos de estado en vivo por un corte eléctrico, quedó claro que una fuente de poder ininterrumpida (UPS) era imprescindible
-
Complejidad y soledad
- Fue un proyecto mucho más desafiante y demandante de tiempo de lo esperado, que pasó de ser un hobby menor a una obsesión seria
- Como al final todo gira en torno a aumentar el saldo de la cuenta, puede ser un trabajo solitario y venir acompañado de una montaña rusa emocional intensa
-
Uso combinado de Go y Python
- El sistema de trading está escrito en Go, pero para la exploración de datos se adopta un enfoque híbrido aprovechando las amplias librerías de ciencia de datos de Python
-
Uso de una PC personal
- Las PC de escritorio modernas son lo bastante potentes, con la optimización adecuada, como para manejar el monitoreo en tiempo real de todo el mercado accionario
-
Uso de ChatGPT
- En lugar de depender solo de búsquedas y lectura cuando no se sabía cómo resolver un problema, se pasó a explicar el problema a ChatGPT, pedir enfoques de solución e incluso generación de código, con la sensación de una mejora de productividad de 3x
Experiencia con eventos de mercado
- Con su propio sistema se pudieron detectar y ver antes que las noticias diversas anomalías del mercado, como el fenómeno de las meme stocks, grandes eventos de IPO, mercados alcistas y desplomes, noticias de la Fed y alzas de tasas
- La sensación se describe como tener un asiento en primera fila para ver cómo se desarrollan los eventos del mercado frente a los ojos
1 comentarios
Comentarios en Hacker News
Trabajé un tiempo en HFT, y todo este campo me pareció realmente fascinante; me alegra que el autor original haya sentido una diversión parecida.
La razón por la que la plataforma en sí suele quedar fuera de la discusión es que el trading es un área donde confluyen alta tecnología, complejidad, fuerte regulación y competencia extrema.
Construir un sistema de entrada de órdenes, un sistema de gestión de riesgo y un sistema de seguimiento de posiciones ya es un gran logro, pero desde la perspectiva de una firma de trading eso ya es casi el costo de entrada.
Por eso la gente habla de estrategias. La plataforma base ya está resuelta, y ahora toca encontrar cómo ganar dinero con ella.
Además, no todos los participantes del mercado están jugando el mismo juego. En HFT se competía por alfas de apenas segundos, recortando nanosegundos en FPGA y microsegundos en redes inalámbricas de Nueva Jersey, mientras que a los bancos les preocupan más las elecciones y la geopolítica que el clima en Carteret. Si llueve, ese día la red de microondas no funciona.
En el medio hay muchísimas estrategias que buscan alfas que duran desde horas hasta semanas, así que incluso hablar el mismo idioma en un foro público se vuelve difícil. Aun así, es un mundo interesante y a veces lo extraño.
En cambio, la estrategia es el área donde hace falta descubrimiento. Hay unas cuantas estrategias bien conocidas que todavía son rentables, pero en general ya se las quedaron las empresas más grandes; el resto es exploración. Algunas estrategias solo dejan ganancias durante fases de mercado muy breves.
Yo también lo extraño a veces, pero se ha integrado tanto que ahora es, en gran medida, un mundo de grandes empresas.
Parece que la mayor parte de esto está compartimentada dentro de cada empresa y no se comenta afuera.
HFT juega un juego completamente distinto. He leído sobre la arquitectura de los mercados y el cableado real, y mientras yo recibo datos desde SIP, HFT se conecta directamente al mercado [1]
Yo opero en segundos, y HFT, como dijiste, opera en microsegundos, así que no hay comparación. En cierto sentido, hasta me alegra no competir directamente con ellos. O quizá sí estoy compitiendo, pero aun así puedo ganar un poco de dinero.
[1] https://www.researchgate.net/figure/Latencies-in-the-Electro...
Básicamente, me pregunto si se trata de hacer más rápido el trading de frecuencia media, o si hay ventajas concretas como obtener prioridad en la cola de órdenes.
Si tienen preguntas sobre este proyecto, puedo responderlas. Empezó como un proyecto personal y terminé obsesionándome por completo.
El sistema en sí no tiene demasiados secretos; la clave está en contar con una plataforma sólida donde puedas enchufar estrategias.
Tal vez lo publique como open source, pero antes tendría que limpiar todos los hacks que fui metiendo.
Tech Trader se presenta como un sistema de trading totalmente autónomo que lleva más de 10 años operando con dinero real sin intervención humana ni actualizaciones.
Dicen que, a diferencia de los sistemas algorítmicos tradicionales, no usa enfoques cuantitativos, arbitraje estadístico ni alta frecuencia, sino que observa las acciones como lo haría una persona, pero aprovechando la disciplina fría de una máquina y su concentración infinita.
Desde su lanzamiento en diciembre de 2012, ha operado de forma totalmente automática con capital real, y dicen que fue creado por una sola persona, un desarrollador autodidacta que usa el apodo de juego pftq.
Me gustaría saber si puedes compartir tu enfoque para enchufar distintas estrategias. Un sistema de estrategias tipo plugin puede abarcar varias capas y volverse complicado muy rápido.
También me interesa saber si en el backtesting guardas todos los datos de cotizaciones y ticks para reproducirlos, o si usas únicamente datos históricos agregados.
Al leer el artículo pensé en probar una configuración con WebSocket de Polygon, pero vi que el primer paquete con funcionalidad WebSocket cuesta 29 dólares, y el paquete Advanced con datos en tiempo real cuesta 200 dólares al mes.
Los datos en tiempo real con llamadas API ilimitadas se ven bastante bien, pero mi estrategia tiene una tasa de acierto de como mucho 78% con tamaños de capital normales, así que me costaría justificar 200 dólares al mes.
Me gustaría saber qué paquete usas y cuáles son sus ventajas y desventajas. Si prefieres responder por correo, está en mi perfil.
No sé si IB envía el feed de precios en tiempo real. La pantalla de TWS se actualiza continuamente, así que parecería que sí envían los datos en tiempo real, pero me pregunto si el libro de órdenes también está disponible por API.
Sé que este artículo está publicado en el blog de polygon.io, pero me pregunto si sería una arquitectura que también podría funcionar solo con la API de IB/TWS.
Uno de los conceptos más malentendidos en el trading algorítmico es que, en la mayoría de los sistemas, la velocidad no es el factor decisivo
Modelos como mi sistema https://grizzlybulls.com/models/vix-ta-macro-mp-extreme han superado ampliamente al mercado en operaciones reales durante más de 3 años, pero en promedio solo operan una vez cada 18 días hábiles y las señales solo se generan cerca de puntos de corte por hora
Los últimos 18 meses fueron más flojos que al principio debido a un gran cambio estructural de alta inflación y rápidas subidas de tasas, pero desde el lanzamiento del sitio en enero de 2022 ha dado un rendimiento de +14.11%, mientras que el SPX fue de -7.83%
Lo logró sin apalancamiento, y en el mismo período la caída máxima también fue menor, de -16.48% frente a -27.57% del SPX
Es una presentación hecha para que parezca que el modelo realmente superó al mercado por mucho. Si de verdad tienes una mina de oro inexplorada, sería impresionante, pero personalmente me cuesta creerlo por varias señales de alerta
Si te interesa el trading algorítmico, vale la pena mirar Collective2. Es un lugar donde ingenieros ofrecen señales de compra y venta mediante suscripción
Se siente como una especie de ligas menores del trading algorítmico y es bastante interesante
Como el sistema rastrea ganancias y pérdidas, es difícil falsear los reportes de desempeño, y si autorizas a Collective2 a acceder a una cuenta de Interactive Brokers, puede ejecutar por ti las señales de trading
Es un servicio que debe tener al menos 10 años, así que también puedes ver el desempeño de largo plazo, aunque la mayoría de los sistemas no duran tanto
https://collective2.com/leader-board
Incluso los que hoy están arriba casi nunca se mantienen mucho tiempo, normalmente 1 o 2 años. Eso muestra que el alpha de la mayoría de los sistemas desaparece bastante rápido
Las curvas de rendimiento también son irregulares, y la estructura es tal que unas pocas operaciones explican la mayor parte de la ganancia
Al desarrollar un sistema de trading automático, los ejes importantes son el feed y la recolección de datos, la generación de features, la generación de señales, la ejecución real de operaciones, la gestión de órdenes y la coordinación general
Los datos de origen rara vez se usan tal cual para tomar decisiones, y muchas veces una buena generación de features es el principal factor de éxito. Un promedio móvil es un ejemplo, pero hoy en día casi nunca alcanza con eso
Este artículo muestra los aspectos técnicos de procesar datos y gestionar órdenes, además del pipeline completo, pero me habría gustado ver más detalles sobre cómo escalar la solución y sobre la implementación asíncrona
Sobre todo porque, ya que usa Go, tiene una estructura de canales adecuada para ese propósito, así que me da más curiosidad
Entiendo que ese no era el foco del artículo, pero también habría ayudado información general sobre la lógica de trading, cómo enchufar nuevas estrategias y cómo parametrizar las estrategias existentes
Los enlaces del final fueron interesantes, y yo estoy desarrollando un bot de trading inteligente basado en machine learning e ingeniería de features (https://github.com/asavinov/intelligent-trading-bot), así que este tipo de artículo puede ser importante
La estructura es simple: se comunican entre sí con goroutines y channels, y se bloquea con un gran mutex
Cuando entra nuevo dato, se generan los agregados necesarios, es decir, velas basadas en ticks, y esos datos disparan el loop de la lógica de BUY. Si detecta algo, lanza una orden mediante la API de IB
Es muy simple y no hay nada complejo. Llegué a rastrear más de 100 posiciones al mismo tiempo y simplemente funcionó bien, así que no toqué mucho la lógica asíncrona compleja
Los parámetros en realidad están hardcodeados dentro del loop de BUY. Puede sonar raro, pero en una configuración pequeña no cambian tan seguido
La idea es correr las operaciones unas cuantas veces, ajustar valores, reiniciar y volver a probar. En un entorno enterprise quizá habría un lenguaje formal o hot loading, pero en mi caso hardcodearlo funciona suficientemente bien
Ni Go en sí ni ningún otro lenguaje da una gran ventaja. La ventaja la da el algoritmo de trading, y eso siempre es difícil de encontrar
Pasé varios meses buscando los parámetros óptimos, pero al final solo funcionaban con datos históricos, y en la práctica era totalmente distinto
Si el algoritmo y la estrategia fueran perfectos, incluso usando Visual Basic podrían ser mejores que Go, Rust o cualquier otro lenguaje. El lenguaje es solo una herramienta
Está bien haber usado Go, pero el título puede prestarse un poco a malentendidos. La gente podría tomarlo como algún tipo de ventaja, y no lo es
Y además, no creo que un lenguaje con recolector de basura sea una buena opción para HFT
Como desarrollar manualmente esa lógica, es decir, la estrategia, es naturalmente difícil, hice un bot de trading inteligente que deriva estrategias de trading a partir de datos históricos
https://github.com/asavinov/intelligent-trading-bot
Actualmente funciona con criptomonedas, pero puede aplicarse a otros mercados
https://t.me/intelligent_trading_signals
Que algo funcione solo con datos históricos y luego sea distinto en la realidad es una situación típica. La clave es crear estrategias que también funcionen con datos futuros no vistos
El algoritmo de backtesting también debe diseñarse para evitar que datos futuros se filtren hacia el pasado
En la industria se usan mucho C++ y Python, así que en realidad usar Go puede ser una desventaja, pero era el lenguaje que sabía usar
No intentaba crear una impresión equivocada. Go encaja bastante bien para recibir y procesar datos y llamar APIs remotas, así que en la práctica funciona bien
Pero si alguien piensa usar esto como base para conseguir trabajo, probablemente no ayude mucho
Hay lugares que usan Java y preasignan toda la memoria necesaria al iniciar. Jane Street también es conocida por usar OCaml
Así se obtiene un rendimiento bastante bueno y no hay que preocuparse por bugs de memoria
Después de experimentar durante un tiempo con datos históricos, la utilidad de esos datos disminuye
Yo estoy haciendo un bot en TypeScript porque es el lenguaje que conozco, y en Python porque hay muchas herramientas
Es un trabajo demasiado abrumador y solitario. Los otros proyectos siempre los hice en equipo, y aunque fueran equipos muy pequeños con trabajo autónomo, al menos había reuniones y standups de vez en cuando
Llevo 6 meses haciéndolo solo, así que pensé en invitar a un amigo solo para no estar completamente solo
Como es un side project, quizá no logre avanzar mucho, pero con gusto converso cuando sea
La única forma que se me ocurre es conseguir datos que ellos no tengan
Me parece que este post es totalmente vacío y hecho para generar clics. En resumen sería algo como: “puedes usar polygon.io para datos de mercado, pero el trading algorítmico igual es difícil, así que todavía no hay mucho que compartir”
Personalmente quería compartir la estructura de alto nivel de construir tu propio sistema. Cuando yo caí en esta madriguera, pensé que me habría gustado encontrar un post así
Si me dices qué más habría mejorado el contenido, con gusto lo incorporo
Vale la pena buscar a gente que disfrute del bucle de retroalimentación puro que ofrecen el código, la estrategia y el dinero en el trading
He estado estudiando el timing y la correlación entre acciones e índices como fuente de alfa, y he tenido cierto éxito
Ahora estoy tratando de automatizar ese proceso, y realmente disfruto el trabajo en sí
No intento actuar como market maker ni andar saltando constantemente entre símbolos. Estoy enfocado en pulir un modelo preciso que monetice muy bien unos pocos símbolos
Algunas herramientas útiles son TradingView y los indicadores y estrategias de Pinescript, modelos en Excel con datos exportados para backtesting, Python y Go para el machine learning del backend, y ChatGPT para iterar código nuevo rápidamente
Si a alguien le interesa, me gustaría conversar en trading @ dianazink.com
Buen post, me gustó la explicación concreta y especialmente las capturas de pantalla
Entiendo que no quieras entrar en detalle sobre la estrategia, pero me pregunto si podrías explicar si las operaciones se basan por completo en análisis técnico o si también usas datos externos o feeds de datos alternativos
Es decir, si es un sistema casi cerrado con entrada de Polygon y salida por la API de IB, o si es una configuración más amplia que incluye feeds de datos personalizados como sitios de noticias, Twitter o Reddit
Si es lo segundo, también me interesa saber cómo equilibras eso con el backtesting histórico cuando la cobertura histórica de algunas fuentes de datos es parcial
Últimamente he estado viendo formas de usar tablas de consulta con valores históricos precalculados para detectar anomalías, por ejemplo, juzgar algo como “¿esta actividad es normal en esta acción?”
El BXRX de hoy es un buen ejemplo [1]
También estoy observando la actividad de opciones para intentar usarla como señal
[1] https://www.google.com/search?q=BXRX