{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "eadfbd02",
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import time\n",
    "from scipy import stats\n",
    "from IPython.display import clear_output\n",
    "\n",
    "from fastlob import Orderbook, OrderParams, OrderSide"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "68e566bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_orders(T: int, midprice: float):\n",
    "    result = list()\n",
    "    \n",
    "    for _ in range(T):\n",
    "    \n",
    "        n_ask_limits = stats.poisson.rvs(500)\n",
    "        n_bid_limits = stats.poisson.rvs(500)\n",
    "    \n",
    "        ask_limits_price = stats.expon.rvs(loc=midprice, scale=1, size=n_ask_limits)\n",
    "        bid_limits_price = -stats.expon.rvs(loc=midprice, scale=1, size=n_bid_limits) + 2*midprice\n",
    "    \n",
    "        ask_limits_quantities = stats.uniform.rvs(loc=1, scale=100, size=n_ask_limits)\n",
    "        bid_limits_quantities = stats.uniform.rvs(loc=1, scale=100, size=n_bid_limits)\n",
    "    \n",
    "        ask_limits_params = [OrderParams(OrderSide.ASK, p, q) for (p, q) in zip(ask_limits_price, ask_limits_quantities)]\n",
    "        bid_limits_params = [OrderParams(OrderSide.BID, p, q) for (p, q) in zip(bid_limits_price, bid_limits_quantities)]\n",
    "    \n",
    "        n_markets = stats.poisson.rvs(100)\n",
    "    \n",
    "        markets_price = stats.norm.rvs(loc=midprice, scale=2, size=n_markets)\n",
    "        markets_quantities = stats.uniform.rvs(loc=1, scale=100, size=n_markets)\n",
    "        markets_bid_or_ask = [random.choice((OrderSide.BID, OrderSide.ASK)) for _ in range(n_markets)]\n",
    "    \n",
    "        markets_params = [OrderParams(s, p, q) for (s, p, q) in zip(markets_bid_or_ask, markets_price, markets_quantities)]\n",
    "    \n",
    "        orders = ask_limits_params + bid_limits_params + markets_params\n",
    "        random.shuffle(orders)\n",
    "        \n",
    "        result.append(orders)\n",
    "        \n",
    "    return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "3a672864",
   "metadata": {},
   "outputs": [],
   "source": [
    "def simulate(orders: list, speed: float):\n",
    "    ob = Orderbook('Simulation')\n",
    "    ob.start()\n",
    "\n",
    "    for o in orders:\n",
    "        ob.process_many(o)\n",
    "        ob.render()\n",
    "        time.sleep(speed)\n",
    "        clear_output(wait=True)\n",
    "        \n",
    "    ob.stop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e2f638cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "midprice = stats.uniform.rvs(0.1, 1000)\n",
    "orders = generate_orders(1000, midprice)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "561b31ef",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   [ORDER-BOOK SIMULATION]\n",
      "\n",
      "\u001b[31m   ...(898 more asks)\n",
      " - 488.98 | 4605 | 235872.77 | 115337067.0746\n",
      " - 488.97 | 4691 | 238536.11 | 116637001.7067\n",
      " - 488.96 | 4653 | 238572.79 | 116652551.3984\n",
      " - 488.95 | 4701 | 240103.38 | 117398547.6510\n",
      " - 488.94 | 4627 | 234441.99 | 114628066.5906\n",
      " - 488.93 | 4775 | 242226.20 | 118431655.9660\n",
      " - 488.92 | 4611 | 234577.30 | 114689533.5160\n",
      " - 488.91 | 1997 | 101831.95 | 49786658.6745\n",
      " - 488.90 | 004 | 00168.91 | 82580.0990\n",
      " - 488.89 | 001 | 00010.65 | 5206.6785\n",
      "\u001b[0m ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
      "\u001b[32m - 488.82 | 003 | 00090.94 | 44453.2908\n",
      " - 488.81 | 2221 | 114479.81 | 55958875.9261\n",
      " - 488.80 | 4776 | 244335.24 | 119431065.3120\n",
      " - 488.79 | 4815 | 244049.52 | 119288964.8808\n",
      " - 488.78 | 4544 | 235018.06 | 114872127.3668\n",
      " - 488.77 | 4652 | 238286.14 | 116467116.6478\n",
      " - 488.76 | 4586 | 234470.70 | 114599899.3320\n",
      " - 488.75 | 4502 | 228385.34 | 111623334.9250\n",
      " - 488.74 | 4462 | 226656.95 | 110776317.7430\n",
      " - 488.73 | 4431 | 224201.81 | 109574150.6013\n",
      "   ...(899 more bids)\n",
      "\u001b[0m\u001b[34m\n",
      " - spread = 0.07\u001b[0m\u001b[34m | midprice = 488.855\u001b[0m\u001b[34m\n",
      " - asks volume = 25523666.39 | bids volume = 25494504.15\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "simulate(orders, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b088362c-2ca0-4ac8-b4c4-f4ab1eba78bc",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "fastlob",
   "language": "python",
   "name": "venv"
  },
  "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.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
