diff --git a/Optiver/assignment/Basic Quoter.ipynb b/Optiver/assignment/Basic Quoter.ipynb index 0ba3a18..0311038 100644 --- a/Optiver/assignment/Basic Quoter.ipynb +++ b/Optiver/assignment/Basic Quoter.ipynb @@ -70,37 +70,22 @@ " # Wait for some time to avoid breaching the exchange frequency limit\n", " time.sleep(0.05)\n", "\n", - "def vwap_mid_from_top_levels(bids, asks, depth=3):\n", + "def microprice_top1(bids, asks):\n", " \"\"\"\n", - " Berechnet den VWAP-basierten Mid-Preis auf Grundlage\n", - " der obersten 'depth' Level in bids und asks.\n", - "\n", - " Parameter:\n", - " - bids: List[OrderBookLevel], sortiert nach fallendem Preis\n", - " - asks: List[OrderBookLevel], sortiert nach steigendem Preis\n", - " - depth: int, Anzahl der Level pro Seite, die berücksichtigt werden\n", - "\n", - " Rückgabe:\n", - " - float oder None (falls total_volume == 0)\n", + " Berechnet den Microprice auf Basis des Top-1 Bid- und Ask-Levels:\n", + " (Ask Price * Bid Size + Bid Price * Ask Size) / (Bid Size + Ask Size)\n", + " Fallback auf einfachen Mittelwert, falls (Bid Size + Ask Size) == 0.\n", " \"\"\"\n", - " total_volume = 0\n", - " weighted_sum = 0\n", - "\n", - " # Falls das Orderbuch weniger als 'depth' Ebenen aufweist, automatisch anpassen\n", - " actual_depth = min(depth, len(bids), len(asks))\n", - "\n", - " for level in bids[:actual_depth]:\n", - " weighted_sum += level.price * level.volume\n", - " total_volume += level.volume\n", - "\n", - " for level in asks[:actual_depth]:\n", - " weighted_sum += level.price * level.volume\n", - " total_volume += level.volume\n", - "\n", - " if total_volume == 0:\n", + " if not bids or not asks:\n", " return None\n", - "\n", - " return weighted_sum / total_volume" + " bid_price = bids[0].price\n", + " ask_price = asks[0].price\n", + " bid_size = bids[0].volume\n", + " ask_size = asks[0].volume\n", + " total_size = bid_size + ask_size\n", + " if total_size == 0:\n", + " return None\n", + " return ((ask_price * bid_size) + (bid_price * ask_size)) / total_size" ] }, { @@ -143,8 +128,7 @@ " # Remove all existing (still) outstanding limit orders\n", " exchange.delete_orders(instrument.instrument_id)\n", " \n", - " # Obtain order book and only skip this instrument if there are no bids or offers available at all on that instrument,\n", - " # as we want to decide zwischen einfachem Mid oder VWAP-basiertem Mid\n", + " # Obtain order book; skip if incomplete\n", " instrument_order_book = exchange.get_last_price_book(instrument.instrument_id)\n", " if not (instrument_order_book and instrument_order_book.bids and instrument_order_book.asks):\n", " print(f'{instrument.instrument_id:>6s} -- INCOMPLETE ORDER BOOK')\n", @@ -153,32 +137,18 @@ " # Obtain own current position in instrument\n", " position = exchange.get_positions()[instrument.instrument_id]\n", "\n", - " # Obtain best bid and ask prices from order book (für Anzeige)\n", + " # Obtain best bid and ask for display\n", " best_bid_price = instrument_order_book.bids[0].price\n", " best_ask_price = instrument_order_book.asks[0].price\n", "\n", - " # Berechne Volumina der Top-3-Level je Seite\n", - " bid_vol_top3 = sum(level.volume for level in instrument_order_book.bids[:3])\n", - " ask_vol_top3 = sum(level.volume for level in instrument_order_book.asks[:3])\n", - " use_simple_mid = False\n", - "\n", - " if bid_vol_top3 + ask_vol_top3 > 0:\n", - " rel_diff = abs(bid_vol_top3 - ask_vol_top3) / max(bid_vol_top3, ask_vol_top3)\n", - " # Wenn sich die Top-Volumina um weniger als 10% unterscheiden, einfachen Mid verwenden\n", - " if rel_diff < 0.10:\n", - " use_simple_mid = True\n", - "\n", - " if use_simple_mid:\n", + " # Berechne Microprice (Top-1)\n", + " mid_price = microprice_top1(\n", + " instrument_order_book.bids,\n", + " instrument_order_book.asks\n", + " )\n", + " if mid_price is None:\n", + " # Fallback: einfacher Mid, falls Microprice nicht berechenbar\n", " mid_price = (best_bid_price + best_ask_price) / 2.0\n", - " else:\n", - " mid_price = vwap_mid_from_top_levels(\n", - " instrument_order_book.bids,\n", - " instrument_order_book.asks,\n", - " depth=3\n", - " )\n", - " if mid_price is None:\n", - " print(f'{instrument.instrument_id:>6s} -- VWAP MID PRICE NOT COMPUTABLE')\n", - " continue\n", "\n", " # Calculate our fair/theoretical price based on the chosen mid_price and our current position\n", " theoretical_price = mid_price - PRICE_RETREAT_PER_LOT * position\n",