Donde se forman los precios
Un precio en pantalla es el resultado de una cola. En una bolsa, compradores y vendedores colocan órdenes limitadas: «comprar 300 a 99,50», «vender 200 a 100,00». Las que no se ejecutan quedan en el libro de órdenes: las ofertas de compra (bids), la mejor al precio más alto, y las de venta (asks), la mejor al precio más bajo. Una operación ocurre cuando una orden entrante se encuentra con una en espera. Todo lo que los temas anteriores llaman precio, diferencial, deslizamiento e impacto sale de esta estructura.
# A side of the book as a dict {price: total size}
bids = {99.5: 300, 99.4: 500, 99.0: 1200}
asks = {100.0: 200, 100.1: 400, 100.5: 800}
best_bid, best_ask = max(bids), min(asks)
print(best_bid, best_ask) # 99.5 100.0
print(round(best_ask - best_bid, 2), (best_bid + best_ask) / 2) # the spread 0.5 and the mid 99.75Diferencial, precio medio y profundidad
El mejor bid y el mejor ask son la cima del libro. Su diferencia es el diferencial (spread), el precio de operar al instante: un comprador que toma el ask y revende al bid pierde el diferencial. A medio camino está el precio medio, la referencia habitual de un precio justo. La profundidad es el tamaño en espera en cada nivel y más allá, y dice cuánto puede operarse antes de que el precio se mueva. Un lado vacío significa que no hay precio en ese lado, así que diferencial y medio quedan indefinidos: None, no cero.
def best_bid_ask(bids, asks):
return (max(bids) if bids else None, min(asks) if asks else None)
def spread_and_mid(bids, asks):
bid, ask = best_bid_ask(bids, asks)
if bid is None or ask is None:
return None, None
return ask - bid, (bid + ask) / 2
print(spread_and_mid({99.5: 300, 99.4: 500}, {100.0: 200, 100.1: 400})) # (0.5, 99.75)
print(spread_and_mid({}, {100.0: 200})) # (None, None): one side is emptyAñadir órdenes sin cambiar el pasado
Una nueva orden limitada se une a un nivel de precio existente, sumando a su tamaño total, o abre un nivel nuevo. Escribirlo como una función que devuelve un dict nuevo en lugar de modificar el anterior tiene una ventaja práctica: se conserva una instantánea del libro antes de la orden, útil para probar y reproducir. Copia con dict(side), cambia la copia, devuélvela. Una función que modifica en silencio su argumento es una fuente clásica de errores cuando el mismo libro se usa en dos sitios.
def add_limit_order(side, price, size):
new = dict(side) # a copy: the original book is not touched
new[price] = new.get(price, 0) + size
return new
bids = {99.5: 300, 99.4: 500}
after = add_limit_order(bids, 99.5, 100) # joins the existing level
after = add_limit_order(after, 99.3, 50) # opens a new level
print(after) # {99.5: 400, 99.4: 500, 99.3: 50}
print(bids) # {99.5: 300, 99.4: 500} unchangedCasar una orden de mercado
Una compra de mercado toma los asks desde el precio más bajo hacia arriba: todo el primer nivel, luego el segundo, hasta que la orden se llena o el libro se vacía. Recorre los precios ordenados, toma min(left, size_at_price) en cada uno, registra la ejecución y borra el nivel (tomado entero) o redúcelo (tomado en parte). La lista de ejecuciones da el precio medio visto en el tema de ejecuciones, y el libro restante es el mercado tras tu operación: más delgado arriba, con peor mejor ask.
def match_market_buy(asks, size):
remaining = dict(asks)
fills = []
left = size
for price in sorted(asks): # cheapest first
if left <= 0:
break
take = min(left, asks[price])
fills.append((price, take))
left -= take
if take == asks[price]:
del remaining[price] # the level is used up
else:
remaining[price] = asks[price] - take
return fills, remaining
asks = {100.0: 200, 100.1: 400, 100.5: 800}
fills, remaining = match_market_buy(asks, 500)
print(fills) # [(100.0, 200), (100.1, 300)]
print(remaining) # {100.1: 100, 100.5: 800}- Cada lado es un dict
{price: size}: el mejor bid esmax(bids), el mejor askmin(asks); el diferencial esask - bid, el medio su promedio, y ambos sonNonesi un lado está vacío. - Añada una orden copiando el dict, sumando en el precio y devolviendo la copia; el libro recibido queda sin cambios.
- Una compra de mercado recorre los asks ordenados, tomando
min(left, size)por nivel, borrando los agotados y reduciendo los tomados en parte; los libros reales tienen además una cola en cada nivel.
A continuación: el desequilibrio del flujo de órdenes, leer la presión del libro para anticipar el próximo movimiento del precio.
Lab: qué se califica
- Hallar la cima del libro con
best_bid_ask25 pts - Medir la brecha con
spread_and_mid25 pts - Dejar una orden en el libro con
add_limit_order25 pts - Consumir las ventas con
match_market_buy25 pts