Files
OpenBB/jupyterlab/dashboards/stocks_interactive.ipynb
Colin Delahunty caa2c88c12 Stock Dashboard (#1018)
* Added notebook

* Massive refactoring

* Significant enhancements

* Error handling, variable renaming, refacotring

* Reformatted widgets

* Made rolling adjustable

* Fixed date bug

* Began transition to plotly

* Expanding dict

* Expanded analysis, formatted with black

* Added

* Replaced matplotlib with Plotly

* Slight updates

* Enhanced ability to format dashboard

* Fixed duplicate graph errors

* Fixed duplicate graph errors

* Found out which renderers work where

* removed unused code

* Final enhancements

* Updated requirements

* Added conda dependencies

* removing unneeded changes

* removing unneeded changes

* removing unneeded changes

* Updated git ignore

* Added notes

* removed unused code, added comma warning

* Allowed multi select

* Updated dependencies

* Simplified dependencies

* Fixed dependencies again...

* Added line endings

* Improved widgets and title

* Dider improvements

* Removed DS Store (sorry Nintendo)

* Updated requirements files

* Updated yml

* Updated yml

* Updated yaml

* Fixing change

* Allow for lab or Voila

* Updated toml

* Updated requirements.txt

* Update conda-3-8-env.yaml

* Update conda-3-8-env-full.yaml

* Updated

* A tragic forgetting

* Dependency reset (not ready to merge

* removed high entropy

* Another dependency update

* Added in my dependencies
2021-12-30 12:22:21 +00:00

156 lines
5.8 KiB
Plaintext
Vendored

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "e9ad60bc",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from datetime import datetime, timedelta\n",
"import ipywidgets as widgets\n",
"import plotly.graph_objs as go\n",
"import yfinance as yf\n",
"import pandas as pd\n",
"from IPython.display import display"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "beb36881",
"metadata": {},
"outputs": [],
"source": [
"views = {\n",
" \"Raw Data\": lambda x, y: x,\n",
" \"Percent Change\": lambda x, y: x.pct_change(),\n",
" \"Rolling Average\": lambda x, y: x.rolling(y).mean(),\n",
" \"Rolling Variance\": lambda x, y: x.rolling(y).var(),\n",
" \"Rolling Standard Deviation\": lambda x, y: x.rolling(y).var() ** 0.5,\n",
" \"Rolling Coefficient of Variation\": lambda x, y: (x.rolling(y).var() ** 0.5)\n",
" / (x.rolling(y).mean()),\n",
"}\n",
"\n",
"\n",
"def format_plotly(fig, calc, data, start, end):\n",
" fig.update_yaxes(title=None)\n",
" fig.update_xaxes(title=None)\n",
" if calc:\n",
" if len(calc) == 1:\n",
" fig_title = f\"{calc[0]} of {data} from {start.strftime('%Y/%m/%d')} to {end.strftime('%Y/%m/%d')}\"\n",
" else:\n",
" fig_title = f\"{', '.join(calc)} of {data} from {start.strftime('%Y/%m/%d')} to {end.strftime('%Y/%m/%d')}\"\n",
" fig.update_layout(\n",
" autosize=False,\n",
" width=1000,\n",
" height=500,\n",
" title={\n",
" \"text\": fig_title,\n",
" \"y\": 0.95,\n",
" \"x\": 0.5,\n",
" \"xanchor\": \"center\",\n",
" \"yanchor\": \"top\",\n",
" },\n",
" )\n",
"\n",
"\n",
"last_tickers = \"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f8c2f65c",
"metadata": {
"tags": [
"parameters"
]
},
"outputs": [],
"source": [
"def view_chart(calculation, data, rolling, start, end, tickers):\n",
" global last_tickers, df\n",
" if tickers and tickers[-1] == \",\":\n",
" if tickers != last_tickers:\n",
" df = yf.download(tickers, period=\"max\", progress=False)\n",
" last_tickers = tickers\n",
"\n",
" start_n = datetime(start.year, start.month, start.day)\n",
" end_n = datetime(end.year, end.month, end.day)\n",
" fig = go.Figure()\n",
" for item in calculation:\n",
" calcs = views[item](df[data], rolling)\n",
" result = calcs.loc[(calcs.index >= start_n) & (calcs.index <= end_n)]\n",
" \n",
" if isinstance(result, pd.Series):\n",
" plot = go.Scatter(x=result.index, y=result, mode=\"lines\", name=f\"{tickers.split(',')[0]} {item}\")\n",
" fig.add_trace(plot)\n",
" else:\n",
" for val in result:\n",
" plot = go.Scatter(x=result.index,y=result[val],mode=\"lines\",name=f\"{val.upper()} {item}\")\n",
" fig.add_trace(plot)\n",
"\n",
" format_plotly(fig, calculation, data, start, end)\n",
" # Jupyter-lab and Google Colab: do not use renderer argument\n",
" # VS Code: ADD: renderer=\"cocalc\"\n",
" # Voila: ADD: renderer=\"notebook\"\n",
" if os.environ.get('SERVER_SOFTWARE','jupyter').startswith('voila'):\n",
" fig.show(config={\"showTips\": False}, renderer=\"notebook\")\n",
" else:\n",
" fig.show(config={\"showTips\": False})\n",
"\n",
"w_auto = widgets.Layout(width=\"auto\")\n",
"calc_widget = widgets.SelectMultiple(options=list(views.keys()), value=[\"Raw Data\"], layout=w_auto)\n",
"data_widget = widgets.Dropdown(\n",
" options=[\"Open\", \"Close\", \"High\", \"Low\", \"Volume\"], value=\"Close\", layout=w_auto\n",
")\n",
"rolling_widget = widgets.Dropdown(options=list(range(2, 101)), value=60, layout=w_auto)\n",
"start_widget = widgets.DatePicker(value=datetime.today() - timedelta(days=365), layout=w_auto)\n",
"end_widget = widgets.DatePicker(value=datetime.today(), layout=w_auto)\n",
"tickers_widget = widgets.Text(value=\"TSLA,\", layout=w_auto)\n",
"data_box = widgets.VBox([tickers_widget, data_widget, rolling_widget])\n",
"date_box = widgets.VBox([start_widget, end_widget])\n",
"controls = widgets.HBox([calc_widget, data_box, date_box], layout=widgets.Layout(width=\"60%\"))\n",
"\n",
"stocks_view = widgets.interactive_output(\n",
" view_chart,\n",
" {\"calculation\": calc_widget,\n",
" \"data\": data_widget,\n",
" \"rolling\": rolling_widget,\n",
" \"start\": start_widget,\n",
" \"end\": end_widget,\n",
" \"tickers\": tickers_widget,\n",
" }\n",
")\n",
"\n",
"title_html = '<h1>Stock Analysis Dashboard</h1>'\n",
"warning_html = '<p style=\"color:red\"=>You MUST use a comma after EVERY stock you type in.</p>'\n",
"app_contents = [widgets.HTML(title_html), controls, widgets.HTML(warning_html), stocks_view]\n",
"app = widgets.VBox(app_contents)\n",
"\n",
"\n",
"display(app)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.9.7 64-bit ('base': conda)",
"name": "python397jvsc74a57bd0e896a00ead8b521528d79ac9ef24990696f2b751eb283ab8e0d078c9c4971ffc"
},
"language_info": {
"name": "python",
"version": ""
},
"metadata": {
"interpreter": {
"hash": "e896a00ead8b521528d79ac9ef24990696f2b751eb283ab8e0d078c9c4971ffc"
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}