{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Market depth (order book)\n",
    "=============="
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<IB connected to 127.0.0.1:7497 clientId=16>"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from ib_insync import *\n",
    "util.startLoop()\n",
    "\n",
    "ib = IB()\n",
    "ib.connect('127.0.0.1', 7497, clientId=16)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To get a list of all exchanges that support market depth data and display the first five:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[DepthMktDataDescription(exchange='DTB', secType='OPT', listingExch='', serviceDataType='Deep', aggGroup=2147483647),\n",
       " DepthMktDataDescription(exchange='LSEETF', secType='STK', listingExch='', serviceDataType='Deep', aggGroup=2147483647),\n",
       " DepthMktDataDescription(exchange='SGX', secType='FUT', listingExch='', serviceDataType='Deep', aggGroup=2147483647),\n",
       " DepthMktDataDescription(exchange='IDEALPRO', secType='CASH', listingExch='', serviceDataType='Deep', aggGroup=4),\n",
       " DepthMktDataDescription(exchange='ARCA', secType='STK', listingExch='', serviceDataType='Deep', aggGroup=2147483647)]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l = ib.reqMktDepthExchanges()\n",
    "l[:5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's subscribe to market depth data for EURUSD:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "contract = Forex('EURUSD')\n",
    "ib.qualifyContracts(contract)\n",
    "ticker = ib.reqMktDepth(contract)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To see a live order book, an event handler for ticker updates is made that displays a dynamically updated dataframe:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>bidSize</th>\n",
       "      <th>bidPrice</th>\n",
       "      <th>askPrice</th>\n",
       "      <th>askSize</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>15500000</td>\n",
       "      <td>1.12265</td>\n",
       "      <td>1.12275</td>\n",
       "      <td>21500000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>10200000</td>\n",
       "      <td>1.1226</td>\n",
       "      <td>1.1228</td>\n",
       "      <td>9000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1000000</td>\n",
       "      <td>1.12255</td>\n",
       "      <td>1.12285</td>\n",
       "      <td>1000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1000000</td>\n",
       "      <td>1.1225</td>\n",
       "      <td>1.1232</td>\n",
       "      <td>50000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    bidSize bidPrice askPrice   askSize\n",
       "0  15500000  1.12265  1.12275  21500000\n",
       "1  10200000   1.1226   1.1228   9000000\n",
       "2   1000000  1.12255  1.12285   1000000\n",
       "3   1000000   1.1225   1.1232     50000\n",
       "4         0        0        0         0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import display, clear_output\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(index=range(5),\n",
    "        columns='bidSize bidPrice askPrice askSize'.split())\n",
    "\n",
    "def onTickerUpdate(ticker):\n",
    "    bids = ticker.domBids\n",
    "    for i in range(5):\n",
    "        df.iloc[i, 0] = bids[i].size if i < len(bids) else 0\n",
    "        df.iloc[i, 1] = bids[i].price if i < len(bids) else 0\n",
    "    asks = ticker.domAsks\n",
    "    for i in range(5):\n",
    "        df.iloc[i, 2] = asks[i].price if i < len(asks) else 0\n",
    "        df.iloc[i, 3] = asks[i].size if i < len(asks) else 0\n",
    "    clear_output(wait=True)\n",
    "    display(df)\n",
    "\n",
    "ticker.updateEvent += onTickerUpdate\n",
    "\n",
    "IB.sleep(15);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Stop the market depth subscription:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "ib.cancelMktDepth(contract)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "ib.disconnect()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
