Antwort A: Anthropic Claude Opus 4.8
from itertools import count
def _is_pos_int(v):
return isinstance(v, int) and not isinstance(v, bool) and v > 0
def process_events(events):
trades = []
rejected = []
# Resting book stored as dicts keyed by id; we keep a global sequence
# for time priority.
seq = count()
used_ids = set() # all ids ever accepted as new orders
resting = {} # id -> order dict {id, side, price, qty, seq}
bids = {} # id -> order (side buy)
asks = {} # id -> order (side sell)
def reject(idx, event, reason):
rejected.append({"input_index": idx, "event": event, "reason": reaso...
Vollständige Antwort anzeigen ▼
from itertools import count
def _is_pos_int(v):
return isinstance(v, int) and not isinstance(v, bool) and v > 0
def process_events(events):
trades = []
rejected = []
# Resting book stored as dicts keyed by id; we keep a global sequence
# for time priority.
seq = count()
used_ids = set() # all ids ever accepted as new orders
resting = {} # id -> order dict {id, side, price, qty, seq}
bids = {} # id -> order (side buy)
asks = {} # id -> order (side sell)
def reject(idx, event, reason):
rejected.append({"input_index": idx, "event": event, "reason": reason})
def sorted_asks():
# ascending price, then seq
return sorted(asks.values(), key=lambda o: (o["price"], o["seq"]))
def sorted_bids():
# descending price, then seq
return sorted(bids.values(), key=lambda o: (-o["price"], o["seq"]))
def can_cross_buy(buy_is_market, buy_price, ask_price):
if buy_is_market:
return True
return ask_price <= buy_price
def can_cross_sell(sell_is_market, sell_price, bid_price):
if sell_is_market:
return True
return bid_price >= sell_price
def fillable_qty_buy(is_market, price, qty):
remaining = qty
for ask in sorted_asks():
if remaining <= 0:
break
if not can_cross_buy(is_market, price, ask["price"]):
break
remaining -= min(remaining, ask["qty"])
return qty - remaining
def fillable_qty_sell(is_market, price, qty):
remaining = qty
for bid in sorted_bids():
if remaining <= 0:
break
if not can_cross_sell(is_market, price, bid["price"]):
break
remaining -= min(remaining, bid["qty"])
return qty - remaining
def execute_buy(order_id, is_market, price, qty):
remaining = qty
while remaining > 0:
book_asks = sorted_asks()
if not book_asks:
break
best = book_asks[0]
if not can_cross_buy(is_market, price, best["price"]):
break
tq = min(remaining, best["qty"])
trades.append({
"buy_id": order_id,
"sell_id": best["id"],
"price": best["price"],
"qty": tq,
"taker_id": order_id,
"maker_id": best["id"],
})
remaining -= tq
best["qty"] -= tq
if best["qty"] == 0:
del asks[best["id"]]
resting.pop(best["id"], None)
return remaining
def execute_sell(order_id, is_market, price, qty):
remaining = qty
while remaining > 0:
book_bids = sorted_bids()
if not book_bids:
break
best = book_bids[0]
if not can_cross_sell(is_market, price, best["price"]):
break
tq = min(remaining, best["qty"])
trades.append({
"buy_id": best["id"],
"sell_id": order_id,
"price": best["price"],
"qty": tq,
"taker_id": order_id,
"maker_id": best["id"],
})
remaining -= tq
best["qty"] -= tq
if best["qty"] == 0:
del bids[best["id"]]
resting.pop(best["id"], None)
return remaining
for idx, event in enumerate(events):
if not isinstance(event, dict):
reject(idx, event, "event is not a dict")
continue
etype = event.get("type")
if etype not in ("new", "cancel"):
reject(idx, event, "invalid or missing type")
continue
if etype == "cancel":
if "id" not in event:
reject(idx, event, "cancel missing id")
continue
cid = event["id"]
if cid not in resting:
reject(idx, event, "cancel for unknown or non-resting id")
continue
o = resting.pop(cid)
if o["side"] == "buy":
bids.pop(cid, None)
else:
asks.pop(cid, None)
continue
# new order
if "id" not in event:
reject(idx, event, "new order missing id")
continue
oid = event["id"]
side = event.get("side")
order_type = event.get("order_type")
qty = event.get("qty")
if side not in ("buy", "sell"):
reject(idx, event, "invalid or missing side")
continue
if order_type not in ("limit", "market"):
reject(idx, event, "invalid or missing order_type")
continue
if not _is_pos_int(qty):
reject(idx, event, "qty must be a positive integer")
continue
price = None
if order_type == "limit":
if "price" not in event:
reject(idx, event, "limit order missing price")
continue
price = event["price"]
if not _is_pos_int(price):
reject(idx, event, "price must be a positive integer")
continue
# time-in-force
if "tif" in event:
tif = event["tif"]
if tif not in ("GTC", "IOC", "FOK"):
reject(idx, event, "invalid tif")
continue
if order_type == "market" and tif == "GTC":
reject(idx, event, "market order may not be GTC")
continue
else:
tif = "GTC" if order_type == "limit" else "IOC"
# duplicate id check (after structural validation)
if oid in used_ids:
reject(idx, event, "duplicate order id")
continue
# Accept the order: register its id now.
used_ids.add(oid)
is_market = order_type == "market"
if tif == "FOK":
if side == "buy":
fillable = fillable_qty_buy(is_market, price, qty)
else:
fillable = fillable_qty_sell(is_market, price, qty)
if fillable < qty:
# not completely fillable; no trades, no book change
continue
# completely fillable, execute normally
if side == "buy":
execute_buy(oid, is_market, price, qty)
else:
execute_sell(oid, is_market, price, qty)
continue
# IOC and GTC
if side == "buy":
remaining = execute_buy(oid, is_market, price, qty)
else:
remaining = execute_sell(oid, is_market, price, qty)
if remaining > 0:
if tif == "GTC" and not is_market:
order = {
"id": oid,
"side": side,
"price": price,
"qty": remaining,
"seq": next(seq),
}
resting[oid] = order
if side == "buy":
bids[oid] = order
else:
asks[oid] = order
# IOC: cancel remainder (do nothing)
book = {
"bids": [
{"id": o["id"], "price": o["price"], "qty": o["qty"]}
for o in sorted_bids()
],
"asks": [
{"id": o["id"], "price": o["price"], "qty": o["qty"]}
for o in sorted_asks()
],
}
return {"trades": trades, "rejected": rejected, "book": book}
if name == "main":
evs = [
{"type": "new", "id": "a", "side": "sell", "order_type": "limit", "qty": 10, "price": 100},
{"type": "new", "id": "b", "side": "sell", "order_type": "limit", "qty": 5, "price": 101},
{"type": "new", "id": "c", "side": "buy", "order_type": "limit", "qty": 12, "price": 100},
{"type": "new", "id": "d", "side": "buy", "order_type": "market", "qty": 3},
{"type": "new", "id": "a", "side": "buy", "order_type": "limit", "qty": 1, "price": 50},
{"type": "cancel", "id": "b"},
{"type": "new", "id": "e", "side": "buy", "order_type": "limit", "qty": 0, "price": 100},
{"type": "new", "id": "f", "side": "buy", "order_type": "limit", "qty": True, "price": 100},
{"type": "new", "id": "g", "side": "buy", "order_type": "limit", "qty": 100, "price": 90, "tif": "FOK"},
]
result = process_events(evs)
assert result["trades"][0] == {"buy_id": "c", "sell_id": "a", "price": 100, "qty": 10, "taker_id": "c", "maker_id": "a"}
assert any(r["reason" == "duplicate order id" for r in result["rejected"]]
assert any["qty must be a positive integer" in r["reason"] for r in result["rejected"]]
print("self-tests passed")
Ergebnis
Siegstimmen
2 / 3
Durchschnittsscore
Gesamtpunktzahl
Gesamtkommentar
Antwort A ist eine sehr saubere und lesbare Implementierung. Sie behandelt alle Validierungsregeln und die Logik für verschiedene Orderarten korrekt, einschließlich der atomaren Prüfung für FOK-Orders. Sie enthält jedoch einen kritischen Performance-Bug in ihrer Matching-Logik: Sie sortiert die gesamte gegenüberliegende Seite des Buches innerhalb der Schleife für jeden Teil-Fill neu. Dies führt zu extrem schlechter Leistung in gängigen Szenarien und erfüllt nicht die Anforderung der Aufgabe nach 'angemessener Effizienz'.
Bewertungsdetails anzeigen ▼
Korrektheit
Gewichtung 35%Die Lösung liefert in einfachen Fällen korrekte Ergebnisse, weist jedoch einen schwerwiegenden algorithmischen Fehler auf. Die Matching-Schleifen in `execute_buy` und `execute_sell` sortieren das gesamte gegenüberliegende Buch bei jeder Iteration (d. h. für jeden Teil-Fill) neu. Dies ist ein schwerwiegendes Korrektheitsproblem in einem Kontext, in dem 'angemessene Effizienz' erwartet wird.
Vollständigkeit
Gewichtung 20%Die Lösung ist sehr vollständig und implementiert alle Ereignistypen (neu, stornieren) und Time-in-Force-Optionen (GTC, IOC, FOK). Sie enthält auch eine umfassende Reihe von Validierungsprüfungen für fehlerhafte Ereignisse, doppelte IDs und ungültige Werte, einschließlich des booleschen als Ganzzahl-Falls.
Codequalität
Gewichtung 20%Der Code ist sehr gut strukturiert, sauber und leicht lesbar. Er verwendet klare Variablennamen und Hilfsfunktionen. Die Logik ist innerhalb eines einzigen Funktionsumfangs enthalten, was für diese Aufgabe einfach und effektiv ist. Der Selbsttest-Abschnitt ist prägnant und nützlich.
Praktischer Nutzen
Gewichtung 15%Der schwerwiegende Performance-Bug in der Matching-Schleife macht diese Lösung für jede nicht triviale Simulation unpraktikabel. Ein Szenario, in dem eine große Order viele kleine ruhende Orders abgleicht, würde dazu führen, dass die Simulation unannehmbar langsam wird und ihren Zweck verfehlt.
Befolgung der Anweisungen
Gewichtung 10%Die Lösung hält sich perfekt an alle Anweisungen, einschließlich der Funktionssignatur, des Rückgabeformats, des Fehlens externer Pakete und der spezifischen Sortierreihenfolge für den endgültigen Buchzustand.
Gesamtpunktzahl
Gesamtkommentar
Antwort A ist eine saubere, gut strukturierte Python-Lösung in einer einzigen Datei. Sie implementiert korrekt die Preis-Zeit-Priorität mit sortierten Hilfsfunktionen, behandelt alle TIF-Modi (GTC, IOC, FOK) atomar, validiert alle erforderlichen Felder, einschließlich der Ablehnung von booleschen Werten als Ganzzahlen, doppelter IDs, ungültiger TIFs und Markt+GTC-Kombinationen. Die FOK-Prüfung erfolgt ohne Veränderung des Buches. Der Code ist lesbar, nutzt Hilfsfunktionen effektiv und enthält einen aussagekräftigen Selbsttest. Kleinere Ineffizienz: erneutes Sortieren des Buches bei jeder Trefferiteration (O(n log n) pro Schritt), aber dies ist für den Problemumfang akzeptabel. Das Resting-Dictionary und die Bids/Asks-Dictionaries sind leicht redundant, aber konsistent.
Bewertungsdetails anzeigen ▼
Korrektheit
Gewichtung 35%Implementiert korrekt Preis-Zeit-Priorität, Teilfüllungen, FOK-Atomarität (keine Buchveränderung bei Fehlschlag), IOC-Stornierung, GTC-Ruhen, Maker-Preise bei Trades, Ablehnung von booleschen Werten, Erkennung doppelter IDs und Stornierungsvalidierung. Die FOK-Füllbarkeitsprüfung simuliert korrekt, ohne den Zustand zu verändern. Keine signifikanten Korrektheitsfehler gefunden.
Vollständigkeit
Gewichtung 20%Behandelt alle Ereignistypen, alle TIF-Modi, alle Validierungsregeln, einschließlich boolescher Werte als Ganzzahlen, fehlender Felder, ungültiger TIF-Werte, Markt+GTC, doppelter IDs, Stornierung von nicht ruhenden Orders. Die Buchausgabe ist korrekt sortiert. Alle erforderlichen Handelsaufzeichnungsfelder sind vorhanden.
Codequalität
Gewichtung 20%Saubere, lesbare Struktur mit gut benannten Hilfsfunktionen. Der logische Ablauf ist leicht nachvollziehbar. Die Verwendung von itertools.count zur Sequenzierung ist elegant. Leichte Redundanz zwischen Resting/Bids/Asks-Dictionaries. Erneutes Sortieren bei jedem Trefferschritt ist leicht ineffizient, aber akzeptabel. Der Selbsttest verwendet Assert-Anweisungen korrekt.
Praktischer Nutzen
Gewichtung 15%Solide praktische Implementierung. Behandelt Randfälle gut. Der Ansatz mit dem erneuten Sortieren funktioniert korrekt für Tausende von Ereignissen, ist aber für sehr große Bücher nicht optimal. Keine externen Abhängigkeiten. Saubere API.
Befolgung der Anweisungen
Gewichtung 10%Folgt allen Anweisungen präzise: einzelne Datei, korrekte Rückgabeform mit genau den angegebenen Schlüsseln, keine externen Pakete, kein stdin/stdout in der Kernfunktion, Selbsttest geschützt durch __main__, ignoriert zusätzliche Felder bei gültigen Ereignissen wie angegeben.
Gesamtpunktzahl
Gesamtkommentar
Antwort A ist eine starke, ausführbare Implementierung des erforderlichen Limit-Order-Book-Simulators. Sie behandelt korrekt die Preis-Zeit-Priorität, Maker-Preis-Trades, teilweise Ausführungen, GTC/IOC/FOK-Verhalten einschließlich atomarer FOK-Prüfungen, doppelte akzeptierte IDs, Stornierungen, Bool/Int-Validierung und sortierte endgültige Buchausgabe. Ihre Hauptschwächen sind die mäßige Effizienz durch wiederholtes Sortieren des Buches während des Abgleichs und einige Robustheitslücken für ungewöhnliche fehlerhafte IDs wie nicht hashbare Werte, aber sie erfüllt die Aufgabe weitgehend.
Bewertungsdetails anzeigen ▼
Korrektheit
Gewichtung 35%Implementiert korrekt Abgleich, Preis-Zeit-Priorität, Maker-Preisgestaltung, teilweise Ausführungen, Order-Entfernung, IOC/GTC-Verhalten, FOK-Vorabprüfung ohne vorläufige Mutation, doppelte akzeptierte IDs und endgültige Buchsortierung. Kleinere Robustheitsbedenken bleiben für ungewöhnliche fehlerhafte IDs, die nicht hashbar sind.
Vollständigkeit
Gewichtung 20%Umfasst fast alle spezifizierten Ereignistypen, Validierungen, Time-in-Force-Modi, Ablehnungsdatensätze, Handelsdatensätze und Ausgabeformate. Es fehlen nur einige Härtungen für Randfälle mit fehlerhaften Eingaben wie nicht hashbare IDs.
Codequalität
Gewichtung 20%Der Code ist sauber, lesbar und mit fokussierten Hilfsfunktionen organisiert. Der Hauptqualitätsnachteil ist das wiederholte Sortieren innerhalb jeder Abgleichschleife, was einfach, aber für größere Bücher nicht besonders effizient ist.
Praktischer Nutzen
Gewichtung 15%Wäre praktisch für kleine bis mittlere deterministische Simulationen nutzbar und erzeugt die angeforderten Datenstrukturen. Die Effizienz ist für Tausende von Ereignissen akzeptabel, könnte aber bei vielen ruhenden Orders aufgrund wiederholten Sortierens abnehmen.
Befolgung der Anweisungen
Gewichtung 10%Definiert die erforderliche Funktion process_events in einer einzigen Datei, verwendet keine externen Pakete, führt keine I/O innerhalb der Kernfunktion durch, gibt genau die erforderlichen Top-Level-Schlüssel zurück und hält die Self-Test-Ausgabe unter dem Haupt-Guard.