Wo Preise entstehen
Ein Preis auf dem Bildschirm ist das Ergebnis einer Warteschlange. An einer Börse stellen Käufer und Verkäufer Limit-Orders: „kaufe 300 zu 99,50“, „verkaufe 200 zu 100,00“. Nicht ausgeführte ruhen im Limit-Orderbuch: die Gebote (Bids), das beste zum höchsten Preis, und die Angebote (Asks), das beste zum niedrigsten. Ein Handel entsteht, wenn eine eingehende Order auf eine ruhende trifft. Alles, was die früheren Themen Preis, Spread, Slippage und Marktwirkung nennen, stammt aus dieser Struktur.
# 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.75Spread, Mittelkurs und Tiefe
Das beste Gebot und das beste Angebot sind die Spitze des Buchs. Ihre Differenz ist der Spread, der Preis für sofortiges Handeln: Wer das Angebot nimmt und zum Gebot zurückverkauft, verliert den Spread. In der Mitte liegt der Mittelkurs, die übliche Referenz für einen fairen Preis. Die Tiefe ist die auf jedem Niveau und darüber hinaus ruhende Größe und sagt, wie viel gehandelt werden kann, bevor sich der Preis bewegt. Eine leere Seite heißt, dass es auf dieser Seite gar keinen Preis gibt, Spread und Mitte sind also undefiniert: None, nicht null.
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 emptyOrders hinzufügen, ohne die Vergangenheit zu ändern
Eine neue Limit-Order schließt sich einem bestehenden Preisniveau an und erhöht dessen Gesamtgröße oder eröffnet ein neues Niveau. Das als Funktion zu schreiben, die ein neues Dict zurückgibt statt das alte zu ändern, hat einen praktischen Vorteil: Man behält eine Momentaufnahme des Buchs vor der Order, nützlich zum Testen und Wiederabspielen. Mit dict(side) kopieren, die Kopie ändern, zurückgeben. Eine Funktion, die ihr Argument stillschweigend verändert, ist eine klassische Fehlerquelle, wenn dasselbe Buch an zwei Stellen verwendet wird.
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} unchangedEine Market-Order matchen
Ein Market-Kauf nimmt die Angebote vom niedrigsten Preis aufwärts: das ganze erste Niveau, dann das zweite, bis die Order gefüllt oder das Buch leer ist. Laufen Sie über die sortierten Preise, nehmen Sie bei jedem min(left, size_at_price), notieren Sie die Ausführung und löschen Sie das Niveau (ganz genommen) oder verkleinern Sie es (teilweise genommen). Die Ausführungsliste liefert den Durchschnittspreis aus dem Ausführungsthema, und das verbleibende Buch ist der Markt nach Ihrem Handel: oben dünner, mit schlechterem besten Angebot.
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}- Jede Seite ist ein Dict
{price: size}: das beste Gebot istmax(bids), das beste Angebotmin(asks); Spread istask - bid, Mitte ihr Mittel, beideNone, wenn eine Seite leer ist. - Fügen Sie eine Order hinzu, indem Sie das Dict kopieren, beim Preis addieren und die Kopie zurückgeben; das übergebene Buch bleibt unverändert.
- Ein Market-Kauf läuft über die sortierten Angebote, nimmt je Niveau
min(left, size), löscht verbrauchte Niveaus, verkleinert teilweise genommene; echte Bücher haben zudem eine Warteschlange auf jedem Niveau.
Als Nächstes: Order-Flow-Ungleichgewicht, den Druck im Buch lesen, um die nächste Preisbewegung vorwegzunehmen.
Lab: Was bewertet wird
- Mit
best_bid_askdie Spitze des Orderbuchs finden25 Pkt. - Mit
spread_and_middie Lücke messen25 Pkt. - Mit
add_limit_ordereine Order ins Buch stellen25 Pkt. - Mit
match_market_buydie Verkaufsangebote abtragen25 Pkt.