Kairos · Trading Institucional
NQ20.418,75 0,00 %ES5.871,81 0,51 %BTCUSDT67.625,59 0,32 %ETHUSDT3.283,61 0,03 %AAPL228,26 0,06 %NVDA120,83 0,20 %EURUSD1,0794 0,44 %VIX14,60 0,12 %NQ20.418,75 0,00 %ES5.871,81 0,51 %BTCUSDT67.625,59 0,32 %ETHUSDT3.283,61 0,03 %AAPL228,26 0,06 %NVDA120,83 0,20 %EURUSD1,0794 0,44 %VIX14,60 0,12 %
Nivel 1 operativo y publicado; Niveles 2 y 3 con contratos de datos declarados

El mercado, a 0 fotogramas por segundo.

Kairos es un puesto de operación bursátil completo que corre entero en el navegador: acción del precio, libro de órdenes, cartera en papel y calendario macroeconómico sobre un mismo reloj.

Terminal de trading · Web (Next.js + Firebase)2026

Arquitecto y desarrollador único (front-end, motor de gráficos, dominio y despliegue)

21

tipologías de gráfico declaradas (6 renderizando)

32

indicadores en el catálogo del TA-Engine

22

marcos temporales, de 1 segundo a 1 año

BTCUSDT· 1m · Velas japonesasdata-stream.binance.vision

caminata determinista · 66 velas · 1 rAF por panel · 0 renders de React por tick

Capacidades · lectura en vivo

El mercado no pasa por React88,4
Memoria compartida con los workers26,4
Motor de gráficos por capas57,6
Feed compuesto: real donde lo hay, simulado donde no30,7
Aritmética verificada a mano, no contra sí misma82,2
Semáforo de impacto macroeconómico33,1
01 / La tesis

Dos lados del mismo libro

El estado del arte se vende como gráfico con indicadores encima o como terminal cerrado y carísimo. La posición contraria es un puesto completo que corre entero en el navegador.

Corto · el problema

Las plataformas de trading al uso o son gráficos con indicadores encima, o son terminales profesionales cerrados y carísimos. Reproducir un puesto institucional en la web choca con tres muros: el navegador no está pensado para redibujar a 60 FPS mientras recibe cientos de mensajes por segundo, React se convierte en un cuello de botella si cada tick provoca un render, y el cómputo de indicadores sobre series largas bloquea el hilo de interfaz. A eso se suma un problema de honestidad: una plataforma que muestra un mercado simulado y encima cobra depósitos reales no es un bróker, es un mercado ficticio con dinero real dentro.

Largo · la solución

Un terminal construido en Clean Architecture donde la dependencia apunta siempre hacia dentro y el dominio no conoce ni React, ni el canvas, ni el transporte. El mercado se almacena en un búfer circular columnar sobre un único ArrayBuffer con seis columnas y un Int32Array de control apto para Atomics: se comparte con los Web Workers sin serializar nada. El motor de gráficos es un renderizador Canvas 2D por capas, agnóstico de React, con un requestAnimationFrame por panel y bandera de suciedad. La autenticación pasó al SDK de Firebase en el navegador, lo que permite publicar el sitio como export estático; lo que protege de verdad los datos son las reglas de Firestore evaluadas en el servidor contra el uid, no ninguna comprobación del cliente. Y el alcance financiero se corta donde debe: cartera en papel, cero depósitos, y una lista explícita de requisitos previos a cualquier módulo de fondos.

02 / Profundidad

Siete niveles de este libro

Lo que sostiene el terminal, apilado como se apila la profundidad: arriba lo que se paga en rendimiento, abajo lo que se cobra en honestidad.

NivelCapacidadLado
07El mercado no pasa por ReactUn tick escribe en un Float64Array y marca el lienzo como sucio. Desplazar o hacer zoom no produce un solo render del árbol de componentes; la cabecera se refresca a 4 Hz como máximo. Coste medido: 1,25 ms por fotograma con tres indicadores, panel de oscilador, marcadores macro y 140 velas — un 7,5 % del presupuesto de 16,6 ms.Ask
06Memoria compartida con los workersOhlcvSeries es un búfer circular columnar sobre un único ArrayBuffer con un Int32Array de control apto para Atomics. Con aislamiento de origen cruzado activo (COOP + COEP, acotado a /terminal para no romper la ventana emergente de Google), el TA-Engine lee exactamente la misma memoria que el renderizador: coste de transferencia cero.Ask
05Motor de gráficos por capasUn renderizador Canvas 2D con diez capas independientes — rejilla, serie, volumen, superposición de indicadores, panel de oscilador, marcadores macro, posiciones, línea de precio, barra de precios y cruceta — sobre un registro que declara las 21 tipologías de gráfico de la especificación.Ask
04Feed compuesto: real donde lo hay, simulado donde noCompositeMarketDataFeed enruta cada instrumento al adaptador que sabe servirlo: BTCUSDT y ETHUSDT en vivo desde el espejo público de datos de Binance, y el resto del catálogo desde un simulador determinista. La interfaz sigue viendo un único puerto MarketDataFeed.Bid
03Aritmética verificada a mano, no contra sí mismaUn verificador de 52 comprobaciones contrasta ROI, curva de capital, ratios, comisiones y swap contra valores calculados a mano en el propio caso de prueba. Reimplementar la fórmula al lado sólo demostraría que dos copias del mismo error coinciden.Bid
02Semáforo de impacto macroeconómicoCarpetas roja, naranja y amarilla con cuenta regresiva y avisos a 5 y 1 minuto, medidor de volatilidad por desviación y alerta de Volatilidad Extrema Inminente por encima del 20 %. Los eventos se marcan verticalmente sobre la vela exacta de publicación.Bid
01Lo que no está, se diceLa verificación en dos pasos no se implementa porque el proyecto tiene MFA deshabilitado y una cuenta anónima no puede inscribir un segundo factor: el panel de perfil muestra ese estado real. Creerse protegido sin estarlo es peor que saberse desprotegido.Bid
spreadEn desarrollo
03 / La interfaz

Cinco franjas, un solo reloj

El terminal ocupa el alto completo de la ventana sin scroll: barra superior, estado de cuenta, cuerpo, bitácora y barra de estado.

kairos-74b99.web.app/terminal

Kairos

Fase 1 · Data Nivel 1

Layout
1234
Marco enlazadoFeed en vivo14:32:08 UTCAS

Saldo

10.000,00

Equity

10.412,55

P&L flotante

+412,55

Margen usado

1.240,00

Margen libre

9.172,55

Nivel

839,7 %

BTCUSDTBinance · espejo público
1s1m5m1h1D
VelasLíneaHeikin
0,25 @ 67.180,20SL 66.940,00TP 67.640,00
67.64067.48067.32067.16067.00067.298
RSI (14) · Wilder305070

Lista de seguimiento

NQNasdaq 100 · futuro20.418,75+0,18 %
ESS&P 500 · futuro5.842,250,49 %
BTCUSDTBitcoin · Binance67.412,30+0,80 %
ETHUSDTEthereum · Binance3.284,66+1,11 %
AAPLApple Inc.228,411,42 %
NVDANVIDIA Corp.121,08+1,73 %
HoraInstrumentoLadoVol.EntradaSalidaComisión + swapNeto
14:12:04BTCUSDTCompra0,2566.940,0067.298,10−4,20+85,32
13:48:51NQVenta220.462,2520.418,75−3,10+84,90
12:59:12EURUSDCompra1,01,08711,0842−1,80−30,80
ArrastrarRuedaArrastrar barra de preciosDoble clicSharedArrayBuffer: disponibleFirebase: kairos-74b99Nivel 2 · Nivel 3: contratos declarados

Terminal · rejilla multiactivo

BTCUSDTBitcoin / Tether · Binance67.298,10
MercadoLímiteStop
Cantidad0,25Nocional16.824,53
Stop (ticks)240Objetivo (ticks)342
Riesgo−60,00 USDRecompensa+85,50 USDRelación1 : 1,43
COMPRAR 67.298,60VENDER 67.297,90

Cartera en papel: las órdenes se ejecutan contra el simulador local y no salen a ningún mercado.

Panel de ejecución (ticket de orden)

Entorno macroeconómico

Alertas ON
RojaNaranjaAmarillaσ 24,0 %

⚠ Volatilidad extrema inminente

IPC subyacente (EE. UU.) · desviación esperada 24,0 %

14:30IPC subyacente (EE. UU.)03:34
Previo 3,2 %Consenso 3,1 %Actual
DESVIACIÓN ESPERADA24,0 %
15:00PMI manufacturero ISM08:32
Previo 48,7Consenso 49,2Actual
DESVIACIÓN ESPERADA9,4 %
16:00Subasta de letras a 4 semanasPublicado
Previo 4,32 %Consenso 4,30 %Actual 4,29 %
DESVIACIÓN REALIZADA0,7 %

Fed Watch · próxima decisión

Sin cambios62 %
−25 pb33 %
−50 pb5 %

Módulo macroeconómico

Kairos · Trading Institucional

Acceso de operador

No se almacenan contraseñas: la identidad la verifica Google mediante Firebase Authentication.

Continuar con GoogleEntrar como invitado

La sesión la gestiona Firebase y persiste en este navegador. Los datos quedan protegidos por reglas evaluadas en el servidor.

Acceso de operador

Las maquetas reproducen la interfaz real; los datos que muestran son de ejemplo.

04 / Niveles de datos

Lo que corre y lo que está declarado

La especificación va por niveles y la landing no los confunde: un nivel operativo de extremo a extremo y dos con los contratos de datos cerrados y tipados.

Nivel 1Operativo

Acción del precio y entorno

  • ·OHLCV en búfer columnar
  • ·22 marcos con frontera UTC
  • ·Indicadores en TA-Engine
  • ·Cartera en papel
  • ·Calendario macro
Nivel 2Contratos listos

Microestructura

  • ·Entidad MarketDepth
  • ·Libro por niveles
  • ·Cinta de operaciones
  • ·Puerto tipado declarado
  • ·Sin adaptador activo
Nivel 3Contratos listos

Flujo institucional y motor 3D

  • ·Entidad QuantAnalytics
  • ·WebGL reservado
  • ·Mapa de calor térmico
  • ·Puerto tipado declarado
  • ·Sin adaptador activo
05 / Catálogo

Catorce módulos enrutados

IDMóduloDescripción
F-01RejillaRejilla multiactivo de 1 a 4 paneles en paralelo, cada uno con instrumento, granularidad y tipo de serie propios; en móvil se apila sin perder la barra de precios
F-02MarcosGranularidad temporal continua de 1 segundo a 1 año (22 marcos), con alineación real a fronteras UTC y opción de enlazar el marco entre todos los paneles
F-03EscalaBarra de precios vertical integrada en el borde derecho, con etiqueta de último precio y escalado por arrastre
F-04TA-EngineTA-Engine en Web Worker con registro modular de 32 indicadores: SMA por suma deslizante O(n) y RSI con suavizado de Wilder ya implementados
F-05ÓrdenesCartera en papel con órdenes a mercado, límite y stop; Stop Loss y Take Profit arrastrables sobre el propio gráfico, elevación a break even y cierres rápidos globales
F-06BitácoraBitácora de operaciones con comisión de vuelta completa, swap por noche cruzada, resultado neto y exportación a CSV
F-07CuentaEstado de cuenta en vivo: saldo, equity, P&L flotante, margen usado y libre, y nivel de margen con semáforo
F-08RendimientoPanel de rendimiento: ROI multitemporal, curva de capital, mapa de calor diario y ratios, todo derivado del historial cerrado sin almacenar ningún agregado
F-09MacroMódulo macroeconómico con semáforo de impacto, calendario con cuenta regresiva, Fed Watch y curva de rendimiento del Tesoro
F-10AvisosAvisos locales del navegador al ejecutarse un Stop Loss o Take Profit, al entrar una orden pendiente y al caer el margen en zona crítica
F-11AccesoAcceso con Google mediante ventana emergente o cuenta de invitado anónima pero real, con uid propio y cartera persistida igual que cualquier otra
F-12SyncSincronización bidireccional con Firestore de cartera, disposición de paneles y preferencias, agrupando escrituras a 1,5 s
F-13EstadoBarra de estado con diagnóstico del entorno: disponibilidad de SharedArrayBuffer, proyecto de Firebase conectado y ayudas de interacción
F-14LandingLanding pública prerenderizada, sin una sola petición a terceros, que explica los tres niveles de datos y las cifras reales del motor
06 / Stack

Con qué está construido

Aplicación

Next.js 16.3·React 19.2·TypeScript 5·App Router·output: 'export' (sitio estático)

Interfaz

Tailwind CSS 4·@tailwindcss/postcss·Tokens Material Design 3 (esquema oscuro)·Tipografía del sistema (sin recursos de terceros)

Motor de gráficos

Canvas 2D API·Renderizador propio por capas·Escalas y controlador de viewport propios·WebGL reservado para el motor 3D de Nivel 3

Cómputo y concurrencia

Web Workers·SharedArrayBuffer·Float64Array / Int32Array·Atomics·COOP + COEP acotados a /terminal

Datos de mercado

WebSocket (data-stream.binance.vision)·REST klines (data-api.binance.vision)·Simulador determinista mulberry32·Feed compuesto con reconexión de retroceso exponencial

Backend gestionado

Firebase 12·Firebase Authentication (Google + anónimo)·Cloud Firestore·Firebase Hosting

Calidad y herramientas

ESLint 9 + eslint-config-next·tsx·Verificador de analítica propio (52 comprobaciones)

07 / Arquitectura

La dependencia siempre hacia dentro

src/presentation

React · 8 contextos apilados

src/application

Servicios: agregador, cartera, analítica

src/core

Entidades, value-objects y puertos · sin framework

Clean Architecture estricta con la dependencia siempre hacia dentro: presentation → application → domain. El núcleo (src/core) es puro TypeScript sin framework: entidades (Candle, Instrument, TopOfBook, Order, Position, TradingAccount, MacroEvent, MarketDepth de Fase 2, QuantAnalytics de Fase 3), value-objects (Timeframe con alineación UTC real), puertos (MarketDataFeed, CandleRepository, IndicatorEngine, MacroCalendarRepository) y servicios de aplicación (agregador de velas, motor de cartera en papel, analítica de rendimiento, desviación de volatilidad). src/infrastructure implementa esos puertos: adaptadores de Binance, simulador, feed compuesto y factoría, capa anticorrupción snake_case → dominio en los mapeadores del protocolo WebSocket, y la integración con Firebase. src/charting es el motor de gráficos, agnóstico de React: interfaz ChartRenderer, escalas, viewport, registro de las 21 tipologías y un renderizador Canvas 2D con diez capas. src/presentation contiene React con ocho contextos apilados en el orden de las dependencias (transporte → instantánea de mercado → analítica → macro → cartera → preferencias → espacio de trabajo). src/workers es un directorio aislado con el deserializador de WebSocket y el TA-Engine, comunicados por contratos de mensajería tipados. No hay rutas de servidor ni Cloud Functions: el sitio se compila como export estático y la seguridad recae íntegramente en las reglas de Firestore, que niegan por defecto y sólo abren users/{uid} a su propietario. Unas 14.200 líneas de TypeScript y TSX.

08 / Retos

Ocho incidencias y su cierre

Cada una se abrió contra un síntoma medible y se cerró contra una causa. Las que siguen abiertas están anotadas como tales.

1Síntoma

Un terminal que redibuja a cada tick y recalcula indicadores en el hilo principal se entrecorta en cuanto el mercado se acelera; con React en medio, cada impresión de la cinta provocaría un render del árbol completo.

Cierre

Se sacó el mercado de React por completo: cada tick escribe en un búfer circular columnar de Float64Array y sólo marca el lienzo como sucio, con un requestAnimationFrame por panel. El transporte agrupa mensajes y emite un postMessage por fotograma en vez de uno por tick, y las peticiones al TA-Engine se fusionan a ~8 Hz porque recalcular a los 20 Hz del feed sería tirar trabajo. Resultado medido: 1,25 ms por fotograma.

2Síntoma

El aislamiento de origen cruzado (COOP: same-origin) es requisito del navegador para exponer SharedArrayBuffer, pero impide que un documento hable con la ventana emergente que abre — y el acceso con Google de Firebase usa exactamente eso.

Cierre

El aislamiento se acotó a /terminal, dejando /acceso fuera. Además se eligió ventana emergente en lugar de redirección, porque signInWithRedirect deposita estado en el almacenamiento del authDomain, que es un tercero respecto al sitio, y falla de forma intermitente con el bloqueo de cookies de terceros. Como output: 'export' deja inactiva la función headers() de Next en producción, las cabeceras están duplicadas a propósito en firebase.json.

3Síntoma

El dominio principal de Binance devuelve HTTP 451 (ubicación restringida) desde buena parte de Latinoamérica, y como la petición sale del navegador de cada usuario, la restricción se aplicaría a cada uno por separado dejando el terminal sin precios.

Cierre

Se usa el espejo público de datos de mercado (data-api.binance.vision y data-stream.binance.vision), que sirve lo mismo sin esa puerta y devuelve access-control-allow-origin: *, así que además atraviesa el COEP de /terminal. Se abren tres streams por instrumento en una única conexión combinada: @trade para el OHLC, @bookTicker para el spread en tiempo real y @ticker por la apertura de 24 h.

4Síntoma

Binance no ofrece marcos de 5 s, 15 s, 30 s ni los multi-mes, y componerlos agrupando de N en N desde el índice 0 del array producía velas desfasadas — 13 s de desvío medidos en un marco de 15 s — que no casaban con las que forma el agregador en vivo, dejando una costura visible entre el histórico y el tiempo real.

Cierre

Se agrupa por frontera temporal alineada en lugar de por posición en el array. La corrección resuelve además los huecos de segundos sin negociación. Verificado en producción: el bid del panel coincide exactamente con el de la API, y la apertura de sesión también.

5Síntoma

Al pasar a export estático se cayó el modelo anterior de seguridad, que verificaba una cookie firmada con HMAC en un proxy antes de servir el terminal. El HTML y el JavaScript son ahora descargables por cualquiera y ninguna comprobación del navegador puede impedirlo.

Cierre

Se separó experiencia de protección: AuthGuard sólo evita mostrar un terminal sin sesión, y quien protege de verdad son las reglas de Firestore, que Google evalúa en el servidor contra el uid del token, con denegación por defecto y una única ruta abierta a su propietario. Para una aplicación cuyo mercado es un simulador en el propio navegador es el reparto correcto: lo valioso son los datos del operador, no el código de la página. Verificado en producción: una lectura sin credenciales devuelve 403.

6Síntoma

La reconciliación entre la cartera local y la de la nube sólo sincronizaba los cambios posteriores al inicio de sesión, de modo que una cartera ya existente en el navegador no llegaba nunca al servidor. Y arrastrar un Stop Loss sobre el gráfico disparaba una escritura por cada movimiento del ratón.

Cierre

Reconciliación en dos direcciones: al entrar, lo remoto manda si trae operaciones; si la nube está vacía y hay cartera local, se sube. Las escrituras se agrupan a 1,5 s. Nada que dependa de localStorage o del reloj se inicializa con useState — eso abortaría la hidratación del árbol entero —, sino con useSyncExternalStore y su getServerSnapshot.

7Síntoma

next build con Turbopack emite los Web Workers como TypeScript en crudo dentro de _next/static/media/, y su arranque generado usa importScripts(), así que el entrypoint falla antes de ejecutar una sola línea propia. El TA-Engine llevaba roto sin que nada lo delatara.

Cierre

La causa está diagnosticada y documentada como incumplimiento abierto, con las tres vías descartadas anotadas (ruta relativa en vez de alias, quitar type: 'module', desactivar el export estático). De ahí salió una regla dura: todo worker DEBE tener onerror, porque sin él fallan en silencio. El feed de Binance se dejó en el hilo principal tras medir que sus ~720 msg/s cuestan 0,007 ms por fotograma.

8Síntoma

ctx.font no resuelve custom properties de CSS: una cadena de fuente con var(--…) es inválida y el canvas revierte en silencio a 10px sans-serif, sin error, dejando toda la tipografía del gráfico rota.

Cierre

charting/theme.ts declara pilas de fuentes literales, espejadas explícitamente en globals.css junto al resto de la paleta, de modo que la interfaz en DOM y el dibujo en canvas nunca divergen de color ni de tipografía.

09 / Ingeniería

El presupuesto son 16,6 milisegundos

Sesenta fotogramas por segundo no es una promesa de marketing: es un techo de tiempo por fotograma que se mide o no se tiene.

1,25 ms

coste medido de un fotograma con tres indicadores, oscilador, marcadores macro y 140 velas

0

coste de transferencia entre el TA-Engine y el renderizador: leen la misma memoria

O(n)

SMA por suma deslizante; RSI con suavizado de Wilder

Tiempo por fotograma · 56 muestras

0 por encima del presupuesto

16,6 ms · presupuesto

tres indicadores · panel de oscilador · marcadores macro · 140 velas

3

rutas: landing, acceso y terminal

21

tipologías de gráfico declaradas (6 renderizando)

32

indicadores en el catálogo del TA-Engine

22

marcos temporales, de 1 segundo a 1 año

8

instrumentos en catálogo (futuros, cripto, acciones, FX, índice)

10

capas independientes del renderizador Canvas 2D

2

Web Workers: deserializador y TA-Engine

52

comprobaciones del verificador de analítica

1,25 ms

coste medido de un fotograma (7,5 % del presupuesto)

~14.200

líneas de TypeScript y TSX

Identidad · monograma, lockup y tarjeta social

Lockup horizontal usado en la interfaz: monograma K en cian con acentos verde y rojo, y logotipo KAIROS en gris claro; fondo recortado por diferencia para asentar sobre cualquier superficie del tema.
Lockup horizontal usado en la interfaz: monograma K en cian con acentos verde y rojo, y logotipo KAIROS en gris claro; fondo recortado por diferencia para asentar sobre cualquier superficie del tema.
Logo original a resolución completa, con el fondo oscuro incrustado; se conserva como referencia y es el origen de la tarjeta social.
Logo original a resolución completa, con el fondo oscuro incrustado; se conserva como referencia y es el origen de la tarjeta social.
Banner original de marca, origen del lockup recortado que se usa en la interfaz.
Banner original de marca, origen del lockup recortado que se usa en la interfaz.
Tarjeta social 1200×630 derivada del logo, servida por el App Router.
Tarjeta social 1200×630 derivada del logo, servida por el App Router.
Kairos · Trading InstitucionalLo que no está, se dice.
02

Implementa una especificación técnica por niveles: el Nivel 1 (acción del precio y entorno) está operativo de extremo a extremo, mientras que los Niveles 2 (microestructura) y 3 (flujo institucional y motor 3D) tienen ya cerrados y tipados sus contratos de datos.

03

El reto real no era dibujar velas, sino sostener 60 FPS mientras la cinta imprime miles de operaciones por segundo: el mercado nunca pasa por React, escribe directamente en búferes columnares Float64Array y marca el lienzo como sucio.

04

Los pares de criptomoneda cotizan en vivo contra el espejo público de datos de Binance; futuros, acciones, divisa e índice los sirve un simulador determinista, y un feed compuesto enruta cada instrumento sin que la interfaz note la diferencia.

05

El proyecto documenta con el mismo rigor lo que NO implementa: la verificación en dos pasos, el módulo de fondos y 30 de los 32 indicadores del catálogo aparecen como estado real, no como interruptores decorativos.

ArrastrarRuedaArrastrar barra de preciosDoble clic SharedArrayBuffer: disponibleFirebase: kairos-74b99Nivel 2 · Nivel 3: contratos declarados

Kairos · Trading Institucional

¿Quieres algo así para tu producto?

Un terminal de mercado a 60 fotogramas por segundo en el navegador, con el dominio fuera de React y la seguridad donde de verdad se evalúa. Si tu producto vive de datos que llegan más rápido de lo que se pueden pintar, ése es mi terreno.