{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Collecting ninjabook\n",
" Downloading ninjabook-0.1.6-cp38-abi3-macosx_11_0_arm64.whl.metadata (429 bytes)\n",
"Collecting tabulate\n",
" Using cached tabulate-0.9.0-py3-none-any.whl.metadata (34 kB)\n",
"Downloading ninjabook-0.1.6-cp38-abi3-macosx_11_0_arm64.whl (217 kB)\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m217.2/217.2 kB\u001b[0m \u001b[31m6.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25hUsing cached tabulate-0.9.0-py3-none-any.whl (35 kB)\n",
"Installing collected packages: tabulate, ninjabook\n",
" Attempting uninstall: tabulate\n",
" Found existing installation: tabulate 0.9.0\n",
" Uninstalling tabulate-0.9.0:\n",
" Successfully uninstalled tabulate-0.9.0\n",
" Attempting uninstall: ninjabook\n",
" Found existing installation: ninjabook 0.1.5\n",
" Uninstalling ninjabook-0.1.5:\n",
" Successfully uninstalled ninjabook-0.1.5\n",
"Successfully installed ninjabook-0.1.6 tabulate-0.9.0\n",
"\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.3.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"%pip install ninjabook tabulate --force-reinstall"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Parsing raw data into `Event`"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"300000"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import csv\n",
"from ninjabook import Event\n",
"\n",
"events = []\n",
"with open(\"../data/norm_book_data_300k.csv\", newline='') as csvfile:\n",
" reader = csv.DictReader(csvfile)\n",
" for row in reader:\n",
" event = Event(\n",
" timestamp= int(row['timestamp']),\n",
" seq=int(row['seq']),\n",
" is_trade=bool(row['is_trade']=='1'),\n",
" is_buy=bool(row['is_buy']=='1'),\n",
" price=float(row['price']),\n",
" size=float(row['size'])\n",
" )\n",
" events.append(event)\n",
"\n",
"len(events)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Ingesting `Events` and streaming BBO"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"+------------------+--------+---------------+---------------+---------+---------------+---------------+\n",
"| ts | seq | best_bid_sz | best_bid_px | mid | best_ask_px | best_ask_sz |\n",
"+==================+========+===============+===============+=========+===============+===============+\n",
"| 1575161162310275 | 199955 | 0.019027 | 7490.55 | 7491.39 | 7492.22 | 0.204504 |\n",
"+------------------+--------+---------------+---------------+---------+---------------+---------------+\n",
"| 1575161162409739 | 199968 | 0.019027 | 7490.55 | 7491.35 | 7492.16 | 0.019353 |\n",
"+------------------+--------+---------------+---------------+---------+---------------+---------------+\n",
"| 1575161162509896 | 199980 | 0.019027 | 7490.55 | 7491.33 | 7492.1 | 0.3 |\n",
"+------------------+--------+---------------+---------------+---------+---------------+---------------+\n",
"| 1575161162610363 | 199987 | 0.019027 | 7490.55 | 7491.29 | 7492.03 | 0.211905 |\n",
"+------------------+--------+---------------+---------------+---------+---------------+---------------+\n",
"| 1575161162710305 | 199997 | 0.019027 | 7490.55 | 7491.27 | 7491.99 | 0.214587 |\n",
"+------------------+--------+---------------+---------------+---------+---------------+---------------+\n"
]
}
],
"source": [
"from ninjabook import Orderbook \n",
"from tabulate import tabulate \n",
"\n",
"ob = Orderbook(0.01)\n",
"\n",
"data = []\n",
"\n",
"for event in events[:200_000]:\n",
" bbo = ob.process_stream_bbo(event)\n",
" if bbo != None:\n",
" best_bid_px = bbo[0].price if bbo[0] is not None else None\n",
" best_bid_sz = bbo[0].size if bbo[0] is not None else None\n",
" best_ask_px = bbo[1].price if bbo[1] is not None else None\n",
" best_ask_sz = bbo[1].size if bbo[1] is not None else None\n",
" mid = ob.midprice()\n",
" data.append([ob.last_updated, ob.last_sequence, best_bid_sz, best_bid_px, mid, best_ask_px, best_ask_sz])\n",
"\n",
"headers = [\"ts\", \"seq\", \"best_bid_sz\", \"best_bid_px\", \"mid\", \"best_ask_px\", \"best_ask_sz\"]\n",
"\n",
"print(tabulate(data[-5:], headers=headers, tablefmt=\"grid\"))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Processing `Events` and getting top 3 bids and asks"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"last sequence: 199999\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| best_bid_sz | best_bid_px | mid | best_ask_px | best_ask_sz |\n",
"+===============+===============+=========+===============+===============+\n",
"| | | | 7492.02 | 4 |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| | | | 7492.01 | 0.149845 |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| | | | 7491.99 | 0.214587 |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| | | 7491.27 | | |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| 0.019027 | 7490.55 | | | |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| 0.812102 | 7490.19 | | | |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| 0.401352 | 7490.1 | | | |\n",
"+---------------+---------------+---------+---------------+---------------+\n"
]
}
],
"source": [
"from ninjabook import Orderbook\n",
"from tabulate import tabulate \n",
"\n",
"ob = Orderbook(0.01)\n",
"\n",
"for event in events[:200_000]:\n",
" ob.process(event)\n",
" \n",
"data = []\n",
"\n",
"for ask in sorted(ob.top_asks(3), key=lambda x: x.price, reverse=True):\n",
" data.append([None, None, None, ask.price, ask.size])\n",
" \n",
"data.append([None, None, ob.midprice(), None, None])\n",
"\n",
"for bid in ob.top_bids(3):\n",
" data.append([bid.size, bid.price, None, None, None])\n",
" \n",
"headers = [\"best_bid_sz\", \"best_bid_px\", \"mid\", \"best_ask_px\", \"best_ask_sz\"]\n",
"\n",
"print(\"last sequence:\", ob.last_sequence)\n",
"print(tabulate(data, headers=headers, tablefmt=\"grid\"))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Processing raw events without using `Event`"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"last sequence: 299999\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| best_bid_sz | best_bid_px | mid | best_ask_px | best_ask_sz |\n",
"+===============+===============+=========+===============+===============+\n",
"| | | | 7451.03 | 2.57563 |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| | | | 7451.02 | 1.11018 |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| | | | 7451.01 | 3.9983 |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| | | 7450.36 | | |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| 0.00279 | 7449.71 | | | |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| 2 | 7447.44 | | | |\n",
"+---------------+---------------+---------+---------------+---------------+\n",
"| 0.531638 | 7447.43 | | | |\n",
"+---------------+---------------+---------+---------------+---------------+\n"
]
}
],
"source": [
"from tabulate import tabulate \n",
"\n",
"from ninjabook import Orderbook\n",
"\n",
"\n",
"ob = Orderbook(0.01) # tick_size = 0.01\n",
"\n",
"for raw in events:\n",
" ob.process_raw(\n",
" raw.timestamp, \n",
" raw.seq, \n",
" raw.is_trade, \n",
" raw.is_buy, \n",
" raw.price, \n",
" raw.size\n",
" )\n",
" \n",
"data = []\n",
"\n",
"for ask in sorted(ob.top_asks(3), key=lambda x: x.price, reverse=True):\n",
" data.append([None, None, None, ask.price, ask.size])\n",
" \n",
"data.append([None, None, ob.midprice(), None, None])\n",
"\n",
"for bid in ob.top_bids(3):\n",
" data.append([bid.size, bid.price, None, None, None])\n",
" \n",
"headers = [\"best_bid_sz\", \"best_bid_px\", \"mid\", \"best_ask_px\", \"best_ask_sz\"]\n",
"\n",
"print(\"last sequence:\", ob.last_sequence)\n",
"print(tabulate(data, headers=headers, tablefmt=\"grid\"))\n"
]
}
],
"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.11.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}