summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanglewood <85772166+deeleeramone@users.noreply.github.com>2023-08-25 09:19:44 -0700
committerGitHub <noreply@github.com>2023-08-25 16:19:44 +0000
commit8a5592b0342886ce06fdc4152caa6a5207131b82 (patch)
tree960f7104b104868988a6eca81edc605366ce9483
parentfc6137c86b279da5bb136e2e49846267a5242d1b (diff)
Add example notebook for building volume-at-price chart. (#5370)
* Add example notebook for building volume-at-price chart. Adds an example notebook. * Update README.md updates readme file with volumeAtPrice * spelling * spelling
-rw-r--r--examples/README.md11
-rw-r--r--examples/volumeAtPrice.ipynb6441
2 files changed, 6452 insertions, 0 deletions
diff --git a/examples/README.md b/examples/README.md
index 1d5f487e5c7..bf63622353d 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -63,3 +63,14 @@ This notebook demonstrates how to fetch and work with options chains data.
### googleColabInstallation
This notebook demonstrates how to install the OpenBB SDK within Google Colab.
+
+
+### volumeAtPrice
+
+Volume-at-price is a chart used by technical analysts as a visual gauge to where the trading levels are concentrated, relative to price and volume. In short, it is the sum of volume at different price levels. This notebook utilizes individual components of the OpenBB SDK and combines them to build a new view.
+
+- Price
+- Volume
+- VWAP
+- SMA
+- OpenBBFigure
diff --git a/examples/volumeAtPrice.ipynb b/examples/volumeAtPrice.ipynb
new file mode 100644
index 00000000000..6df96180944
--- /dev/null
+++ b/examples/volumeAtPrice.ipynb
@@ -0,0 +1,6441 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "d724df06",
+ "metadata": {},
+ "source": [
+ "# Building a Volume at Price Chart\n",
+ "\n",
+ "Volume-at-price is a chart used by technical analysts as a visual gauge to where the trading levels are concentrated, relative to price and volume. In short, it is the sum of volume at different price levels. This notebook utilizes individual components of the OpenBB SDK and combines them to build a new view."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 67,
+ "id": "bb37c115-58e5-446d-9eab-047d2f650721",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Import statements\n",
+ "\n",
+ "from datetime import datetime, timedelta\n",
+ "from typing import Optional, Union\n",
+ "from openbb_terminal.sdk import openbb\n",
+ "import pandas as pd\n",
+ "from plotly import graph_objects as go\n",
+ "from plotly.subplots import make_subplots\n",
+ "from openbb_terminal import OpenBBFigure\n",
+ "from openbb_terminal.common.technical_analysis import ta_helpers\n",
+ "from openbb_terminal.common.technical_analysis.overlap_model import sma, vwap\n",
+ "from openbb_terminal.rich_config import console\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8b045af0",
+ "metadata": {},
+ "source": [
+ "Let's look at the pieces we want to put together.\n",
+ "\n",
+ "- Price\n",
+ "- Volume\n",
+ "- VWAP\n",
+ "- SMA"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 71,
+ "id": "88a7f4be",
+ "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>Open</th>\n",
+ " <th>High</th>\n",
+ " <th>Low</th>\n",
+ " <th>Close</th>\n",
+ " <th>Adj Close</th>\n",
+ " <th>Volume</th>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>date</th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>2023-08-23 09:30:00</th>\n",
+ " <td>364.859985</td>\n",
+ " <td>364.859985</td>\n",
+ " <td>364.850006</td>\n",
+ " <td>364.850006</td>\n",
+ " <td>364.850006</td>\n",
+ " <td>1978013</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 09:31:00</th>\n",
+ " <td>364.859985</td>\n",
+ " <td>365.269989</td>\n",
+ " <td>364.730011</td>\n",
+ " <td>365.130005</td>\n",
+ " <td>365.130005</td>\n",
+ " <td>197931</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 09:32:00</th>\n",
+ " <td>365.119995</td>\n",
+ " <td>365.265015</td>\n",
+ " <td>364.640015</td>\n",
+ " <td>364.709900</td>\n",
+ " <td>364.709900</td>\n",
+ " <td>156792</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 09:33:00</th>\n",
+ " <td>364.690002</td>\n",
+ " <td>365.156189</td>\n",
+ " <td>364.690002</td>\n",
+ " <td>364.959991</td>\n",
+ " <td>364.959991</td>\n",
+ " <td>133015</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 09:34:00</th>\n",
+ " <td>364.970001</td>\n",
+ " <td>365.149292</td>\n",
+ " <td>364.750000</td>\n",
+ " <td>364.880005</td>\n",
+ " <td>364.880005</td>\n",
+ " <td>203328</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ " Open High Low Close \\\n",
+ "date \n",
+ "2023-08-23 09:30:00 364.859985 364.859985 364.850006 364.850006 \n",
+ "2023-08-23 09:31:00 364.859985 365.269989 364.730011 365.130005 \n",
+ "2023-08-23 09:32:00 365.119995 365.265015 364.640015 364.709900 \n",
+ "2023-08-23 09:33:00 364.690002 365.156189 364.690002 364.959991 \n",
+ "2023-08-23 09:34:00 364.970001 365.149292 364.750000 364.880005 \n",
+ "\n",
+ " Adj Close Volume \n",
+ "date \n",
+ "2023-08-23 09:30:00 364.850006 1978013 \n",
+ "2023-08-23 09:31:00 365.130005 197931 \n",
+ "2023-08-23 09:32:00 364.709900 156792 \n",
+ "2023-08-23 09:33:00 364.959991 133015 \n",
+ "2023-08-23 09:34:00 364.880005 203328 "
+ ]
+ },
+ "execution_count": 71,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Get the OHLC+V data\n",
+ "\n",
+ "ticker= \"QQQ\"\n",
+ "ohlc_data = openbb.stocks.load(ticker, start_date = datetime.now().date().strftime(\"%Y-%m-%d\"), interval=1, verbose=False)\n",
+ "ohlc_data.head(5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e1fd1f07",
+ "metadata": {},
+ "source": [
+ "Rounding the price levels - here to the nearest ten cents - will make the final chart easier display better."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 76,
+ "id": "10246983",
+ "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>Volume</th>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>Close</th>\n",
+ " <th></th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>364.6</th>\n",
+ " <td>418695.0</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>364.7</th>\n",
+ " <td>156792.0</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>364.8</th>\n",
+ " <td>647207.0</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>364.9</th>\n",
+ " <td>2341760.0</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>365.0</th>\n",
+ " <td>261823.0</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ " Volume\n",
+ "Close \n",
+ "364.6 418695.0\n",
+ "364.7 156792.0\n",
+ "364.8 647207.0\n",
+ "364.9 2341760.0\n",
+ "365.0 261823.0"
+ ]
+ },
+ "execution_count": 76,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Separate volume and close into a new DataFrame and group by the price.\n",
+ "\n",
+ "_vap = pd.DataFrame(data = [(round(ohlc_data[\"Close\"], 1)),ohlc_data[\"Volume\"]]).transpose()\n",
+ "_vap_df = _vap.groupby(\"Close\").sum()[[\"Volume\"]]\n",
+ "_vap_df.head(5)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 77,
+ "id": "03938620",
+ "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>VWAP_D</th>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>date</th>\n",
+ " <th></th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>2023-08-23 09:30:00</th>\n",
+ " <td>364.853333</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 09:31:00</th>\n",
+ " <td>364.870616</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 09:32:00</th>\n",
+ " <td>364.870685</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 09:33:00</th>\n",
+ " <td>364.874176</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 09:34:00</th>\n",
+ " <td>364.878156</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ " VWAP_D\n",
+ "date \n",
+ "2023-08-23 09:30:00 364.853333\n",
+ "2023-08-23 09:31:00 364.870616\n",
+ "2023-08-23 09:32:00 364.870685\n",
+ "2023-08-23 09:33:00 364.874176\n",
+ "2023-08-23 09:34:00 364.878156"
+ ]
+ },
+ "execution_count": 77,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Get VWAP levels\n",
+ "\n",
+ "_vwap = vwap(ohlc_data)\n",
+ "_vwap.head(5)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 78,
+ "id": "e1321d33",
+ "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>SMA_10</th>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>date</th>\n",
+ " <th></th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>2023-08-23 14:49:00</th>\n",
+ " <td>369.148868</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 14:50:00</th>\n",
+ " <td>369.159866</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 14:51:00</th>\n",
+ " <td>369.165869</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 14:52:00</th>\n",
+ " <td>369.200879</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2023-08-23 14:53:00</th>\n",
+ " <td>369.228598</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ " SMA_10\n",
+ "date \n",
+ "2023-08-23 14:49:00 369.148868\n",
+ "2023-08-23 14:50:00 369.159866\n",
+ "2023-08-23 14:51:00 369.165869\n",
+ "2023-08-23 14:52:00 369.200879\n",
+ "2023-08-23 14:53:00 369.228598"
+ ]
+ },
+ "execution_count": 78,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Calculate the simple moving average.\n",
+ "\n",
+ "_sma_df = sma(data = ohlc_data[\"Close\"], length = 10)\n",
+ "_sma_df.tail(5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d87c0523",
+ "metadata": {},
+ "source": [
+ "## Parameterize the Components as a Function\n",
+ "\n",
+ "To combine these components, a function needs to be created that parameterizes the inputs.\n",
+ "\n",
+ "The two functions below represent the \"model\" and \"view\" components. As Terminal components, they would be added to `openbb_terminal/common/technical_analysis/volume_model.py` and `volume_view.py` respectively. \n",
+ "\n",
+ "At the SDK level, users can call on either one, but only the view will return a chart and provide an input for the simple moving average. As a Terminal as a function, the controller module would call the view function, `display_vap()`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 84,
+ "id": "754d902f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def vap(data: pd.DataFrame) -> pd.DataFrame:\n",
+ " \"\"\"Volume at Price.\n",
+ "\n",
+ " Parameters\n",
+ " ----------\n",
+ " data: pd.DataFrame\n",
+ " Dataframe of OHLC + Volume.\n",
+ "\n",
+ " Returns\n",
+ " -------\n",
+ " pd.DataFrame\n",
+ " Dataframe with technical indicator.\n",
+ " \"\"\"\n",
+ " close_col = ta_helpers.check_columns(data, high=False, low=False)\n",
+ " if close_col is None:\n",
+ " return pd.DataFrame()\n",
+ " if \"Volume\" not in data.columns:\n",
+ " console.print(\"[red]Volume column not found[/red]\\n\")\n",
+ " return pd.DataFrame()\n",
+ "\n",
+ " vap_df = pd.DataFrame(data=[(round(data[\"Close\"], 1)), data[\"Volume\"]]).transpose()\n",
+ "\n",
+ " return vap_df.groupby(\"Close\").sum()[[\"Volume\"]]\n",
+ "\n",
+ "def display_vap(\n",
+ " data: Optional[pd.DataFrame] = None,\n",
+ " symbol: str = \"\",\n",
+ " ma: Optional[int] = None,\n",
+ " export: str = \"\",\n",
+ " sheet_name: Optional[str] = None,\n",
+ " external_axes: bool = False,\n",
+ ") -> Union[OpenBBFigure, None]:\n",
+ " \"\"\"Plots Volume-at-Price with an optional simple moving average.\n",
+ "\n",
+ " Parameters\n",
+ " ----------\n",
+ " data : pd.DataFrame\n",
+ " Dataframe of ohlc prices\n",
+ " symbol : str\n",
+ " Ticker\n",
+ " ma: int\n",
+ " Window for calculating the simple moving average.\n",
+ " sheet_name: str\n",
+ " Optionally specify the name of the sheet the data is exported to.\n",
+ " export: str\n",
+ " Format to export data as\n",
+ " external_axes : bool, optional\n",
+ " Whether to return the figure object or not, by default False\n",
+ " \"\"\"\n",
+ " if data is None or data.empty:\n",
+ " data = openbb.stocks.load(symbol, start_date=datetime.now().strftime(\"%Y-%m-%d\"), interval=1)\n",
+ " if data.empty:\n",
+ " return None\n",
+ " \n",
+ " if ma is None:\n",
+ " ma = 0\n",
+ " ma_df = pd.DataFrame()\n",
+ "\n",
+ " if \"vw\" in data.columns:\n",
+ " data[\"VWAP\"] = data[\"vw\"]\n",
+ " data[\"VWAP\"] = vwap(data)\n",
+ "\n",
+ " vap_df = vap(data)\n",
+ "\n",
+ " fig = make_subplots(\n",
+ " rows=1, cols=2, shared_xaxes=False, shared_yaxes=True, horizontal_spacing=0.001\n",
+ " )\n",
+ " fig.add_trace(\n",
+ " go.Bar(\n",
+ " x=vap_df.Volume.astype(int),\n",
+ " y=vap_df.index,\n",
+ " orientation=\"h\",\n",
+ " name=\"Volume at Price\",\n",
+ " opacity=0.25,\n",
+ " marker={\"color\": \"gray\"},\n",
+ " ),\n",
+ " row=1,\n",
+ " col=1,\n",
+ " )\n",
+ " fig.add_trace(\n",
+ " go.Scatter(x=data.index, y=data[\"VWAP\"], name=\"VWAP\", marker={\"color\": \"red\"}),\n",
+ " row=1,\n",
+ " col=2,\n",
+ " )\n",
+ " fig.add_trace(\n",
+ " go.Scatter(\n",
+ " x=data.index, y=data[\"Close\"], name=\"Close\", marker={\"color\": \"green\"}\n",
+ " ),\n",
+ " row=1,\n",
+ " col=2,\n",
+ " )\n",
+ " if ma != 0:\n",
+ " ma_df = sma(data[\"Close\"], ma).iloc[:, 0]\n",
+ " fig.add_trace(\n",
+ " go.Scatter(\n",
+ " x=ma_df.index,\n",
+ " y=ma_df,\n",
+ " name=f\"SMA {ma}\",\n",
+ " marker={\"color\": \"orange\"},\n",
+ " ),\n",
+ " row=1,\n",
+ " col=2,\n",
+ " )\n",
+ "\n",
+ " fig.update_layout(\n",
+ " yaxis2=dict(\n",
+ " zeroline=False,\n",
+ " showticklabels=False,\n",
+ " showgrid=False,\n",
+ " mirror=True,\n",
+ " showline=True,\n",
+ " ticklen=0,\n",
+ " ),\n",
+ " xaxis2=dict(\n",
+ " zeroline=False,\n",
+ " mirror=True,\n",
+ " showline=True,\n",
+ " ticks=\"outside\",\n",
+ " showgrid=False,\n",
+ " ticklen=0,\n",
+ " domain=[0, 0],\n",
+ " ),\n",
+ " xaxis1=dict(\n",
+ " zeroline=False,\n",
+ " showline=False,\n",
+ " showticklabels=False,\n",
+ " showgrid=False,\n",
+ " autorange=False,\n",
+ " mirror=False,\n",
+ " range=[0, max(vap_df.Volume)],\n",
+ " ticklen=0,\n",
+ " domain=[0, 0],\n",
+ " ),\n",
+ " yaxis1=dict(\n",
+ " zeroline=False,\n",
+ " showgrid=False,\n",
+ " showticklabels=True,\n",
+ " ticks=\"outside\",\n",
+ " mirror=True,\n",
+ " showline=False,\n",
+ " ticklen=0,\n",
+ " ),\n",
+ " plot_bgcolor=\"rgba(0,0,0,0)\",\n",
+ " title=f\"{symbol} - Volume at Price\",\n",
+ " title_y=1,\n",
+ " title_x=0.5,\n",
+ " legend=dict(\n",
+ " orientation=\"h\",\n",
+ " yanchor=\"top\",\n",
+ " y=1.115,\n",
+ " xanchor=\"right\",\n",
+ " x=1,\n",
+ " bgcolor=\"rgba(0,0,0,0)\"\n",
+ " ),\n",
+ " )\n",
+ " # Using the OpenBBFigure class will provide additional processing like removing the time periods between trading days.\n",
+ " ta = OpenBBFigure(fig)\n",
+ "\n",
+ " return ta.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d18c378b",
+ "metadata": {},
+ "source": [
+ "The function will check if the `data` parameter is used, and will grab one-minute data from today if not. There is also an optional parameter to add a simple moving average line."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 80,
+ "id": "25a88e10",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">Loading Intraday 1min data for QQQ with starting period 2023-08-23.\n",
+ "</pre>\n"
+ ],
+ "text/plain": [
+ "Loading Intraday 1min data for QQQ with starting period 2023-08-23.\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.plotly.v1+json": {
+ "config": {
+ "displaylogo": false,
+ "plotlyServerURL": "https://plot.ly",
+ "scrollZoom": true
+ },
+ "data": [
+ {
+ "marker": {
+ "color": "gray",
+ "line": {
+ "width": 0.15
+ }
+ },
+ "name": "Volume at Price",
+ "opacity": 0.25,
+ "orientation": "h",
+ "type": "bar",
+ "x": [
+ 418695,
+ 156792,
+ 647207,
+ 2341760,
+ 261823,
+ 278826,
+ 311512,
+ 323116,
+ 221954,
+ 634974,
+ 237158,
+ 317011,
+ 169302,
+ 455307,
+ 64683,
+ 954020,
+ 553816,
+ 149883,
+ 107005,
+ 750123,
+ 355684,
+ 174201,
+ 688809,
+ 502720,
+ 546406,
+ 550109,
+ 314513,
+ 311710,
+ 521756,
+ 103543,
+ 538149,
+ 1252361,
+ 1727588,
+ 3072788,
+ 1137470,
+ 1444764,
+ 2441902,
+ 1622618,
+ 751166,
+ 972414,
+ 535703,
+ 735372,
+ 766396,
+ 784820,
+ 736010,
+ 509624,
+ 561723,
+ 438226,
+ 180454
+ ],
+ "xaxis": "x",
+ "y": [
+ 364.6,
+ 364.7,
+ 364.8,
+ 364.9,
+ 365,
+ 365.1,
+ 365.4,
+ 365.5,
+ 365.7,
+ 365.8,
+ 365.9,
+ 366.1,
+ 366.2,
+ 366.4,
+ 366.5,
+ 366.6,
+ 366.7,
+ 366.8,
+ 366.9,
+ 367.1,
+ 367.2,
+ 367.3,
+ 367.4,
+ 367.5,
+ 367.6,
+ 367.7,
+ 367.8,
+ 368,
+ 368.2,
+ 368.3,
+ 368.4,
+ 368.5,
+ 368.6,
+ 368.7,
+ 368.8,
+ 368.9,
+ 369,
+ 369.1,
+ 369.2,
+ 369.3,
+ 369.4,
+ 369.5,
+ 369.6,
+ 369.7,
+ 369.8,
+ 369.9,
+ 370,
+ 370.1,
+ 370.2
+ ],
+ "yaxis": "y"
+ },
+ {
+ "hovertemplate": "%{y}",
+ "marker": {
+ "color": "red"
+ },
+ "name": "VWAP",
+ "type": "scatter",
+ "x": [
+ "2023-08-23T09:30:00",
+ "2023-08-23T09:31:00",
+ "2023-08-23T09:32:00",
+ "2023-08-23T09:33:00",
+ "2023-08-23T09:34:00",
+ "2023-08-23T09:35:00",
+ "2023-08-23T09:36:00",
+ "2023-08-23T09:37:00",
+ "2023-08-23T09:38:00",
+ "2023-08-23T09:39:00",
+ "2023-08-23T09:40:00",
+ "2023-08-23T09:41:00",
+ "2023-08-23T09:42:00",
+ "2023-08-23T09:43:00",
+ "2023-08-23T09:44:00",
+ "2023-08-23T09:45:00",
+ "2023-08-23T09:46:00",
+ "2023-08-23T09:47:00",
+ "2023-08-23T09:48:00",
+ "2023-08-23T09:49:00",
+ "2023-08-23T09:50:00",
+ "2023-08-23T09:51:00",
+ "2023-08-23T09:52:00",
+ "2023-08-23T09:53:00",
+ "2023-08-23T09:54:00",
+ "2023-08-23T09:55:00",
+ "2023-08-23T09:56:00",
+ "2023-08-23T09:57:00",
+ "2023-08-23T09:58:00",
+ "2023-08-23T09:59:00",
+ "2023-08-23T10:00:00",
+ "2023-08-23T10:01:00",
+ "2023-08-23T10:02:00",
+ "2023-08-23T10:03:00",
+ "2023-08-23T10:04:00",
+ "2023-08-23T10:05:00",
+ "2023-08-23T10:06:00",
+ "2023-08-23T10:07:00",
+ "2023-08-23T10:08:00",
+ "2023-08-23T10:09:00",
+ "2023-08-23T10:10:00",
+ "2023-08-23T10:11:00",
+ "2023-08-23T10:12:00",
+ "2023-08-23T10:13:00",
+ "2023-08-23T10:14:00",
+ "2023-08-23T10:15:00",
+ "2023-08-23T10:16:00",
+ "2023-08-23T10:17:00",
+ "2023-08-23T10:18:00",
+ "2023-08-23T10:19:00",
+ "2023-08-23T10:20:00",
+ "2023-08-23T10:21:00",
+ "2023-08-23T10:22:00",
+ "2023-08-23T10:23:00",
+ "2023-08-23T10:24:00",
+ "2023-08-23T10:25:00",
+ "2023-08-23T10:26:00",
+ "2023-08-23T10:27:00",
+ "2023-08-23T10:28:00",
+ "2023-08-23T10:29:00",
+ "2023-08-23T10:30:00",
+ "2023-08-23T10:31:00",
+ "2023-08-23T10:32:00",
+ "2023-08-23T10:33:00",
+ "2023-08-23T10:34:00",
+ "2023-08-23T10:35:00",
+ "2023-08-23T10:36:00",
+ "2023-08-23T10:37:00",
+ "2023-08-23T10:38:00",
+ "2023-08-23T10:39:00",
+ "2023-08-23T10:40:00",
+ "2023-08-23T10:41:00",
+ "2023-08-23T10:42:00",
+ "2023-08-23T10:43:00",
+ "2023-08-23T10:44:00",
+ "2023-08-23T10:45:00",
+ "2023-08-23T10:46:00",
+ "2023-08-23T10:47:00",
+ "20