Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 22 additions & 52 deletions Optiver/assignment/Basic Quoter.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
},
{
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down