Lección 1.1.3 · 60 min
Libro de órdenes: bid, ask, spread y profundidad
El libro de órdenes es la lista de lo que los demás están dispuestos a comprar y vender, y a qué precio. Esta lección lo lee en sus tres niveles de detalle sobre la sesión de NOVA: el mejor precio, la escalera de diez niveles y los mensajes orden a orden, con los que se reconstruye el libro y se descubre una orden iceberg.
- Módulo
- 1.1 · Cómo funcionan los mercados
- Duración
- 60 min
Lecciones del nivel 1
1.1 · Cómo funcionan los mercados
1.2 · Clases de activos
- 1.2.1 Acciones: splits, dividendos y eventos corporativos
- 1.2.2 ETFs: réplica, tracking error, apalancados y UCITS
- 1.2.3 Futuros: especificaciones, margen, roll y contango
- 1.2.4 Forex: pares, pips, lotes, rollover y CFD
- 1.2.5 Opciones: call, put, valor intrínseco y valor temporal
- 1.2.6 Cripto: spot, perpetuos, funding y custodia
- 1.2.7 Renta fija y tipos de interés; CFDs y productos apalancados
1.3 · Fuentes de datos de mercado
- 1.3.1 Tipos de datos de mercado: EOD, barras, ticks, libro y referencia
- 1.3.2 Fuentes de datos gratuitas
- 1.3.3 APIs de datos retail y prosumer
- 1.3.4 Proveedores de datos profesionales
- 1.3.5 Datos de cripto y on-chain
- 1.3.6 Brókeres como fuente de datos
- 1.3.7 Licencias y términos de uso de datos
- 1.3.8 Cómo elegir proveedor de datos
1.4 · Ingeniería de datos financieros
- 1.4.1 Descarga por REST y websockets: paginación, límites y reintentos
- 1.4.2 Limpieza de datos: faltantes, ticks erróneos, huecos y zonas horarias
- 1.4.3 Ajustes por splits y dividendos: precios ajustados y sin ajustar
- 1.4.4 Universos sin sesgo de supervivencia: deslistados, fusiones y cambios de símbolo
- 1.4.5 Construcción de barras: tiempo, ticks, volumen, dólar y desequilibrio
- 1.4.6 Series continuas de futuros: reglas de roll, ajuste por diferencia y ajuste por ratio
- 1.4.7 Almacenamiento: CSV, Parquet, particionado, DuckDB, TimescaleDB y ArcticDB
- 1.4.8 Pipeline reproducible: descarga, validación, actualización incremental y tests de calidad
1.5 · Datos fundamentales y macro
1.6 · Análisis exploratorio financiero
1.7 · Análisis técnico programado
Qué es un libro de órdenes
En la negociación continua, cada orden limitada que no se ejecuta al llegar se queda esperando en el libro de órdenes: una lista ordenada de lo que otros participantes están dispuestos a comprar y vender. El libro tiene dos lados:
- Bid (compras). Órdenes de compra ordenadas de mayor a menor precio. El primero es el mejor bid: el precio más alto que alguien paga ahora mismo.
- Ask u offer (ventas). Órdenes de venta ordenadas de menor a mayor precio. El primero es el mejor ask: el precio más bajo al que alguien vende ahora mismo.
La distancia entre el mejor ask y el mejor bid es la horquilla (spread). Si alguien quiere comprar ya, paga el ask; si quiere vender ya, cobra el bid. Por eso la horquilla es el primer coste de operar (lección 1.1.5). El precio medio es el punto entre los dos, y es la referencia habitual de «el precio» en un instante.
Cada nivel es un precio con órdenes. Su tamaño es la suma de las acciones de todas las órdenes a ese precio. La profundidad es cuánto hay en el libro: en un nivel, en los cinco primeros, a menos de un céntimo del medio… Los precios van de tick en tick, el salto mínimo de precio: en NOVA, como en la mayoría de las acciones de EE. UU., un céntimo.
Los datos de esta lección son el libro visible de NOVA, la acción ficticia de la lección 1.1.1, el 2 de junio de 2025. Recuerda la simplificación del simulador: hay un único libro visible, el agregado de los centros con libro.
Tres niveles de detalle: L1, L2 y L3
Los proveedores venden el libro con tres grados de detalle, y cada uno se obtiene agregando el siguiente:
Fuente Mermaid
flowchart TB L3[L3: cada orden] -->|suma por precio| L2[L2: por nivel] L2 -->|solo el primero| L1[L1: mejor precio] L3 -->|ejecuciones| T[Operaciones]
| Nivel | Qué contiene | En los datos del curso | Para qué sirve |
|---|---|---|---|
| L1 (top of book) | Mejor bid y mejor ask con sus tamaños | nova_cotizaciones.parquet, una fila por cambio | Horquilla, precio medio, alinear operaciones (1.1.1) |
| L2 (market by price) | Varios niveles por lado, con tamaño y número de órdenes | nova_libro_l2.parquet, 10 niveles cada 10 s | Profundidad, impacto de una orden grande, desequilibrio |
| L3 (market by order) | Cada orden: alta, cancelación, modificación y ejecución, con su identificador | nova_libro_l3.parquet, 5 minutos | Cola de prioridad, icebergs, reconstrucción exacta del libro |
Cuanto más detalle, más volumen de datos y más caro (lección 1.3.1). En NOVA, cinco minutos de L3 son 7.241 mensajes: a ese ritmo, la sesión completa pasaría del medio millón, frente a 129.247 cambios de L1 en todo el día. Para un sistema que opera a diario basta con L1 y barras; para estudiar costes de ejecución hace falta L2; para modelar la cola o la llegada de órdenes, L3.
Una foto del libro, nivel a nivel
Las fotos L2 de NOVA tienen una fila por nivel y lado, cada 10 segundos. Esta es la de las 19:00:00 UTC, las 15:00 de Nueva York, puesta como una escalera: compras a la izquierda, ventas a la derecha.
import numpy as np
import pandas as pd
l2 = pd.read_parquet("nova_libro_l2.parquet")
foto = l2[l2["ts"] == "2025-06-02 19:00:00+00:00"]
bid = foto[foto["lado"] == "bid"].set_index("nivel")
ask = foto[foto["lado"] == "ask"].set_index("nivel")
escalera = pd.concat({
"bid": bid[["ordenes", "tamano", "precio"]],
"ask": ask[["precio", "tamano", "ordenes"]],
}, axis=1)
escalera bid ask
ordenes tamano precio precio tamano ordenes
nivel
1 36.0 13432.0 52.74 52.75 1870 5
2 44.0 9380.0 52.73 52.76 9900 18
3 41.0 9059.0 52.72 52.77 13280 29
4 5.0 1800.0 52.71 52.78 17322 54
5 2.0 600.0 52.70 52.79 14521 49
6 1.0 100.0 52.69 52.80 5142 30
7 3.0 526.0 52.67 52.81 9303 22
8 1.0 300.0 52.64 52.82 4300 11
9 NaN NaN NaN 52.83 1229 8
10 NaN NaN NaN 52.84 2252 6La figura de la cabecera dibuja la misma escalera. Se ven varias cosas que no están en un gráfico de precios. El lado comprador solo tiene ocho niveles en ese instante, y entre 52,69 y 52,67 falta el 52,68: «nivel» es un precio con órdenes, no cada tick. El primer nivel de compra tiene 13.432 acciones repartidas en 36 órdenes; el de venta, solo 1.870 en 5. Y en los diez niveles hay más del doble de acciones a la venta que a la compra. La foto es un instante: diez segundos después será otra.
Las medidas de L1 salen de los dos primeros niveles:
def medidas_l1(foto):
b = foto[(foto["lado"] == "bid") & (foto["nivel"] == 1)].iloc[0]
a = foto[(foto["lado"] == "ask") & (foto["nivel"] == 1)].iloc[0]
medio = (b["precio"] + a["precio"]) / 2
horquilla = a["precio"] - b["precio"]
qb, qa = b["tamano"], a["tamano"]
return pd.Series({
"bid": b["precio"], "ask": a["precio"], "medio": medio,
"horquilla_ticks": round(horquilla / 0.01),
"horquilla_pb": 1e4 * horquilla / medio,
"desequilibrio": (qb - qa) / (qb + qa),
"microprecio": (b["precio"] * qa + a["precio"] * qb)
/ (qb + qa),
})
medidas_l1(foto).round(4)bid 52.7400
ask 52.7500
medio 52.7450
horquilla_ticks 1.0000
horquilla_pb 1.8959
desequilibrio 0.7556
microprecio 52.7488
dtype: float64La horquilla es de un tick, 1,9 puntos básicos sobre el precio medio. El desequilibrio del primer nivel va de −1 (solo hay venta) a +1 (solo compra):
Aquí vale 0,76: casi todo el primer nivel es compra. El microprecio pondera cada precio por el tamaño del lado contrario:
Con 13.432 acciones esperando a comprar a 52,74 y solo 1.870 vendiendo a 52,75, lo probable es que el ask se agote antes que el bid, y el precio medio suba medio céntimo. El microprecio, 52,7488, ya está casi en el ask.
Profundidad acumulada
La pregunta práctica es cuántas acciones se pueden comprar o vender sin alejarse demasiado del precio medio. La profundidad acumulada la responde: para cada precio, la suma de lo que hay desde el mejor nivel hasta él.
medio = medidas_l1(foto)["medio"]
prof = foto.sort_values(["lado", "nivel"]).copy()
prof["acumulado"] = prof.groupby("lado")["tamano"].cumsum()
prof["distancia_cent"] = (100 * (prof["precio"] - medio).abs()).round(1)
print(prof.groupby("lado")["tamano"].sum().to_string())
prof.pivot(index="nivel", columns="lado",
values=["distancia_cent", "acumulado"])lado
ask 79119
bid 35197
distancia_cent acumulado
lado ask bid ask bid
nivel
1 0.5 0.5 1870.0 13432.0
2 1.5 1.5 11770.0 22812.0
3 2.5 2.5 25050.0 31871.0
4 3.5 3.5 42372.0 33671.0
5 4.5 4.5 56893.0 34271.0
6 5.5 5.5 62035.0 34371.0
7 6.5 7.5 71338.0 34897.0
8 7.5 10.5 75638.0 35197.0
9 8.5 NaN 76867.0 NaN
10 9.5 NaN 79119.0 NaNA menos de 2,5 céntimos del medio hay 31.871 acciones a la compra (tres niveles) y 25.050 a la venta. Más allá, el lado vendedor sigue engordando mientras el comprador se queda casi plano: en 10 niveles, 35.197 contra 79.119. Una orden de compra de 20.000 acciones necesitaría los tres primeros niveles de venta; una de venta del mismo tamaño se llenaría con el primer nivel de compra y parte del segundo. Cuánto cuesta en cada caso es el impacto de la orden, que la lección 1.1.4 calcula recorriendo el libro y la 1.1.5 convierte en coste.
La horquilla a lo largo de la sesión
En una acción líquida con un precio de unas decenas de dólares, la horquilla suele estar pegada al mínimo, un tick. Las 2.340 fotos de la sesión permiten ver cuándo se abre:
n1 = l2[l2["nivel"] == 1].pivot(index="ts", columns="lado",
values=["precio", "tamano"])
pb, pa = n1[("precio", "bid")], n1[("precio", "ask")]
qb, qa = n1[("tamano", "bid")], n1[("tamano", "ask")]
ticks = ((pa - pb) / 0.01).round()
pbs = 1e4 * (pa - pb) / ((pa + pb) / 2)
hora_ny = n1.index.tz_convert("America/New_York")
tabla = pd.DataFrame({"ticks": ticks.values, "pb": pbs.values,
"mas_de_1": (ticks > 1).values}, index=hora_ny)
print(ticks.value_counts().sort_index().to_string())
tabla.resample("30min").mean().round(3)1.0 2252
2.0 87
3.0 1
ticks pb mas_de_1
ts
2025-06-02 09:30:00-04:00 1.022 1.916 0.022
2025-06-02 10:00:00-04:00 1.039 1.947 0.039
2025-06-02 10:30:00-04:00 1.028 1.925 0.028
2025-06-02 11:00:00-04:00 1.033 1.926 0.028
2025-06-02 11:30:00-04:00 1.044 1.940 0.044
2025-06-02 12:00:00-04:00 1.039 1.933 0.039
2025-06-02 12:30:00-04:00 1.028 1.914 0.028
2025-06-02 13:00:00-04:00 1.056 1.963 0.056
2025-06-02 13:30:00-04:00 1.006 1.883 0.006
2025-06-02 14:00:00-04:00 1.044 1.957 0.044
2025-06-02 14:30:00-04:00 1.022 1.931 0.022
2025-06-02 15:00:00-04:00 1.022 1.940 0.022
2025-06-02 15:30:00-04:00 1.111 2.102 0.111El 96,2 % de las fotos tiene la horquilla mínima, de un tick. Las demás se reparten por el día, con más frecuencia en la última media hora, cuando la llegada de órdenes se acelera antes de la subasta de cierre (lección 1.1.2) y los creadores de mercado ajustan sus cotizaciones. En puntos básicos la horquilla depende del precio: el mismo céntimo es 1,88 puntos básicos con la acción a 53 USD y sería 10 con la acción a 10 USD. Para comparar costes entre activos, la horquilla se mide en puntos básicos; para entender la mecánica, en ticks.
¿Anticipa el libro el siguiente precio?
Si el primer nivel de venta está casi vacío y el de compra lleno, lo siguiente que suele pasar es que el ask se agote y el precio medio suba. Con las fotos de NOVA se puede medir: para cada foto, el desequilibrio y el cambio del precio medio hasta la foto siguiente, diez segundos después.
medio_s = (pa + pb) / 2
deseq = (qb - qa) / (qb + qa)
cambio = 100 * (medio_s.shift(-1) - medio_s) # céntimos
df = pd.DataFrame({"deseq": deseq, "cambio": cambio}).dropna()
df["tramo"] = pd.cut(df["deseq"], [-1, -0.6, -0.2, 0.2, 0.6, 1],
include_lowest=True)
print(f"correlación: {df['deseq'].corr(df['cambio']):.2f}")
df.groupby("tramo", observed=True)["cambio"].agg(
["mean", "size"]).round(3)correlación: 0.56
mean size
tramo
(-1.001, -0.6] -0.645 599
(-0.6, -0.2] -0.146 374
(-0.2, 0.2] -0.036 388
(0.2, 0.6] 0.088 382
(0.6, 1.0] 0.661 596La relación es clara y casi simétrica: cuando el primer nivel está muy cargado a la venta (desequilibrio por debajo de −0,6), el precio medio baja de media 0,65 céntimos en los diez segundos siguientes; cuando está muy cargado a la compra, sube 0,66. La correlación es de 0,56. ¿Por qué el microprecio es mejor estimación del precio «verdadero» que el medio? Porque ya incorpora esa información. Comparando los dos con el precio medio de la foto siguiente:
micro = (pb * qa + pa * qb) / (qb + qa)
siguiente = medio_s.shift(-1)
ok = siguiente.notna()
for nombre, pred in (("medio", medio_s), ("microprecio", micro)):
rmse = np.sqrt(((siguiente - pred)[ok] ** 2).mean())
print(f"{nombre:<12} error cuadrático medio: {100 * rmse:.3f} cent")medio error cuadrático medio: 0.867 cent
microprecio error cuadrático medio: 0.736 centEl microprecio reduce el error de predicción del precio medio siguiente de 0,867 a 0,736 céntimos, un 15 %. Son datos sintéticos, en los que la relación se ha construido de forma limpia; en datos reales también aparece, pero más débil y a horizontes muy cortos, segundos o menos.
Prioridad precio-tiempo
Cuando llega una orden agresiva, ¿contra qué orden del libro se ejecuta? En casi todos los mercados de acciones, por prioridad precio-tiempo: primero el mejor precio y, dentro del mismo precio, la orden que llegó antes. Cada nivel es una cola.
Fuente Mermaid
flowchart LR C[Compra a mercado] --> A[1.ª, más antigua] A --> B[2.ª orden] B --> N[Última llegada]
Las consecuencias son concretas. Una orden nueva se pone al final de la cola de su precio. Reducir el tamaño de una orden conserva su puesto; aumentarlo o cambiarle el precio equivale a cancelarla y enviar otra, que va al final. Y una orden limitada en el mejor bid no se ejecuta hasta que se hayan ejecutado o cancelado todas las que tenía delante. Por eso «el precio tocó mi límite» no significa «mi orden se ejecutó» (lección 1.1.4).
Del L3 al L2: reconstruir el libro
El fichero L3 tiene los mensajes orden a orden entre las 14:00 y las 14:05 UTC. Las 358 primeras filas, todas con la marca de las 14:00:00, son la foto inicial: cada orden viva, en orden de prioridad. Después viene un mensaje por cambio.
l3 = pd.read_parquet("nova_libro_l3.parquet")
print(len(l3), "mensajes")
print(l3["evento"].value_counts().to_string())
l3.iloc[358:364]7241 mensajes
evento
alta 3443
cancelacion 2842
ejecucion 746
modificacion 210
ts id_orden evento lado precio tamano
358 2025-06-02 14:00:00.111345+00:00 41031081 alta bid 53.03 200
359 2025-06-02 14:00:00.121651+00:00 41031083 alta bid 52.99 97
360 2025-06-02 14:00:00.154247+00:00 41030881 cancelacion ask 53.12 100
361 2025-06-02 14:00:00.178017+00:00 41031084 alta ask 53.10 1000
362 2025-06-02 14:00:00.209129+00:00 41030590 cancelacion bid 53.04 200
363 2025-06-02 14:00:00.260941+00:00 41030785 cancelacion ask 53.13 100Las reglas de cada mensaje: alta añade una orden al final de la cola de su precio; cancelacion la quita;
modificacion deja el nuevo tamaño y conserva la prioridad; ejecucion resta lo ejecutado y, si llega a cero, la
orden sale. Con un diccionario de Python, que conserva el orden de inserción, eso es todo lo que hace falta para
mantener las colas:
def aplica(libro, m):
"""Aplica un mensaje L3 al libro {id: [lado, precio, tamaño]}."""
if m.evento == "alta":
libro[m.id_orden] = [m.lado, m.precio, m.tamano]
elif m.evento == "cancelacion":
del libro[m.id_orden]
elif m.evento == "modificacion":
libro[m.id_orden][2] = m.tamano # conserva el puesto
elif m.evento == "ejecucion":
libro[m.id_orden][2] -= m.tamano
if libro[m.id_orden][2] == 0:
del libro[m.id_orden]
def a_l2(libro, n=10):
"""Agrega las órdenes por precio: el L2 de n niveles."""
df = pd.DataFrame(list(libro.values()),
columns=["lado", "precio", "tamano"])
g = (df.groupby(["lado", "precio"])["tamano"]
.agg(tamano="sum", ordenes="size").reset_index())
bids = g[g["lado"] == "bid"].nlargest(n, "precio")
asks = g[g["lado"] == "ask"].nsmallest(n, "precio")
out = pd.concat([bids, asks])
out["nivel"] = out.groupby("lado").cumcount() + 1
cols = ["lado", "nivel", "precio", "tamano", "ordenes"]
return out[cols].reset_index(drop=True)Ahora se reproducen los mensajes en orden y, en cada instante en que hay foto L2 (cada 10 segundos), se compara el libro reconstruido con la foto. Cada foto incluye todos los mensajes con marca de tiempo menor o igual que la suya:
fotos = pd.date_range("2025-06-02 14:00:00", "2025-06-02 14:05:00",
freq="10s", tz="UTC")
libro, iguales, i = {}, 0, 0
mensajes = list(l3.itertuples(index=False))
for t in fotos:
while i < len(mensajes) and mensajes[i].ts <= t:
aplica(libro, mensajes[i])
i += 1
ref = l2[l2["ts"] == t].drop(columns="ts").reset_index(drop=True)
iguales += a_l2(libro).equals(ref)
print(f"{iguales} de {len(fotos)} fotos coinciden")
print(len(libro), "órdenes vivas a las 14:05:00")31 de 31 fotos coinciden
345 órdenes vivas a las 14:05:00Las 31 fotos coinciden exactamente: niveles, precios, tamaños y número de órdenes. Es la comprobación que conviene hacer siempre con un feed L3 propio: si el libro reconstruido se desvía del L2 del proveedor, falta algún mensaje o se ha aplicado mal una regla. Otra comprobación barata: las ejecuciones del L3 deben sumar el volumen de los centros con libro en la cinta de operaciones.
op = pd.read_parquet("nova_operaciones.parquet")
ventana = op[(op["ts"] > "2025-06-02 14:00:00+00:00")
& (op["ts"] <= "2025-06-02 14:05:00+00:00")]
con_libro = ventana["centro"].isin(["PRINCIPAL", "MTF_A", "MTF_B"])
print("L3:", l3.loc[l3["evento"] == "ejecucion", "tamano"].sum())
print("cinta, centros con libro:",
ventana.loc[con_libro, "tamano"].sum())
print("cinta, todos los centros:", ventana["tamano"].sum())L3: 78705
cinta, centros con libro: 78705
cinta, todos los centros: 134726Las 78.705 acciones ejecutadas contra el libro coinciden con la cinta. El resto del volumen de esos cinco minutos se cruzó en el oscuro y en el internalizador, que no pasan por el libro: el L3 más completo de una bolsa no enseña toda la negociación de la acción.
Con el libro reconstruido se ve la cola completa de un nivel, que ningún L2 enseña:
cola = [(oid, o[2]) for oid, o in libro.items()
if o[0] == "bid" and o[1] == max(
v[1] for v in libro.values() if v[0] == "bid")]
print("precio:", libro[cola[0][0]][1], "· órdenes:", len(cola),
"· acciones:", sum(q for _, q in cola))
pd.DataFrame(cola[:5], columns=["id_orden", "tamano"])precio: 53.17 · órdenes: 34 · acciones: 14140
id_orden tamano
0 41034369 1078
1 41034404 200
2 41034422 100
3 41034426 62
4 41034433 500La primera orden de la cola tiene 1.078 acciones y se ejecutará antes que ninguna otra a ese precio. Una orden de compra nueva a 53,17 tendría delante 14.140 acciones: antes de que le toque, alguien tiene que vender todo eso, o las órdenes de delante cancelarse.
La orden iceberg
Una orden iceberg enseña solo una parte de su tamaño. Cuando la parte visible se ejecuta entera, el sistema repone
otro tramo desde la reserva oculta, con el mismo identificador y al final de la cola. En el L2 solo se ve el tramo
visible. En el L3 la delata la repetición: una orden normal tiene un único alta.
altas = l3[l3["evento"] == "alta"].groupby("id_orden").size()
print(altas[altas > 1].to_string())
ice = l3[l3["id_orden"] == altas.idxmax()]
print(ice.groupby("evento")["tamano"].agg(["size", "sum"]).to_string())
print("precio:", ice["precio"].iloc[0], "· lado:", ice["lado"].iloc[0])
print("de", ice["ts"].min().strftime("%H:%M:%S"),
"a", ice["ts"].max().strftime("%H:%M:%S.%f"))id_orden
41031312 30
size sum
evento
alta 30 9000
ejecucion 86 9000
precio: 53.09 · lado: ask
de 14:00:20 a 14:01:31.224465La orden 41031312 vende a 53,09. Aparece 30 veces con 300 acciones (la primera y 29 reposiciones) y se ejecuta en 86 trozos que suman 9.000 acciones, todo lo que tenía, entre las 14:00:20 y las 14:01:31. Quien miraba el L2 veía en 53,09 unos cientos de acciones a la venta; en realidad había 9.000. El efecto en el precio se ve en la cotización:
cot = pd.read_parquet("nova_cotizaciones.parquet").set_index("ts")
tramo = cot["2025-06-02 14:00:10":"2025-06-02 14:02:00"]
tramo.resample("10s").last() bid ask tam_bid tam_ask
ts
2025-06-02 14:00:10+00:00 53.08 53.09 3631 13073
2025-06-02 14:00:20+00:00 53.08 53.09 12431 10914
2025-06-02 14:00:30+00:00 53.08 53.09 19151 2361
2025-06-02 14:00:40+00:00 53.08 53.09 26743 653
2025-06-02 14:00:50+00:00 53.08 53.09 32909 71
2025-06-02 14:01:00+00:00 53.08 53.09 37482 259
2025-06-02 14:01:10+00:00 53.08 53.09 41363 259
2025-06-02 14:01:20+00:00 53.08 53.09 38533 249
2025-06-02 14:01:30+00:00 53.09 53.10 7681 54
2025-06-02 14:01:40+00:00 53.11 53.12 6156 89
2025-06-02 14:01:50+00:00 53.13 53.15 3946 4475
2025-06-02 14:02:00+00:00 53.13 53.15 3850 4975Durante algo más de un minuto, el ask no se mueve de 53,09 aunque el tamaño visible a la venta se reduce a unas decenas o cientos de acciones y el bid acumula decenas de miles: cada vez que el tramo visible se agota, aparece otro. Cuando la reserva se termina, a las 14:01:31, el ask pasa de 53,09 a 53,15 en menos de treinta segundos. Para quien compra, la iceberg es liquidez que no esperaba; para quien estudia el libro, un desequilibrio que «debería» haber movido el precio y no lo hizo.
Ejercicios
- Calcula la horquilla en puntos básicos, el desequilibrio y el microprecio de la foto L2 de las 13:30:00 UTC, la primera de la sesión, y compáralos con los de las 15:00 de Nueva York.
Solución
primera = l2[l2["ts"] == "2025-06-02 13:30:00+00:00"]
pd.DataFrame({"13:30 UTC": medidas_l1(primera),
"19:00 UTC": medidas_l1(foto)}).round(4) 13:30 UTC 19:00 UTC
bid 53.3400 52.7400
ask 53.3600 52.7500
medio 53.3500 52.7450
horquilla_ticks 2.0000 1.0000
horquilla_pb 3.7488 1.8959
desequilibrio 0.4118 0.7556
microprecio 53.3541 52.7488En la primera foto, justo después de la subasta de apertura, la horquilla es de dos ticks (53,34 a 53,36) y el libro todavía es fino: 1.200 acciones en el mejor bid y 500 en el mejor ask. El desequilibrio es positivo y el microprecio queda por encima del medio, como a las 15:00, pero con una horquilla doble. Los primeros segundos de la sesión continua son los más caros de cruzar.
- Con el libro reconstruido a las 14:05:00, ¿cuántas acciones tendría delante una orden de venta nueva al mejor ask? ¿Y una al segundo nivel de venta?
Solución
asks = sorted({o[1] for o in libro.values() if o[0] == "ask"})
for precio in asks[:2]:
delante = sum(o[2] for o in libro.values()
if o[0] == "ask" and o[1] <= precio)
print(f"vendiendo a {precio}: {delante} acciones por delante")vendiendo a 53.18: 4654 acciones por delante
vendiendo a 53.19: 37172 acciones por delanteA precio igual, la orden nueva va al final de la cola, así que tiene delante todo el nivel: 4.654 acciones en 53,18. En 53,19 tendría delante 37.172. En el segundo nivel tiene delante ese nivel entero (32.518 acciones) y además el primero, que se ejecuta antes por tener mejor precio. Cuanto más lejos del mejor precio, más probable es que la orden no se ejecute nunca si el precio se da la vuelta.
- Un proveedor te ofrece L1 gratis, L2 por una cuota mensual y L3 por una cuota mucho mayor. Tu sistema opera una vez al día, con órdenes de 500 acciones de acciones muy líquidas. ¿Qué nivel necesitas y para qué usarías cada uno?
Solución
Con L1 y barras basta para operar: el tamaño (500 acciones) está muy por debajo de la profundidad típica del primer nivel, así que el coste es esencialmente media horquilla, y la horquilla sale del L1. Un L2 serviría para comprobar de vez en cuando que la profundidad sigue siendo suficiente (por ejemplo, en la apertura o en días de noticias) y para estimar el impacto si el tamaño crece. El L3 no aporta nada a ese horizonte: sirve para modelar colas, icebergs y la llegada de órdenes, cosas que importan a quien opera en segundos o provee liquidez.
Respuesta plegada en cada pregunta
Autoevaluación
El mejor bid de NOVA es 52,74 y el mejor ask 52,75. ¿Cuál es la horquilla en puntos básicos sobre el precio medio?
- A1 punto básico
- BUnos 1,9 puntos básicos
- C0,01 puntos básicos
- D19 puntos básicos
Ver respuesta
Respuesta B. Unos 1,9 puntos básicos
La horquilla es 0,01 USD, un tick. Sobre el precio medio, 52,745, es 0,01 / 52,745 = 0,000190, es decir, 1,90 puntos básicos. En ticks es la mínima posible; en puntos básicos depende del precio de la acción.
¿Qué contiene un dato L2 que no contiene un L1?
- ALas operaciones ejecutadas
- BEl tamaño agregado en varios niveles de precio a cada lado, no solo en el mejor
- CEl identificador de cada orden
- DQuién envió cada orden
Ver respuesta
Respuesta B. El tamaño agregado en varios niveles de precio a cada lado, no solo en el mejor
L1 es el mejor bid y el mejor ask con sus tamaños. L2 añade los siguientes niveles de precio, cada uno con el tamaño total y, a veces, el número de órdenes. El identificador de cada orden es L3; quién la envió no lo publica ningún nivel.
En la foto de las 15:00 de Nueva York, el mejor bid tiene 13.432 acciones y el mejor ask 1.870. ¿Dónde está el microprecio?
- AJusto en el punto medio, 52,745
- BCerca del ask, en torno a 52,749
- CCerca del bid, en torno a 52,741
- DPor debajo del bid
Ver respuesta
Respuesta B. Cerca del ask, en torno a 52,749
El microprecio pondera cada precio por el tamaño del lado contrario: bid × tamaño del ask + ask × tamaño del bid, dividido por la suma. Con mucha más compra que venta en el primer nivel, se acerca al ask: el lado delgado es el que está a punto de agotarse.
Una orden de venta aparece una y otra vez con el mismo identificador al final de la cola de 53,09, siempre con 300 acciones, cada vez que se ejecuta entera. ¿Qué es?
- AUn error del proveedor de datos
- BUna orden iceberg: enseña 300 acciones y repone la parte visible desde una reserva oculta
- CUn creador de mercado que cancela y vuelve a enviar
- DUna orden stop
Ver respuesta
Respuesta B. Una orden iceberg: enseña 300 acciones y repone la parte visible desde una reserva oculta
Una iceberg tiene una parte visible y una reserva. Al agotarse lo visible, el sistema repone otro tramo con el mismo identificador y lo pone al final de la cola, porque la parte nueva pierde la prioridad temporal. En el L2 solo se ve el tramo visible; en el L3 la delata la repetición del identificador.
Llega una orden de compra a mercado de 500 acciones y en el mejor ask hay tres órdenes: A (200, la más antigua), B (100) y C (400). ¿Cómo se reparte?
- AContra C, la más grande
- B200 contra A, 100 contra B y 200 contra C
- CA partes iguales entre las tres
- DContra la más reciente
Ver respuesta
Respuesta B. 200 contra A, 100 contra B y 200 contra C
Con prioridad precio-tiempo, dentro de un mismo precio se ejecuta primero la orden que llegó antes. A se llena entera, luego B, y C se ejecuta por lo que falta (200) y le quedan 200 en el libro, conservando su puesto.
Ideas clave
- El libro tiene dos lados: compras (bid) ordenadas de mayor a menor precio y ventas (ask) de menor a mayor. La distancia entre los mejores es la horquilla.
- L1 es el mejor precio de cada lado; L2, varios niveles con el tamaño agregado; L3, cada orden con su identificador. Cada nivel se obtiene agregando el siguiente.
- La profundidad dice cuánto se puede ejecutar sin mover mucho el precio, y cambia de un instante a otro: el libro visible de NOVA a las 15:00 tenía 35.197 acciones a la compra y 79.119 a la venta en diez niveles.
- El desequilibrio del primer nivel anticipa el siguiente movimiento del precio medio en los datos de NOVA; el microprecio lo incorpora en una sola cifra.
- La prioridad precio-tiempo decide quién se ejecuta primero. Con los mensajes L3 se reconstruye el libro exacto, y el L2 que se obtiene coincide con las 31 fotos de la ventana.