Dentro del slice: tácticas de órdenes hijas entre tu scheduler y el exchange
Una trayectoria de Almgren-Chriss te entrega un número: vender 4.2 BTC en los próximos cinco minutos. Un schedule VWAP te entrega ese mismo tipo de número con una justificación distinta. Ninguno de los dos dice nada sobre lo que ocurre después — si esos 4.2 BTC llegan al libro como una única orden marketable, se quedan en el touch cobrando fees de maker, se esconden detrás de un display de 0.3 BTC, o se repriciean once veces persiguiendo una cotización que se mueve. Esa segunda capa de decisión es la capa táctica, y en libros cripto dominados por fees, habitualmente mueve más PnL por slice que la elección del scheduler que está por encima. Los presupuestos por intervalo del scheduler difieren entre TWAP y un Almgren-Chriss bien calibrado por unos pocos bps de impacto sobre toda la orden padre; pagar fees de taker en slices que podrías haber hecho de maker, o sangrar posición en cola por repricing descuidado, cuesta eso mismo por hora. Este artículo trata sobre la capa que todos operan y casi nadie documenta: la máquina de estados que decide cómo cada orden hija toca el libro.
Dos capas, una interfaz estrecha
Lehalle y Laruelle, en Market Microstructure in Practice (2ª ed., 2018), formalizan lo que converge en cualquier mesa de ejecución: una capa estratégica (el scheduler) que asigna cantidad a lo largo del tiempo, y una capa táctica (el microtrader) que trabaja cada asignación contra el libro en vivo. La separación no es estética — las dos capas viven en relojes distintos y con datos distintos. El scheduler piensa en minutos, consume pronósticos de volatilidad y volumen, y resuelve un problema variacional. La capa táctica piensa en milisegundos a segundos, consume deltas de L2 y estimaciones de cola, y resuelve una secuencia de pequeños problemas de parada óptima.

La interfaz entre ambas debe ser estrecha. Hacia abajo, por slice :
- presupuesto — la cantidad a ejecutar en este intervalo (el de Almgren-Chriss, o el incremento de la curva de volumen de VWAP);
- ventana — la duración del slice;
- urgencia — para Almgren-Chriss, el candidato natural es , que ya comprime aversión al riesgo, volatilidad y liquidez en una sola tasa; para un scheduler VWAP suele ser una distancia de banda ("vamos 1.8% por detrás de la curva objetivo").
Hacia arriba: fills con timestamps y fees, el remanente sin ejecutar, y el shortfall de implementación a nivel de slice medido contra el mid de llegada del intervalo. Ese último punto importa: el parámetro de impacto del scheduler ya fija cuánto debería costar demandar liquidez a la tasa . Toda la descripción del trabajo de la capa táctica cabe en una línea: conseguir fills a mejor costo que el implicado por , sin filtrar la existencia de la orden padre. Si tu shortfall de slice medido supera consistentemente el costo del modelo, tu calibrado puede bajar, el scheduler acelera, y toda la pila mejora. Si no puedes medir el shortfall de slice por separado del costo del schedule, no puedes ajustar ninguna de las dos capas — tienes un número borroso y dos perillas.
La política de remanente también forma parte del contrato. Cuando un slice termina con cantidad sin ejecutar, o bien la capa táctica lo completa a la fuerza (cruzar el remanente — el default bajo urgencia de deadline), o lo devuelve al scheduler para reamortizarlo sobre los slices restantes (aceptable al inicio de un schedule de bajo, tóxico cerca del deadline, donde la reamortización se compone silenciosamente hasta convertirse en un slice final descomunal).
La escalera de escalada: pasivo primero, agresivo por deadline
El resultado más antiguo en este terreno es Harris (1998), "Optimal dynamic order submission strategies in some stylized trading problems" (Financial Markets, Institutions & Instruments 7(2)): para un trader de liquidez que debe completar una operación antes de un deadline, la estrategia óptima es dinámica — permanecer en el libro con órdenes límite mientras el tiempo es barato, repriciear hacia el mercado a medida que se acerca el deadline, y cruzar al final. Todo motor táctico de producción es descendiente de esta forma: postear en el touch, envejecer, escalar, cruzar. Lo que añaden los esquemas de fees modernos y la dinámica de colas es la aritmética exacta de cuándo dispara cada transición.
El break-even para cruzar
Trabajamos por unidad, precios relativos al mid actual, para una compra. Cruzar ahora cuesta medio spread más el fee de taker:
Postear en el bid durante una ventana se llena con probabilidad ; un fill gana el medio spread y paga el fee de maker (negativo si es un rebate). No tener fill significa cruzar al final de la ventana después de que el precio se haya movido, en promedio, en tu contra en — estrictamente positivo, porque la ausencia de fill y la deriva adversa son el mismo evento: tu bid no se ejecuta cuando el mercado se aleja al alza. Costo esperado de postear:
Postear supera a cruzar si y solo si
donde es el premio — el round-trip completo que capturas por ser maker en lugar de taker: el spread más el diferencial de fees. Este es el mismo break-even que rige toda la economía maker-taker de la ejecución, colapsada a un único slice.
Números, perpetuo de BTCUSDT: mid $100,000, spread de un tick s = \0.10f_m = $20f_t = $50\Pi = 0.10 + 50 - 20 = $30.10 \approx 3\sigma_{\text{day}} = $3{,}000\delta(\tau) \approx 0.6,\sigma_{\text{day}}\sqrt{\tau/86400}$ (el 0.6 es un descuento por selección adversa que hay que calibrar, no dar por bueno sin más):
- s: \delta \approx \19p^* = 19/49 \approx 0.39$. Postea solo si esperas al menos un 39% de fill en 10 segundos.
- s: \delta \approx \47p^* = 47/77 \approx 0.61$.
- Con un rebate de maker de 1 bp en vez de un fee de 2 bps (f_m = -\10\Pi = $60.10p^* \approx 0.24$.
De aquí salen dos hechos estructurales. Primero, crece como mientras es constante, así que : la paciencia tiene una expiración dura, y el temporizador de envejecimiento no es una heurística sino el punto de cruce de dos curvas — tu estimada (cóncava, saturándose a medida que se drena la cola por delante) contra (creciente). Segundo, el tier de fees en el que operas mueve físicamente la escalera. Una mejora de tier que recorta los fees de taker hace que tu táctica óptima sea más agresiva — un acoplamiento que la mayoría descubre solo cuando sus estadísticas de fill cambian tras un re-tier VIP.
Cont y Kukanov, "Optimal order placement in limit order markets" (Quantitative Finance 17(1), 2017; arXiv 2012), formalizan esto en un solo periodo: minimizar el costo esperado de ejecutar unidades divididas entre órdenes de mercado y límite (en uno o varios venues), con una penalización por shortfall. La solución de un solo venue es explícita y tiene estructura de newsvendor: el tamaño óptimo de la orden límite está gobernado por la distribución del flujo de salida de cola — postear tamaño de forma agresiva cuando la cola por delante es pequeña en relación al flujo de salida esperado, y cubrir el riesgo de cola con órdenes de mercado. Su extensión multi-venue se resuelve mediante aproximación estocástica y es el núcleo intelectual de la lógica de asignación pasiva de cualquier smart order router. La lectura práctica para un motor táctico: la del break-even anterior no es una constante — es una función de la posición en cola y la tasa de drenaje, razón por la cual la capa táctica debe consumir el estimador de posición en cola como insumo de primera clase.

El parámetro de urgencia comprime toda esta escalera. Un alto del scheduler significa que el tiempo característico es corto: las ventanas se contraen, sube, y el motor salta directo a cruzar — correctamente, porque el scheduler ya declaró que el riesgo de inventario domina el ahorro de fees. Un bajo estira la fase pasiva. La capa táctica nunca debería re-derivar la urgencia a partir de su propia visión del mercado; eso es trabajo del scheduler, y duplicarlo crea dos controladores en desacuerdo.
Repricing sin quemar tu posición en cola
Una vez posteada, la cotización se mueve. Perseguirla sin criterio — cancelar, repostear en el nuevo touch, repetir — es la forma en que los motores tácticos destruyen silenciosamente la misma probabilidad de fill que justificó postear en primer lugar. La posición en cola es un activo con valor monetario medible (Moallemi y Yuan, 2016, le ponen precio: las posiciones al frente de la cola en libros FIFO líquidos valen una fracción considerable del spread), y cada decisión de repricing es un trade: vender tu posición actual en cola, comprar una al final de un nivel de precio distinto. El trade solo vale la pena cuando el valor del nuevo nivel supera al del anterior más los costos de mensajería. Eso exige saber qué hace realmente el amend de cada venue con tu lugar en la fila — y la respuesta es enormemente no uniforme.
CME Globex documenta la semántica más limpia: reducir la cantidad de la orden conserva la prioridad temporal; aumentar la cantidad o cambiar el precio te manda al final de la cola. Este es el modelo de referencia — bajar cantidad es gratis, todo lo demás es re-encolarse.
Binance spot históricamente solo ofrecía POST /api/v3/order/cancelReplace — un cancel-más-new de apariencia atómica pero explícitamente no transaccional. Dos modos: STOP_ON_FAILURE (por defecto — si el cancel falla, no se coloca la nueva orden) y ALLOW_FAILURE (coloca la nueva orden incluso si el cancel falla — hola, exposición doble accidental). La operación puede tener éxito parcial, señalizado por un HTTP 409, así que tu OMS debe reconciliar ambas patas de forma independiente; y la nueva orden siempre arranca una vida de cola nueva. Luego, en 2025, Binance lanzó Order Amend Keep Priority (PUT /api/v3/order/amend/keepPriority): reducir la cantidad in situ, conservando la prioridad temporal, sin costo en el conteo de órdenes abiertas. Semántica de CME, quince años después — y solo la mitad correspondiente a bajar cantidad.
Binance USDT-M futures tiene un endpoint de modificación real (PUT /fapi/v1/order), pero hay que leer la letra chica: solo órdenes LIMIT, hay que enviar tanto price como quantity, y "las órdenes modificadas se reordenarán en la cola de matching" — la documentación no promete conservación de prioridad ni siquiera para reducciones puras de cantidad. Trata cada modify de futuros como un reset de cola que de paso te ahorra un mensaje y conserva el ID de la orden. Un detalle filoso que conviene conocer: modificar una orden GTX (post-only) a un precio que cruzaría hace que la orden sea cancelada, no rechazada-y-conservada — una implementación de peg que no verifique esto ocasionalmente se auto-eliminará por amend.
OKX expone POST /api/v5/trade/amend-order (newPx, newSz, con cxlOnFail para auto-cancelar si el amend falla). Es un único mensaje, conserva el ID de la orden, y confirma de forma asíncrona — sCode = 0 significa "solicitud aceptada", y el resultado real llega por el canal de órdenes como amendResult. Lo que la documentación pública notoriamente no especifica es el comportamiento de la prioridad en cola. No llenes ese vacío de documentación con optimismo. Mídelo: postea dos órdenes marcadoras en un nivel tranquilo, haz amend a la baja del tamaño de una de ellas, y observa cuál se llena primero en unos cuantos cientos de pruebas. Hasta que tengas ese dato, la suposición conservadora — cualquier cambio de precio te re-encola en todas partes, bajar cantidad conserva prioridad solo donde está explícitamente documentado — es la única defendible.

Las consecuencias de política:
- Histéresis, no pegging. Reprecia solo cuando el touch se haya desplazado más de una banda de ticks respecto a tu precio en reposo. Dentro de la banda, la deriva es ruido y tu posición en cola vale más que un tick de mejora de precio. Una banda inicial razonable es de 1 a 3 ticks escalados por la vol de corto plazo; la banda correcta hace que el reprice marginal sea EV-neutral: , con el valor de cola estilo Moallemi-Yuan y el precio sombra de tu límite de tasa de mensajes. Las operaciones de amend/cancel-replace consumen presupuesto de tasa de órdenes en ambos venues de Binance; un motor táctico que se pega a cada tick agotará la capacidad de mensajes del resto de tu sistema.
- Amend a la baja, nunca cancel-repost a la baja. Cuando el scheduler recorta un presupuesto de slice en pleno vuelo (un scheduler POV que ve secarse el volumen, un re-solve de Almgren-Chriss tras fills parciales), usa la vía que preserva prioridad donde exista. Este es el único almuerzo gratis de toda la capa.
- Urgencia asimétrica en el reprice. Repriciear hacia el mercado (persiguiendo) reinicia tu cola a un precio peor — debería dispararse solo desde la lógica de escalada, en su propio temporizador. Repriciear alejándose (el mercado vino hacia ti) es un regalo; tómalo solo vía la banda pasiva, porque tu nivel actual está a punto de llenarse de todos modos.
Icebergs, tamaño de display y qué filtra tu intención
El tamaño de display es la tercera decisión, y es un trade genuinamente de dos caras, no un botón de sigilo gratuito. El registro empírico:
- Frey y Sandås ("The Impact of Iceberg Orders in Limit Order Books", working paper de 2009; Quarterly Journal of Finance, 2017), sobre datos de Xetra: las órdenes iceberg representaban 9.3% del volumen enviado y 15.9% del ejecutado, tenían un tamaño de 12 a 20 veces el de las órdenes límite ordinarias, y — el remate — cuando otros participantes detectan un iceberg, responden con órdenes de mercado que igualan el flujo. El tamaño oculto, una vez inferido, atrae flujo: la búsqueda de liquidez latente funciona en ambas direcciones.
- Bessembinder, Panayides y Venkataraman ("Hidden liquidity: an analysis of order exposure strategies in electronic stock markets", JFE 94(3), 2009), sobre Euronext Paris, donde las órdenes ocultas eran el 44% del volumen de la muestra: ocultar reduce el shortfall de implementación pero también reduce la probabilidad de ejecución completa y alarga el tiempo hasta completarse. La exposición compra fills y los paga en impacto; la opción se usa exactamente como predice la teoría — las órdenes agresivas se exponen para atraer contrapartes, el tamaño paciente se oculta.
- Esser y Mönch ("The navigation of an iceberg", Finance Research Letters 4(2), 2007) tratan el tamaño del peak como una optimización: un display mayor se llena más rápido, un display menor filtra menos, y el óptimo es interior.
Primero la mecánica, porque condiciona la optimización: en prácticamente todo venue que soporta icebergs nativos (Binance spot vía icebergQty, OKX vía sus órdenes de algo iceberg), cada relleno del peak visible entra al final de la cola en ese precio. Un iceberg, por tanto, no es "una orden con tamaño oculto" — es una secuencia de órdenes pequeñas, cada una pagando la espera de cola completa, disparadas automáticamente. En el break-even de fees de arriba, esto importa: la efectiva por peak es la probabilidad de fill al final de la cola, no la de tu posición original. Las colas profundas castigan doblemente a los peaks pequeños — fills más lentos y más selección adversa acumulada por relleno.
Luego está el problema de la señalización. El propio método de detección de Frey y Sandås es la advertencia: su detector frecuentista se apoya en los dos patrones de pereza de implementación más comunes — tamaño de peak constante y timestamps de relleno idénticos al timestamp de la operación que lo ejecutó. Cualquier participante que corra ese detector (y en venues cripto, muchos lo hacen — la propia metadata de matching del exchange se lo facilita aún más al flujo colocado) reconstruye tu tamaño oculto en un puñado de rellenos. Los vectores de fuga, ordenados por cuán seguido los veo en la práctica:
- Tamaños de display constantes o redondos (0.5 BTC, cada vez).
- Relleno instantáneo y determinista tras la ejecución de un peak completo — la firma del mismo timestamp.
- Temporizadores de escalada deterministas: cruzar exactamente a los 30 s de cada slice y la cinta muestra un metrónomo.
- Latencia y banda de reprice fijas — tu cadencia de amend es una huella tan identificable como tus tamaños de orden, tema tratado en huellas digitales e identificación de traders.
El costo de ser detectado no es hipotético. Van Kervel y Menkveld ("High-frequency trading around large institutional orders", Journal of Finance 74(3), 2019) muestran que los HFT inicialmente se posicionan en contra de las metaórdenes institucionales — proveyendo la liquidez que tu táctica pasiva consume — y luego voltean a operar a favor de la orden una vez que su persistencia revela información, haciendo back-running del remanente y elevando materialmente el costo de la orden padre. Sus instituciones respondieron sopesando el beneficio especulativo contra el riesgo de detección. Tu capa táctica es exactamente donde se implementa ese trade-off: aleatoriza el tamaño de display (un uniforme entre 30-70% de una base escalada por vol funciona bien), aplica jitter de ±20-30% a cada temporizador, ocasionalmente deja esperar a un relleno, y nunca dejes que dos órdenes hijas compartan tamaño, fase de temporizador y perfil de latencia. Nada de esto cuesta calidad de fill medible; todo esto eleva el piso de ruido para cualquiera que ajuste un detector a tu flujo.
Un motor táctico mínimo
Toda la capa de arriba se comprime en una pequeña máquina de estados por slice: IDLE → POSTED → (bucle de reprice) → CROSSING → DONE, con el filtro de break-even a la entrada, una banda de histéresis mientras está posteada, y escalada por deadline. La versión de abajo es deliberadamente mínima — sin adaptadores de venue, sin gestión de iceberg — pero es orientada a eventos y libre de efectos secundarios, así que encaja directamente en el simulador consciente de cola del rung 4 de la escalera de simulación de fills: el simulador llama a on_tick/on_fill, e interpreta las acciones como post → GTX/post-only, cross → IOC, cancel_replace/amend_down → la semántica del venue de la matriz anterior.
import math
from dataclasses import dataclass
from enum import Enum, auto
class State(Enum):
IDLE = auto(); POSTED = auto(); CROSSING = auto(); DONE = auto()
@dataclass
class Fees:
maker: float # $ per unit; negative = rebate
taker: float # $ per unit
@dataclass
class Cfg:
tick: float
sigma_1s: float # $ per sqrt(second), from your live vol estimator
adverse_frac: float = 0.6 # E[adverse move | no fill] ~ 0.6 * sigma; calibrate
reprice_band: float = 2.0 # ticks of touch drift tolerated before repricing
escalate_frac: float = 0.7 # cross the remainder at this fraction of the window
class SliceTactic:
"""One instance per scheduler slice. Drive it from a fill simulator or OMS."""
def __init__(self, side: str, qty: float, window: float, fees: Fees, cfg: Cfg):
self.side, self.qty, self.window = side, qty, window
self.fees, self.cfg = fees, cfg
self.filled, self.state, self.px, self.t0 = 0.0, State.IDLE, None, None
def p_star(self, spread: float, tau: float) -> float:
"""Break-even fill probability for posting over a window tau."""
delta = self.cfg.adverse_frac * self.cfg.sigma_1s * math.sqrt(tau)
prize = spread + self.fees.taker - self.fees.maker
return delta / (prize + delta)
def p_fill(self, queue_ahead: float, drain: float, tau: float) -> float:
"""Crude queue-drain estimate; swap in your calibrated fill model."""
if drain <= 0: return 0.0
return min(1.0, drain * tau / max(queue_ahead + self.qty, 1e-9))
def on_tick(self, t, bid, ask, queue_ahead, drain):
if self.state == State.DONE: return []
if self.t0 is None: self.t0 = t
left = self.qty - self.filled
elapsed, remain = t - self.t0, self.window - (t - self.t0)
touch = bid if self.side == "buy" else ask
if elapsed >= self.cfg.escalate_frac * self.window and left > 0:
self.state = State.CROSSING # deadline: pay up, finish
return [("cross", left)]
if self.state == State.IDLE:
if self.p_fill(queue_ahead, drain, remain) >= self.p_star(ask - bid, remain):
self.state, self.px = State.POSTED, touch
return [("post", touch, left)] # GTX / post-only
self.state = State.CROSSING # posting is -EV here
return [("cross", left)]
if self.state == State.POSTED:
if abs(touch - self.px) / self.cfg.tick > self.cfg.reprice_band:
self.px = touch # hysteresis breached:
return [("cancel_replace", touch)] # accept the queue reset
return []
def on_fill(self, t, fill_qty):
self.filled += fill_qty
if self.filled >= self.qty - 1e-9:
self.state = State.DONE
return [("slice_done", self.filled)]
return []
def on_budget_cut(self, new_qty):
"""Scheduler revised the slice down: amend-down keeps queue priority
where documented (CME, Binance spot amend/keepPriority)."""
self.qty = new_qty
left = new_qty - self.filled
return [("amend_down", left)] if left > 0 else [("cancel",)]
Tres advertencias honestas. p_fill aquí es un ratio provisional — en producción debería ser el modelo calibrado en vivo y por buckets del artículo de simulación de fills, porque todo el filtro post/cross vale solo lo que valga esa estimación. adverse_frac esconde la cantidad más difícil del artículo ( depende del régimen y se dispara justo cuando postear resulta más tentador); estímala a partir de tus propios resultados sin fill, agrupados por régimen de vol. Y el motor de arriba reprecia vía cancel-replace de forma incondicional — una versión consciente de venue debería enrutar los cambios a la baja de cantidad por la vía que preserva prioridad y cargar cada acción contra un presupuesto de mensajes.
Córrelo dentro del simulador contra una cinta de replay antes de dar por buenos los parámetros. El experimento que importa: fija el scheduler, barre escalate_frac y reprice_band, y grafica el shortfall de slice contra el costo del modelo implicado por . La superficie tiene una meseta — amplias bandas de parámetros casi óptimos — y dos precipicios: escalar demasiado tarde (remanentes sin llenar cruzando hacia momentum) y repriciear con demasiado entusiasmo (todo el valor de cola quemado). Conviene saber dónde están tus precipicios antes de que producción te los encuentre por ti.
Qué llevarte
- Dos capas, un contrato. El scheduler decide cuánto y para cuándo; la táctica decide cómo. La interfaz es presupuesto, ventana, urgencia hacia abajo; fills y shortfall de slice contra el mid de llegada del intervalo hacia arriba. Si no puedes atribuir el shortfall a una capa, no puedes ajustar ninguna de las dos.
- El filtro post/cross es aritmética, no intuición. Postea si y solo si con . En libros cripto de spread ajustado, el premio es el diferencial de fees, así que tu tier de fees define tu táctica — reajusta la escalera después de cada re-tier.
- Los temporizadores de envejecimiento son el punto de cruce de dos curvas — probabilidad de fill saturándose contra selección adversa que crece como — no constantes de folclore.
- La posición en cola es un activo; conoce la semántica de amend de cada venue antes de gastarla. CME: bajar cantidad conserva prioridad. Binance spot: cancelReplace siempre re-encola, el amend-keepPriority de 2025 la conserva para recortes de cantidad. Binance futures: cada modify re-encola. OKX: sin documentar — mide, y mientras tanto asume lo peor.
- Los icebergs son una secuencia de órdenes al final de la cola, y los perezosos son legibles. Peaks constantes y rellenos con el mismo timestamp son una firma de detección publicada; aleatoriza tamaños y temporizadores o acepta que te hagan back-running.
- Lleva la máquina de estados a tu simulador de fills primero. La capa táctica es la parte de la pila donde backtest y producción más divergen — precisamente por eso pertenece dentro del simulador, no atornillada después.
Enlaces útiles
- Harris, L. — Optimal Dynamic Order Submission Strategies in Some Stylized Trading Problems, Financial Markets, Institutions & Instruments 7(2), 1-76 (1998)
- Cont, R., Kukanov, A. — Optimal Order Placement in Limit Order Markets, Quantitative Finance 17(1), 21-39 (2017)
- Frey, S., Sandås, P. — The Impact of Iceberg Orders in Limit Order Books (2009)
- Bessembinder, H., Panayides, M., Venkataraman, K. — Hidden Liquidity: An Analysis of Order Exposure Strategies in Electronic Stock Markets, Journal of Financial Economics 94(3), 361-383 (2009)
- van Kervel, V., Menkveld, A. — High-Frequency Trading around Large Institutional Orders, Journal of Finance 74(3), 1091-1137 (2019)
- Moallemi, C., Yuan, K. — A Model for Queue Position Valuation in a Limit Order Book (2016)
- Lehalle, C.-A. — Market Microstructure Knowledge Needed for Controlling an Intra-Day Trading Process (2011)
- Binance Spot API — Order Amend Keep Priority
- Binance Spot API — Trading endpoints (cancelReplace semantics)
- Binance USDT-M Futures API — Modify Order
- OKX API v5 — Amend order
- CME Group — Order Functionalities (modification and time priority)
Cita
@article{soloviov2026childordertactics,
author = {Soloviov, Eugen},
title = {Inside the slice: child-order tactics between your scheduler and the exchange},
year = {2026},
url = {https://marketmaker.cc/blog/child-order-execution-tactics},
description = {The tactics layer between execution schedulers and the exchange: passive-then-aggressive escalation with maker-taker break-even math, amend vs cancel-replace queue semantics across venues, iceberg anti-signaling, and a per-slice Python state machine for fill simulators.}
}
Authors
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.