mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-02 07:23:25 +00:00
* include plotly.js in reports html, implement new plotly multi-legends feature * use `ensure_backend` to `check_backend`, improve charts in reports * requirements files * fix files with `CRLF` line endings * Update widget_helpers.py * Update widget_helpers.py * handle unsupported plotly multiple legends version error
500 lines
13 KiB
Plaintext
Vendored
500 lines
13 KiB
Plaintext
Vendored
{
|
|
"cells": [
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "70ba2c8a",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Notebook setup"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "driven-billion",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import warnings\n",
|
|
"import numpy as np\n",
|
|
"import datetime\n",
|
|
"\n",
|
|
"from IPython.display import HTML\n",
|
|
"\n",
|
|
"import openbb_terminal.config_terminal as cfg\n",
|
|
"from openbb_terminal import OpenBBFigure, theme\n",
|
|
"from openbb_terminal.helper_classes import TerminalStyle\n",
|
|
"from openbb_terminal.core.plots.plotly_ta.ta_class import PlotlyTA\n",
|
|
"\n",
|
|
"warnings.filterwarnings(\"ignore\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "473e83c7",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Suppressing sdk logs\n",
|
|
"from openbb_terminal.core.session.current_system import set_system_variable\n",
|
|
"\n",
|
|
"set_system_variable(\"LOGGING_SUPPRESS\", True)\n",
|
|
"\n",
|
|
"# Import the OpenBB SDK\n",
|
|
"from openbb_terminal.sdk import openbb, widgets"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "c3fe7db5-ec6a-42cf-9e66-52dc1de22370",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from openbb_terminal.core.session.current_user import get_current_user\n",
|
|
"\n",
|
|
"user = get_current_user()\n",
|
|
"\n",
|
|
"cfg.theme = TerminalStyle(\n",
|
|
" user.preferences.MPL_STYLE,\n",
|
|
" user.preferences.PMF_STYLE,\n",
|
|
" user.preferences.RICH_STYLE,\n",
|
|
")\n",
|
|
"theme.apply_style(\"light\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "36091f30",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"stylesheet = widgets.html_report_stylesheet()"
|
|
]
|
|
},
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "807fda4e",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Select Ticker"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "intended-sherman",
|
|
"metadata": {
|
|
"tags": [
|
|
"parameters"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Parameters that will be replaced when calling this notebook\n",
|
|
"# Do not leave parameters blank as notebook will not run otherwise\n",
|
|
"symbol = \"GLD\"\n",
|
|
"report_name = \"Equity Report for VTI\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e1f87190",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"ticker = symbol"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "a441ddbc-d75b-4a18-84d4-e01b677674d3",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"if \".\" in ticker:\n",
|
|
" import sys\n",
|
|
"\n",
|
|
" sys.exit(0)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "1be26dae-cafe-4a22-80aa-eff296fc1a9b",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"ticker_data = openbb.stocks.load(\n",
|
|
" symbol=ticker, start_date=datetime.datetime.now() - datetime.timedelta(days=4 * 30)\n",
|
|
")\n",
|
|
"ticker_data = openbb.stocks.process_candle(data=ticker_data)\n",
|
|
"\n",
|
|
"author = \"OpenBB\"\n",
|
|
"report_title = f\"ETF RESEARCH REPORT ON {ticker.upper()}\"\n",
|
|
"report_date = datetime.datetime.now().strftime(\"%d %B, %Y\")\n",
|
|
"report_time = datetime.datetime.now().strftime(\"%H:%M\")\n",
|
|
"report_timezone = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo\n",
|
|
"report_title, report_date, report_time, report_timezone"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "2ecfcf81",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# info = openbb.etf.summary(name=ticker)\n",
|
|
"# info"
|
|
]
|
|
},
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "f8a0d747",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Data"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "39b8e77d",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"data = openbb.stocks.load(ticker)\n",
|
|
"\n",
|
|
"candle_chart = openbb.etf.candle(\n",
|
|
" symbol=ticker,\n",
|
|
" data=data,\n",
|
|
" external_axes=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"if candle_chart:\n",
|
|
" candle_chart = candle_chart.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "f751f57c",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import pandas as pd\n",
|
|
"\n",
|
|
"sectors = openbb.etf.weights(ticker)\n",
|
|
"sector_weights_formatted = {}\n",
|
|
"for sector_weight in sectors:\n",
|
|
" sector_weights_formatted[sector_weight[\"sector\"]] = (\n",
|
|
" float(sector_weight[\"weightPercentage\"].strip(\"%\")) / 100\n",
|
|
" )\n",
|
|
"sector_weights_formatted = dict(sorted(sector_weights_formatted.items()))\n",
|
|
"weights_df = pd.DataFrame.from_dict(sector_weights_formatted, orient=\"index\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "324e2d4b-b2f6-4da3-bac4-ef785ad4e436",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"weights_chart = \"\"\n",
|
|
"\n",
|
|
"if \"Percentage\" in weights_df.columns:\n",
|
|
" weights_df.columns = [\"Percentage\"]\n",
|
|
"\n",
|
|
"if (\n",
|
|
" \"Percentage\" in weights_df.columns\n",
|
|
" and len(weights_df[weights_df[\"Percentage\"] > 10].index) > 1\n",
|
|
"):\n",
|
|
" colors = theme.get_colors()\n",
|
|
" fig = OpenBBFigure.create_subplots(\n",
|
|
" 1,\n",
|
|
" 3,\n",
|
|
" specs=[[{\"type\": \"domain\"}, {\"type\": \"pie\", \"colspan\": 2}, None]],\n",
|
|
" row_heights=[1],\n",
|
|
" column_widths=[0.1, 0.8, 0.1],\n",
|
|
" )\n",
|
|
"\n",
|
|
" fig.add_pie(\n",
|
|
" labels=weights_df[weights_df[\"Percentage\"] > 10].index,\n",
|
|
" values=weights_df[weights_df[\"Percentage\"] > 10][\"Percentage\"],\n",
|
|
" textinfo=\"label+percent\",\n",
|
|
" hoverinfo=\"label+percent\",\n",
|
|
" automargin=True,\n",
|
|
" rotation=45,\n",
|
|
" row=1,\n",
|
|
" col=2,\n",
|
|
" )\n",
|
|
" fig.update_traces(\n",
|
|
" textposition=\"outside\",\n",
|
|
" textfont_size=15,\n",
|
|
" marker=dict(\n",
|
|
" colors=colors,\n",
|
|
" line=dict(color=\"#F5EFF3\", width=0.8),\n",
|
|
" ),\n",
|
|
" )\n",
|
|
"\n",
|
|
" fig.update_layout(\n",
|
|
" margin=dict(t=40, b=20),\n",
|
|
" title=dict(\n",
|
|
" text=f\"Sector holdings of {ticker}\",\n",
|
|
" y=0.98,\n",
|
|
" x=0.5,\n",
|
|
" xanchor=\"center\",\n",
|
|
" yanchor=\"top\",\n",
|
|
" ),\n",
|
|
" colorway=colors,\n",
|
|
" showlegend=False,\n",
|
|
" )\n",
|
|
"\n",
|
|
" weights_chart = fig.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "d8bb53c1-147e-4342-af61-0d0a9cc56e59",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"holdings = openbb.etf.holdings(ticker)\n",
|
|
"holdings"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "b60ebf25",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"indicators = dict(\n",
|
|
" ema=dict(length=[50]),\n",
|
|
" sma=dict(length=[50]),\n",
|
|
" wma=dict(length=[50]),\n",
|
|
")\n",
|
|
"\n",
|
|
"ma_chart = PlotlyTA.plot(ticker_data, indicators, symbol, candles=False, volume=False)\n",
|
|
"\n",
|
|
"if ma_chart:\n",
|
|
" ma_chart = ma_chart.show(external=True)\n",
|
|
" ma_chart = ma_chart.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "fa02a874",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"macd_chart = openbb.ta.macd_chart(\n",
|
|
" ticker_data[\"Close\"], symbol=symbol, external_axes=True\n",
|
|
")\n",
|
|
"\n",
|
|
"if macd_chart:\n",
|
|
" macd_chart = macd_chart.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "de3d59c7",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"cci_chart = openbb.ta.cci_chart(ticker_data, symbol=symbol, external_axes=True)\n",
|
|
"\n",
|
|
"if cci_chart:\n",
|
|
" cci_chart = cci_chart.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "44326981",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"stoch_chart = openbb.ta.stoch_chart(ticker_data, symbol=symbol, external_axes=True)\n",
|
|
"\n",
|
|
"if stoch_chart:\n",
|
|
" stoch_chart = stoch_chart.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "3e171fe5",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"adx_chart = openbb.ta.adx_chart(ticker_data, symbol=symbol, external_axes=True)\n",
|
|
"\n",
|
|
"if adx_chart:\n",
|
|
" adx_chart = adx_chart.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "fc1a5418",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"bbands_chart = openbb.ta.bbands_chart(ticker_data, symbol=symbol, external_axes=True)\n",
|
|
"\n",
|
|
"if bbands_chart:\n",
|
|
" bbands_chart = bbands_chart.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "d4be9f55",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"ad_chart = openbb.ta.ad_chart(ticker_data, symbol=symbol, external_axes=True)\n",
|
|
"\n",
|
|
"if ad_chart:\n",
|
|
" ad_chart = ad_chart.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "4d29aafa",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"ta_rsi = openbb.ta.rsi_chart(ticker_data[\"Close\"], external_axes=True)\n",
|
|
"\n",
|
|
"if ta_rsi:\n",
|
|
" ta_rsi = ta_rsi.to_html()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e539e995",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"df = openbb.ta.rsi(ticker_data[\"Close\"])\n",
|
|
"rsi_value = round(df.values[-1][0], 2)\n",
|
|
"rsi_value"
|
|
]
|
|
},
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "ac501a32-124d-4d21-aae1-a8d147bb1071",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Render the report template to a file"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "abfe37e4-ea38-42c3-8fb5-7cceb233fb12",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"body = \"\"\n",
|
|
"\n",
|
|
"\n",
|
|
"body += widgets.header(\n",
|
|
" author,\n",
|
|
" report_date,\n",
|
|
" report_time,\n",
|
|
" report_timezone,\n",
|
|
" f\"<b>ETF RESEARCH REPORT:</b> {ticker.upper()}\",\n",
|
|
" plotly_js=True,\n",
|
|
")\n",
|
|
"\n",
|
|
"body += widgets.tablinks(\n",
|
|
" [\n",
|
|
" \"SUMMARY\",\n",
|
|
" \"Technical Analysis\",\n",
|
|
" ]\n",
|
|
")\n",
|
|
"\n",
|
|
"htmlcode = widgets.h(3, \"Summary\")\n",
|
|
"# htmlcode += widgets.p(info)\n",
|
|
"htmlcode += widgets.row([candle_chart])\n",
|
|
"\n",
|
|
"htmlcode += widgets.p(\"The ETF has the following weights distribution:\")\n",
|
|
"\n",
|
|
"htmlcode += widgets.row([weights_df.to_html()])\n",
|
|
"htmlcode += widgets.row([weights_chart])\n",
|
|
"\n",
|
|
"htmlcode += widgets.p(\"And has funds in the following assets:\")\n",
|
|
"htmlcode += widgets.row([holdings.to_html()])\n",
|
|
"\n",
|
|
"body += widgets.add_tab(\"SUMMARY\", htmlcode)\n",
|
|
"\n",
|
|
"htmlcode = widgets.row([widgets.h(3, f\"Moving Averages for {symbol}\") + ma_chart])\n",
|
|
"htmlcode += widgets.row([macd_chart or \"\"])\n",
|
|
"htmlcode += widgets.row([ta_rsi or \"\"])\n",
|
|
"htmlcode += widgets.row([stoch_chart or \"\"])\n",
|
|
"htmlcode += widgets.row([cci_chart or \"\"])\n",
|
|
"htmlcode += widgets.row([ad_chart or \"\"])\n",
|
|
"htmlcode += widgets.row([bbands_chart or \"\"])\n",
|
|
"htmlcode += widgets.row([adx_chart or \"\"])\n",
|
|
"body += widgets.add_tab(\"Technical Analysis\", htmlcode)\n",
|
|
"\n",
|
|
"\n",
|
|
"body += widgets.tab_clickable_and_save_evt()\n",
|
|
"\n",
|
|
"report = widgets.html_report(title=report_name, stylesheet=stylesheet, body=body)\n",
|
|
"\n",
|
|
"\n",
|
|
"# to save the results\n",
|
|
"with open(report_name + \".html\", \"w\", encoding=\"utf-8\") as fh:\n",
|
|
" fh.write(report)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"celltoolbar": "Tags",
|
|
"kernelspec": {
|
|
"display_name": "venv",
|
|
"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.10.5"
|
|
},
|
|
"vscode": {
|
|
"interpreter": {
|
|
"hash": "381a209f752e9104bff95ec5e80679ea2e476866b80e4326f1ee6b7658af6049"
|
|
}
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|