mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-29 05:21:48 +00:00
Handling log supression (#4625)
* simplifying the way we deal with the SystemModel by removing the need for system.json file * removing the responsability of supression from the controllers * supressing logs on reports * fix etf report * supressing logs on dashboards * black * typo * ruff * pylint * refacotr def extract_parameters --------- Co-authored-by: James Maslek <jmaslek11@gmail.com>
This commit is contained in:
@@ -3,7 +3,8 @@ from copy import deepcopy
|
||||
|
||||
# IMPORTS INTERNAL
|
||||
from openbb_terminal.core.models import SystemModel
|
||||
from openbb_terminal.core.session.system_handler import handle_system, save_system
|
||||
from openbb_terminal.core.session.env_handler import read_env
|
||||
from openbb_terminal.core.session.utils import load_dict_to_model
|
||||
|
||||
|
||||
def get_current_system() -> SystemModel:
|
||||
@@ -14,8 +15,8 @@ def get_current_system() -> SystemModel:
|
||||
def set_current_system(system: SystemModel):
|
||||
"""Set current system."""
|
||||
global __system # pylint: disable=global-statement
|
||||
save_system(system)
|
||||
__system = system
|
||||
|
||||
|
||||
__system = handle_system()
|
||||
__env_dict = read_env()
|
||||
__system = load_dict_to_model(__env_dict, SystemModel)
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
import atexit
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from pydantic.json import pydantic_encoder
|
||||
|
||||
from openbb_terminal.core.config.paths import (
|
||||
SETTINGS_DIRECTORY,
|
||||
)
|
||||
from openbb_terminal.core.models import SystemModel
|
||||
from openbb_terminal.core.session.env_handler import read_env
|
||||
from openbb_terminal.core.session.utils import load_dict_to_model
|
||||
|
||||
SYSTEM_FILE_PATH = SETTINGS_DIRECTORY / "system.json"
|
||||
|
||||
|
||||
def handle_system(file_path: Path = SYSTEM_FILE_PATH) -> SystemModel:
|
||||
"""
|
||||
Handle the system.
|
||||
|
||||
Reads system data from file if it exists, else reads environment variable data.
|
||||
Returns a system model built from the loaded data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
file_path (Path): The file path.
|
||||
|
||||
Returns
|
||||
-------
|
||||
SystemModel: The system model.
|
||||
"""
|
||||
|
||||
try:
|
||||
if os.path.isfile(file_path):
|
||||
system_data = {}
|
||||
with open(file_path) as f:
|
||||
system_data = json.load(f)
|
||||
if system_data:
|
||||
return load_dict_to_model(system_data, SystemModel)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
__env_dict = read_env()
|
||||
system = load_dict_to_model(__env_dict, SystemModel)
|
||||
save_system(system=system, file_path=file_path)
|
||||
subscribe_delete_system_on_exit(file_path=file_path)
|
||||
return system
|
||||
|
||||
|
||||
def save_system(system: SystemModel, file_path: Path = SYSTEM_FILE_PATH):
|
||||
"""
|
||||
Write system to file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
system (SystemModel): The system model.
|
||||
file_path (Path): The file path.
|
||||
|
||||
Returns
|
||||
-------
|
||||
system (SystemModel): The system model.
|
||||
"""
|
||||
|
||||
try:
|
||||
with open(file_path, "w") as f:
|
||||
json_content = json.dumps(system, default=pydantic_encoder)
|
||||
f.write(json_content)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def subscribe_delete_system_on_exit(file_path: Path):
|
||||
"""
|
||||
Deletes the system file on exiting the application.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
file_path (Path): The file path.
|
||||
"""
|
||||
|
||||
def delete_file(file_path: Path):
|
||||
if os.path.isfile(file_path):
|
||||
os.remove(file_path)
|
||||
|
||||
atexit.register(delete_file, file_path=file_path)
|
||||
@@ -18,7 +18,6 @@ import dotenv
|
||||
import numpy as np
|
||||
import psutil
|
||||
|
||||
import openbb_terminal.config_terminal as cfg
|
||||
from openbb_terminal.base_helpers import load_env_vars, strtobool
|
||||
from openbb_terminal.core.config.paths import REPOSITORY_DIRECTORY, SETTINGS_ENV_FILE
|
||||
from openbb_terminal.core.plots.backend import plots_backend
|
||||
@@ -199,7 +198,6 @@ class DashboardsController(BaseController):
|
||||
cmd += " --theme=dark"
|
||||
|
||||
if ns_parser.input or response.lower() == "y" and not process_check:
|
||||
cfg.change_logging_suppress(new_value=True)
|
||||
self.processes.append(
|
||||
psutil.Popen(
|
||||
f"{cmd} --no-browser --port {port}"
|
||||
@@ -211,7 +209,6 @@ class DashboardsController(BaseController):
|
||||
env=os.environ,
|
||||
)
|
||||
)
|
||||
cfg.change_logging_suppress(new_value=False)
|
||||
atexit.register(self.kill_processes)
|
||||
|
||||
console.print(
|
||||
|
||||
@@ -9,10 +9,17 @@ import streamlit as st
|
||||
import yfinance as yf
|
||||
from rich.table import Table
|
||||
|
||||
import openbb_terminal.config_terminal as cfg
|
||||
from openbb_terminal.core.plots.plotly_helper import OpenBBFigure
|
||||
from openbb_terminal.forecast import helpers
|
||||
from openbb_terminal.rich_config import console
|
||||
from openbb_terminal.sdk import openbb
|
||||
|
||||
# Suppressing sdk logs
|
||||
cfg.change_logging_suppress(new_value=True)
|
||||
|
||||
# Import the OpenBB SDK
|
||||
# pylint: disable=wrong-import-position
|
||||
from openbb_terminal.sdk import openbb # noqa: E402
|
||||
|
||||
st.set_page_config(
|
||||
layout="wide",
|
||||
|
||||
@@ -8,11 +8,18 @@ import pandas as pd
|
||||
import streamlit as st
|
||||
from streamlit.delta_generator import DeltaGenerator
|
||||
|
||||
import openbb_terminal.config_terminal as cfg
|
||||
from openbb_terminal.common.technical_analysis import ta_helpers
|
||||
from openbb_terminal.core.plots.plotly_helper import OpenBBFigure
|
||||
from openbb_terminal.core.plots.plotly_ta.ta_class import PlotlyTA
|
||||
from openbb_terminal.rich_config import console
|
||||
from openbb_terminal.sdk import openbb
|
||||
|
||||
# Suppressing sdk logs
|
||||
cfg.change_logging_suppress(new_value=True)
|
||||
|
||||
# Import the OpenBB SDK
|
||||
# pylint: disable=wrong-import-position
|
||||
from openbb_terminal.sdk import openbb # noqa: E402
|
||||
|
||||
pd.options.plotting.backend = "plotly"
|
||||
st.set_page_config(
|
||||
|
||||
733
openbb_terminal/dashboards/voila/forecast.ipynb
vendored
733
openbb_terminal/dashboards/voila/forecast.ipynb
vendored
@@ -1,361 +1,374 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e9ad60bc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime, timedelta\n",
|
||||
"from typing import Callable, Any\n",
|
||||
"from inspect import signature\n",
|
||||
"import warnings, logging\n",
|
||||
"\n",
|
||||
"import ipywidgets as widgets\n",
|
||||
"import yfinance as yf\n",
|
||||
"import pandas as pd\n",
|
||||
"from IPython.display import display\n",
|
||||
"\n",
|
||||
"from openbb_terminal.sdk import openbb, theme\n",
|
||||
"\n",
|
||||
"theme.apply_style()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "beb36881",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"try:\n",
|
||||
" has_forecast = True\n",
|
||||
" model_opts = {\n",
|
||||
" \"expo\": openbb.forecast.expo_chart,\n",
|
||||
" \"theta\": openbb.forecast.theta_chart,\n",
|
||||
" \"linregr\": openbb.forecast.linregr_chart,\n",
|
||||
" \"regr\": openbb.forecast.regr_chart,\n",
|
||||
" \"rnn\": openbb.forecast.rnn_chart,\n",
|
||||
" \"brnn\": openbb.forecast.brnn_chart,\n",
|
||||
" \"nbeats\": openbb.forecast.nbeats_chart,\n",
|
||||
" \"tcn\": openbb.forecast.tcn_chart,\n",
|
||||
" \"trans\": openbb.forecast.trans_chart,\n",
|
||||
" \"tft\": openbb.forecast.tft_chart,\n",
|
||||
" \"nhits\": openbb.forecast.nhits_chart,\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" feat_engs = {\n",
|
||||
" \"ema\": openbb.forecast.ema,\n",
|
||||
" \"sto\": openbb.forecast.sto,\n",
|
||||
" \"rsi\": openbb.forecast.rsi,\n",
|
||||
" \"roc\": openbb.forecast.roc,\n",
|
||||
" \"mom\": openbb.forecast.mom,\n",
|
||||
" \"atr\": openbb.forecast.atr,\n",
|
||||
" \"delta\": openbb.forecast.delta,\n",
|
||||
" \"signal\": openbb.forecast.signal,\n",
|
||||
" }\n",
|
||||
"except AttributeError as e:\n",
|
||||
" print(e)\n",
|
||||
" has_forecast = False\n",
|
||||
" model_opts = {}\n",
|
||||
" feat_engs = {}\n",
|
||||
"\n",
|
||||
"interval_opts = [\n",
|
||||
" \"1m\",\n",
|
||||
" \"2m\",\n",
|
||||
" \"5m\",\n",
|
||||
" \"15m\",\n",
|
||||
" \"30m\",\n",
|
||||
" \"60m\",\n",
|
||||
" \"90m\",\n",
|
||||
" \"1h\",\n",
|
||||
" \"1d\",\n",
|
||||
" \"5d\",\n",
|
||||
" \"1wk\",\n",
|
||||
" \"1mo\",\n",
|
||||
" \"3mo\",\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def format_df(df: pd.DataFrame) -> pd.DataFrame:\n",
|
||||
" if len(df.columns) != 6:\n",
|
||||
" df.columns = [\"_\".join(col).strip() for col in df.columns.values]\n",
|
||||
" df.reset_index(inplace=True)\n",
|
||||
" df.columns = [x.lower() for x in df.columns]\n",
|
||||
" return df\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def has_parameter(func: Callable[..., Any], parameter: str) -> bool:\n",
|
||||
" params = signature(func).parameters\n",
|
||||
" parameters = params.keys()\n",
|
||||
" return parameter in parameters"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f8c2f65c",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"parameters"
|
||||
]
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Chart:\n",
|
||||
" def __init__(self):\n",
|
||||
" self.last_tickers = \"\"\n",
|
||||
" self.last_interval = \"1d\"\n",
|
||||
" self.df = pd.DataFrame()\n",
|
||||
" self.result = pd.DataFrame()\n",
|
||||
" self.infos = {}\n",
|
||||
"\n",
|
||||
" def handle_changes(\n",
|
||||
" self,\n",
|
||||
" past_covariates,\n",
|
||||
" start,\n",
|
||||
" end,\n",
|
||||
" interval,\n",
|
||||
" tickers,\n",
|
||||
" target_column,\n",
|
||||
" model,\n",
|
||||
" naive,\n",
|
||||
" forecast_only,\n",
|
||||
" ):\n",
|
||||
" ticker_list = tickers.split(\",\")\n",
|
||||
" if ticker_list:\n",
|
||||
" if tickers != self.last_tickers or interval != self.last_interval:\n",
|
||||
" if interval in [\"1d\", \"5d\", \"1wk\", \"1mo\", \"3mo\"]:\n",
|
||||
" self.df = yf.download(\n",
|
||||
" tickers, period=\"max\", interval=interval, progress=False\n",
|
||||
" )\n",
|
||||
" else:\n",
|
||||
" end_date = end + timedelta(days=1)\n",
|
||||
" self.df = yf.download(\n",
|
||||
" tickers,\n",
|
||||
" start=start,\n",
|
||||
" end=end_date,\n",
|
||||
" interval=interval,\n",
|
||||
" progress=False,\n",
|
||||
" )\n",
|
||||
" self.df = format_df(self.df)\n",
|
||||
" self.last_tickers = tickers\n",
|
||||
" self.last_interval = interval\n",
|
||||
" forecast_model = model_opts[model]\n",
|
||||
" self.forecast_model = forecast_model\n",
|
||||
" contains_covariates = has_parameter(forecast_model, \"past_covariates\")\n",
|
||||
"\n",
|
||||
" # Update Inputs\n",
|
||||
" if list(target_widget.options) != [\n",
|
||||
" x for x in self.df.columns if x != \"date\"\n",
|
||||
" ]:\n",
|
||||
" target_widget.options = [x for x in self.df.columns if x != \"date\"]\n",
|
||||
" return\n",
|
||||
" if list(past_covs_widget.options) != [\n",
|
||||
" x for x in self.df.columns if x != \"date\"\n",
|
||||
" ]:\n",
|
||||
" past_covs_widget.options = [x for x in self.df.columns if x != \"date\"]\n",
|
||||
" past_covs_widget.disabled = not contains_covariates\n",
|
||||
" return\n",
|
||||
" if past_covs_widget.disabled == contains_covariates:\n",
|
||||
" past_covs_widget.disabled = not contains_covariates\n",
|
||||
" column_widget.options = [x for x in self.df.columns if x != \"date\"]\n",
|
||||
"\n",
|
||||
" start_n = datetime(start.year, start.month, start.day)\n",
|
||||
" end_n = datetime(end.year, end.month, end.day)\n",
|
||||
" calcs = self.df\n",
|
||||
" if interval in [\"1d\", \"5d\", \"1wk\", \"1mo\", \"3mo\"]:\n",
|
||||
" result = calcs.loc[\n",
|
||||
" (calcs[\"date\"] >= start_n) & (calcs[\"date\"] <= end_n)\n",
|
||||
" ]\n",
|
||||
" else:\n",
|
||||
" result = calcs\n",
|
||||
" if not target_column:\n",
|
||||
" target_column = self.df.columns[0]\n",
|
||||
" kwargs = {}\n",
|
||||
" if contains_covariates and past_covariates != ():\n",
|
||||
" kwargs[\"past_covariates\"] = \",\".join(past_covariates)\n",
|
||||
" if has_parameter(forecast_model, \"naive\"):\n",
|
||||
" kwargs[\"naive\"] = naive\n",
|
||||
" if has_parameter(forecast_model, \"forecast_only\"):\n",
|
||||
" kwargs[\"forecast_only\"] = forecast_only\n",
|
||||
" # This sets up everything to run the function on button click\n",
|
||||
"\n",
|
||||
" self.result = result\n",
|
||||
" self.target_column = target_column\n",
|
||||
" self.n_predict = 5\n",
|
||||
" self.kwargs = kwargs\n",
|
||||
"\n",
|
||||
" def handle_click(self, to_run):\n",
|
||||
" if to_run:\n",
|
||||
" run_widget.value = False\n",
|
||||
" else:\n",
|
||||
" df = self.result.dropna()\n",
|
||||
" if not df.empty:\n",
|
||||
" self.forecast_model(\n",
|
||||
" self.result,\n",
|
||||
" target_column=self.target_column,\n",
|
||||
" n_predict=5,\n",
|
||||
" **self.kwargs\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" def handle_eng(self, target, feature):\n",
|
||||
" self.feature_target = target\n",
|
||||
" self.feature_model = feat_engs[feature]\n",
|
||||
"\n",
|
||||
" def handle_click2(self, to_run):\n",
|
||||
" if to_run:\n",
|
||||
" add_widget.value = False\n",
|
||||
" else:\n",
|
||||
" kwargs = {}\n",
|
||||
" if has_parameter(self.feature_model, \"target_column\"):\n",
|
||||
" kwargs[\"target_column\"] = self.feature_target\n",
|
||||
" self.df = self.feature_model(self.df, **kwargs)\n",
|
||||
" past_covs_widget.options = self.df.columns"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e0d4de31-1b4f-4c1f-8467-ca314a578d56",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"w_auto = widgets.Layout(width=\"auto\")\n",
|
||||
"model_value = list(model_opts)[0] if model_opts else None\n",
|
||||
"model_widget = widgets.Select(\n",
|
||||
" options=list(model_opts),\n",
|
||||
" value=model_value,\n",
|
||||
" layout=widgets.Layout(\n",
|
||||
" width=\"8%\",\n",
|
||||
" ),\n",
|
||||
")\n",
|
||||
"past_covs_widget = widgets.SelectMultiple(\n",
|
||||
" options=[\"\"],\n",
|
||||
" value=[\"\"],\n",
|
||||
" layout=widgets.Layout(\n",
|
||||
" width=\"8%\",\n",
|
||||
" ),\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"base_date = (datetime.today() - timedelta(days=365)).date()\n",
|
||||
"start_widget = widgets.DatePicker(value=base_date, layout=w_auto, description=\"Start\")\n",
|
||||
"end_widget = widgets.DatePicker(\n",
|
||||
" value=datetime.today().date(), layout=w_auto, description=\"End\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"target_widget = widgets.Dropdown(options=[\"\"], value=\"\", description=\"Target\")\n",
|
||||
"interval_widget = widgets.Dropdown(\n",
|
||||
" options=interval_opts, value=\"1d\", layout=w_auto, description=\"Interval\"\n",
|
||||
")\n",
|
||||
"tickers_widget = widgets.Textarea(\n",
|
||||
" value=\"TSLA,\", layout=widgets.Layout(width=\"auto\", height=\"100%\")\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Output box\n",
|
||||
"naive_widget = widgets.ToggleButton(value=False, description=\"Show Naive\")\n",
|
||||
"forecast_only_widget = widgets.ToggleButton(value=False, description=\"Forecast Only\")\n",
|
||||
"run_widget = widgets.ToggleButton(value=False, description=\"Run Model\")\n",
|
||||
"\n",
|
||||
"# feat_box\n",
|
||||
"feat_value = list(feat_engs.keys())[0] if feat_engs else None\n",
|
||||
"column_widget = widgets.Dropdown(options=[\"\"], value=\"\", description=\"Target\")\n",
|
||||
"feat_widget = widgets.Dropdown(\n",
|
||||
" options=list(feat_engs.keys()), value=feat_value, description=\"Feature\"\n",
|
||||
")\n",
|
||||
"add_widget = widgets.ToggleButton(\n",
|
||||
" value=False, description=\"Add Feature\", layout=widgets.Layout(align=\"flex_end\")\n",
|
||||
") # get this to work\n",
|
||||
"\n",
|
||||
"selection_box = widgets.VBox([tickers_widget, target_widget])\n",
|
||||
"date_box = widgets.VBox([start_widget, end_widget, interval_widget])\n",
|
||||
"output_box = widgets.VBox([naive_widget, forecast_only_widget, run_widget])\n",
|
||||
"feat_box = widgets.VBox([column_widget, feat_widget, add_widget])\n",
|
||||
"controls = widgets.HBox(\n",
|
||||
" [selection_box, model_widget, past_covs_widget, date_box, output_box, feat_box],\n",
|
||||
")\n",
|
||||
"if has_forecast:\n",
|
||||
" chart = Chart()\n",
|
||||
" widgets.interactive_output(\n",
|
||||
" chart.handle_changes,\n",
|
||||
" {\n",
|
||||
" \"past_covariates\": past_covs_widget,\n",
|
||||
" \"start\": start_widget,\n",
|
||||
" \"end\": end_widget,\n",
|
||||
" \"interval\": interval_widget,\n",
|
||||
" \"tickers\": tickers_widget,\n",
|
||||
" \"target_column\": target_widget,\n",
|
||||
" \"model\": model_widget,\n",
|
||||
" \"naive\": naive_widget,\n",
|
||||
" \"forecast_only\": forecast_only_widget,\n",
|
||||
" },\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" widgets.interactive_output(\n",
|
||||
" chart.handle_eng, {\"target\": column_widget, \"feature\": feat_widget}\n",
|
||||
" )\n",
|
||||
" widgets.interactive_output(chart.handle_click2, {\"to_run\": add_widget})\n",
|
||||
"\n",
|
||||
" stocks_view = widgets.interactive_output(chart.handle_click, {\"to_run\": run_widget})\n",
|
||||
"\n",
|
||||
" title_html = \"<h1>Timeseries Forecasting Dashboard</h1>\"\n",
|
||||
" warning_html = '<p style=\"color:red\"=>Use a comma after EVERY stock typed.</p>'\n",
|
||||
"\n",
|
||||
" app_contents = [\n",
|
||||
" widgets.HTML(title_html),\n",
|
||||
" controls,\n",
|
||||
" widgets.HTML(warning_html),\n",
|
||||
" stocks_view,\n",
|
||||
" ]\n",
|
||||
" app = widgets.VBox(app_contents)\n",
|
||||
"else:\n",
|
||||
" title_html = \"<h1>Timeseries Forecasting Dashboard</h1>\"\n",
|
||||
" warning_html = (\n",
|
||||
" '<p style=\"color:red\"=>The forecasting dependencies are not installed.</p>'\n",
|
||||
" )\n",
|
||||
" app = widgets.VBox([widgets.HTML(title_html), widgets.HTML(warning_html)])\n",
|
||||
"display(app)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9dbf43a2-70e1-44e9-a524-be3e97008b58",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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.9.6"
|
||||
},
|
||||
"metadata": {
|
||||
"interpreter": {
|
||||
"hash": "e896a00ead8b521528d79ac9ef24990696f2b751eb283ab8e0d078c9c4971ffc"
|
||||
}
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "bd3088e2ce83c7406a082a5b650cfc74fd1480320510d276c9fa5780b96e5fae"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e9ad60bc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime, timedelta\n",
|
||||
"from typing import Callable, Any\n",
|
||||
"from inspect import signature\n",
|
||||
"import warnings, logging\n",
|
||||
"\n",
|
||||
"import ipywidgets as widgets\n",
|
||||
"import yfinance as yf\n",
|
||||
"import pandas as pd\n",
|
||||
"from IPython.display import display\n",
|
||||
"\n",
|
||||
"theme.apply_style()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "404cb982",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Suppressing sdk logs\n",
|
||||
"import openbb_terminal.config_terminal as cfg\n",
|
||||
"cfg.change_logging_suppress(new_value=True)\n",
|
||||
"\n",
|
||||
"# Import the OpenBB SDK\n",
|
||||
"from openbb_terminal.sdk import openbb, widgets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "beb36881",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"try:\n",
|
||||
" has_forecast = True\n",
|
||||
" model_opts = {\n",
|
||||
" \"expo\": openbb.forecast.expo_chart,\n",
|
||||
" \"theta\": openbb.forecast.theta_chart,\n",
|
||||
" \"linregr\": openbb.forecast.linregr_chart,\n",
|
||||
" \"regr\": openbb.forecast.regr_chart,\n",
|
||||
" \"rnn\": openbb.forecast.rnn_chart,\n",
|
||||
" \"brnn\": openbb.forecast.brnn_chart,\n",
|
||||
" \"nbeats\": openbb.forecast.nbeats_chart,\n",
|
||||
" \"tcn\": openbb.forecast.tcn_chart,\n",
|
||||
" \"trans\": openbb.forecast.trans_chart,\n",
|
||||
" \"tft\": openbb.forecast.tft_chart,\n",
|
||||
" \"nhits\": openbb.forecast.nhits_chart,\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" feat_engs = {\n",
|
||||
" \"ema\": openbb.forecast.ema,\n",
|
||||
" \"sto\": openbb.forecast.sto,\n",
|
||||
" \"rsi\": openbb.forecast.rsi,\n",
|
||||
" \"roc\": openbb.forecast.roc,\n",
|
||||
" \"mom\": openbb.forecast.mom,\n",
|
||||
" \"atr\": openbb.forecast.atr,\n",
|
||||
" \"delta\": openbb.forecast.delta,\n",
|
||||
" \"signal\": openbb.forecast.signal,\n",
|
||||
" }\n",
|
||||
"except AttributeError as e:\n",
|
||||
" print(e)\n",
|
||||
" has_forecast = False\n",
|
||||
" model_opts = {}\n",
|
||||
" feat_engs = {}\n",
|
||||
"\n",
|
||||
"interval_opts = [\n",
|
||||
" \"1m\",\n",
|
||||
" \"2m\",\n",
|
||||
" \"5m\",\n",
|
||||
" \"15m\",\n",
|
||||
" \"30m\",\n",
|
||||
" \"60m\",\n",
|
||||
" \"90m\",\n",
|
||||
" \"1h\",\n",
|
||||
" \"1d\",\n",
|
||||
" \"5d\",\n",
|
||||
" \"1wk\",\n",
|
||||
" \"1mo\",\n",
|
||||
" \"3mo\",\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def format_df(df: pd.DataFrame) -> pd.DataFrame:\n",
|
||||
" if len(df.columns) != 6:\n",
|
||||
" df.columns = [\"_\".join(col).strip() for col in df.columns.values]\n",
|
||||
" df.reset_index(inplace=True)\n",
|
||||
" df.columns = [x.lower() for x in df.columns]\n",
|
||||
" return df\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def has_parameter(func: Callable[..., Any], parameter: str) -> bool:\n",
|
||||
" params = signature(func).parameters\n",
|
||||
" parameters = params.keys()\n",
|
||||
" return parameter in parameters"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f8c2f65c",
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"parameters"
|
||||
]
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Chart:\n",
|
||||
" def __init__(self):\n",
|
||||
" self.last_tickers = \"\"\n",
|
||||
" self.last_interval = \"1d\"\n",
|
||||
" self.df = pd.DataFrame()\n",
|
||||
" self.result = pd.DataFrame()\n",
|
||||
" self.infos = {}\n",
|
||||
"\n",
|
||||
" def handle_changes(\n",
|
||||
" self,\n",
|
||||
" past_covariates,\n",
|
||||
" start,\n",
|
||||
" end,\n",
|
||||
" interval,\n",
|
||||
" tickers,\n",
|
||||
" target_column,\n",
|
||||
" model,\n",
|
||||
" naive,\n",
|
||||
" forecast_only,\n",
|
||||
" ):\n",
|
||||
" ticker_list = tickers.split(\",\")\n",
|
||||
" if ticker_list:\n",
|
||||
" if tickers != self.last_tickers or interval != self.last_interval:\n",
|
||||
" if interval in [\"1d\", \"5d\", \"1wk\", \"1mo\", \"3mo\"]:\n",
|
||||
" self.df = yf.download(\n",
|
||||
" tickers, period=\"max\", interval=interval, progress=False\n",
|
||||
" )\n",
|
||||
" else:\n",
|
||||
" end_date = end + timedelta(days=1)\n",
|
||||
" self.df = yf.download(\n",
|
||||
" tickers,\n",
|
||||
" start=start,\n",
|
||||
" end=end_date,\n",
|
||||
" interval=interval,\n",
|
||||
" progress=False,\n",
|
||||
" )\n",
|
||||
" self.df = format_df(self.df)\n",
|
||||
" self.last_tickers = tickers\n",
|
||||
" self.last_interval = interval\n",
|
||||
" forecast_model = model_opts[model]\n",
|
||||
" self.forecast_model = forecast_model\n",
|
||||
" contains_covariates = has_parameter(forecast_model, \"past_covariates\")\n",
|
||||
"\n",
|
||||
" # Update Inputs\n",
|
||||
" if list(target_widget.options) != [\n",
|
||||
" x for x in self.df.columns if x != \"date\"\n",
|
||||
" ]:\n",
|
||||
" target_widget.options = [x for x in self.df.columns if x != \"date\"]\n",
|
||||
" return\n",
|
||||
" if list(past_covs_widget.options) != [\n",
|
||||
" x for x in self.df.columns if x != \"date\"\n",
|
||||
" ]:\n",
|
||||
" past_covs_widget.options = [x for x in self.df.columns if x != \"date\"]\n",
|
||||
" past_covs_widget.disabled = not contains_covariates\n",
|
||||
" return\n",
|
||||
" if past_covs_widget.disabled == contains_covariates:\n",
|
||||
" past_covs_widget.disabled = not contains_covariates\n",
|
||||
" column_widget.options = [x for x in self.df.columns if x != \"date\"]\n",
|
||||
"\n",
|
||||
" start_n = datetime(start.year, start.month, start.day)\n",
|
||||
" end_n = datetime(end.year, end.month, end.day)\n",
|
||||
" calcs = self.df\n",
|
||||
" if interval in [\"1d\", \"5d\", \"1wk\", \"1mo\", \"3mo\"]:\n",
|
||||
" result = calcs.loc[\n",
|
||||
" (calcs[\"date\"] >= start_n) & (calcs[\"date\"] <= end_n)\n",
|
||||
" ]\n",
|
||||
" else:\n",
|
||||
" result = calcs\n",
|
||||
" if not target_column:\n",
|
||||
" target_column = self.df.columns[0]\n",
|
||||
" kwargs = {}\n",
|
||||
" if contains_covariates and past_covariates != ():\n",
|
||||
" kwargs[\"past_covariates\"] = \",\".join(past_covariates)\n",
|
||||
" if has_parameter(forecast_model, \"naive\"):\n",
|
||||
" kwargs[\"naive\"] = naive\n",
|
||||
" if has_parameter(forecast_model, \"forecast_only\"):\n",
|
||||
" kwargs[\"forecast_only\"] = forecast_only\n",
|
||||
" # This sets up everything to run the function on button click\n",
|
||||
"\n",
|
||||
" self.result = result\n",
|
||||
" self.target_column = target_column\n",
|
||||
" self.n_predict = 5\n",
|
||||
" self.kwargs = kwargs\n",
|
||||
"\n",
|
||||
" def handle_click(self, to_run):\n",
|
||||
" if to_run:\n",
|
||||
" run_widget.value = False\n",
|
||||
" else:\n",
|
||||
" df = self.result.dropna()\n",
|
||||
" if not df.empty:\n",
|
||||
" self.forecast_model(\n",
|
||||
" self.result,\n",
|
||||
" target_column=self.target_column,\n",
|
||||
" n_predict=5,\n",
|
||||
" **self.kwargs\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" def handle_eng(self, target, feature):\n",
|
||||
" self.feature_target = target\n",
|
||||
" self.feature_model = feat_engs[feature]\n",
|
||||
"\n",
|
||||
" def handle_click2(self, to_run):\n",
|
||||
" if to_run:\n",
|
||||
" add_widget.value = False\n",
|
||||
" else:\n",
|
||||
" kwargs = {}\n",
|
||||
" if has_parameter(self.feature_model, \"target_column\"):\n",
|
||||
" kwargs[\"target_column\"] = self.feature_target\n",
|
||||
" self.df = self.feature_model(self.df, **kwargs)\n",
|
||||
" past_covs_widget.options = self.df.columns"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e0d4de31-1b4f-4c1f-8467-ca314a578d56",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"w_auto = widgets.Layout(width=\"auto\")\n",
|
||||
"model_value = list(model_opts)[0] if model_opts else None\n",
|
||||
"model_widget = widgets.Select(\n",
|
||||
" options=list(model_opts),\n",
|
||||
" value=model_value,\n",
|
||||
" layout=widgets.Layout(\n",
|
||||
" width=\"8%\",\n",
|
||||
" ),\n",
|
||||
")\n",
|
||||
"past_covs_widget = widgets.SelectMultiple(\n",
|
||||
" options=[\"\"],\n",
|
||||
" value=[\"\"],\n",
|
||||
" layout=widgets.Layout(\n",
|
||||
" width=\"8%\",\n",
|
||||
" ),\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"base_date = (datetime.today() - timedelta(days=365)).date()\n",
|
||||
"start_widget = widgets.DatePicker(value=base_date, layout=w_auto, description=\"Start\")\n",
|
||||
"end_widget = widgets.DatePicker(\n",
|
||||
" value=datetime.today().date(), layout=w_auto, description=\"End\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"target_widget = widgets.Dropdown(options=[\"\"], value=\"\", description=\"Target\")\n",
|
||||
"interval_widget = widgets.Dropdown(\n",
|
||||
" options=interval_opts, value=\"1d\", layout=w_auto, description=\"Interval\"\n",
|
||||
")\n",
|
||||
"tickers_widget = widgets.Textarea(\n",
|
||||
" value=\"TSLA,\", layout=widgets.Layout(width=\"auto\", height=\"100%\")\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Output box\n",
|
||||
"naive_widget = widgets.ToggleButton(value=False, description=\"Show Naive\")\n",
|
||||
"forecast_only_widget = widgets.ToggleButton(value=False, description=\"Forecast Only\")\n",
|
||||
"run_widget = widgets.ToggleButton(value=False, description=\"Run Model\")\n",
|
||||
"\n",
|
||||
"# feat_box\n",
|
||||
"feat_value = list(feat_engs.keys())[0] if feat_engs else None\n",
|
||||
"column_widget = widgets.Dropdown(options=[\"\"], value=\"\", description=\"Target\")\n",
|
||||
"feat_widget = widgets.Dropdown(\n",
|
||||
" options=list(feat_engs.keys()), value=feat_value, description=\"Feature\"\n",
|
||||
")\n",
|
||||
"add_widget = widgets.ToggleButton(\n",
|
||||
" value=False, description=\"Add Feature\", layout=widgets.Layout(align=\"flex_end\")\n",
|
||||
") # get this to work\n",
|
||||
"\n",
|
||||
"selection_box = widgets.VBox([tickers_widget, target_widget])\n",
|
||||
"date_box = widgets.VBox([start_widget, end_widget, interval_widget])\n",
|
||||
"output_box = widgets.VBox([naive_widget, forecast_only_widget, run_widget])\n",
|
||||
"feat_box = widgets.VBox([column_widget, feat_widget, add_widget])\n",
|
||||
"controls = widgets.HBox(\n",
|
||||
" [selection_box, model_widget, past_covs_widget, date_box, output_box, feat_box],\n",
|
||||
")\n",
|
||||
"if has_forecast:\n",
|
||||
" chart = Chart()\n",
|
||||
" widgets.interactive_output(\n",
|
||||
" chart.handle_changes,\n",
|
||||
" {\n",
|
||||
" \"past_covariates\": past_covs_widget,\n",
|
||||
" \"start\": start_widget,\n",
|
||||
" \"end\": end_widget,\n",
|
||||
" \"interval\": interval_widget,\n",
|
||||
" \"tickers\": tickers_widget,\n",
|
||||
" \"target_column\": target_widget,\n",
|
||||
" \"model\": model_widget,\n",
|
||||
" \"naive\": naive_widget,\n",
|
||||
" \"forecast_only\": forecast_only_widget,\n",
|
||||
" },\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" widgets.interactive_output(\n",
|
||||
" chart.handle_eng, {\"target\": column_widget, \"feature\": feat_widget}\n",
|
||||
" )\n",
|
||||
" widgets.interactive_output(chart.handle_click2, {\"to_run\": add_widget})\n",
|
||||
"\n",
|
||||
" stocks_view = widgets.interactive_output(chart.handle_click, {\"to_run\": run_widget})\n",
|
||||
"\n",
|
||||
" title_html = \"<h1>Timeseries Forecasting Dashboard</h1>\"\n",
|
||||
" warning_html = '<p style=\"color:red\"=>Use a comma after EVERY stock typed.</p>'\n",
|
||||
"\n",
|
||||
" app_contents = [\n",
|
||||
" widgets.HTML(title_html),\n",
|
||||
" controls,\n",
|
||||
" widgets.HTML(warning_html),\n",
|
||||
" stocks_view,\n",
|
||||
" ]\n",
|
||||
" app = widgets.VBox(app_contents)\n",
|
||||
"else:\n",
|
||||
" title_html = \"<h1>Timeseries Forecasting Dashboard</h1>\"\n",
|
||||
" warning_html = (\n",
|
||||
" '<p style=\"color:red\"=>The forecasting dependencies are not installed.</p>'\n",
|
||||
" )\n",
|
||||
" app = widgets.VBox([widgets.HTML(title_html), widgets.HTML(warning_html)])\n",
|
||||
"display(app)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9dbf43a2-70e1-44e9-a524-be3e97008b58",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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.9.6"
|
||||
},
|
||||
"metadata": {
|
||||
"interpreter": {
|
||||
"hash": "e896a00ead8b521528d79ac9ef24990696f2b751eb283ab8e0d078c9c4971ffc"
|
||||
}
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "bd3088e2ce83c7406a082a5b650cfc74fd1480320510d276c9fa5780b96e5fae"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import os
|
||||
# pylint: disable=R1732, R0912
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import openbb_terminal.config_terminal as cfg
|
||||
from openbb_terminal.core.session.current_user import get_current_user
|
||||
from openbb_terminal.custom_prompt_toolkit import NestedCompleter
|
||||
from openbb_terminal.decorators import log_start_end
|
||||
@@ -191,7 +190,6 @@ class ReportController(BaseController):
|
||||
ns_parser = self.parse_simple_args(parser, other_args)
|
||||
|
||||
if ns_parser:
|
||||
cfg.change_logging_suppress(new_value=True)
|
||||
if report_name == "equity" and "." in ns_parser.symbol:
|
||||
console.print(
|
||||
"[red]Cannot currently handle tickers with a '.' in them[/red]\n"
|
||||
@@ -203,7 +201,6 @@ class ReportController(BaseController):
|
||||
input_path=str(reports_model.REPORTS_FOLDER / report_name),
|
||||
args_dict=parameters,
|
||||
)
|
||||
cfg.change_logging_suppress(new_value=False)
|
||||
|
||||
else:
|
||||
console.print("[red]Notebook not found![/red]\n")
|
||||
|
||||
@@ -5,12 +5,12 @@ import logging
|
||||
|
||||
# pylint: disable=R1732, R0912
|
||||
import os
|
||||
from ast import literal_eval
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from threading import Thread
|
||||
from typing import Any, Dict, List, Union
|
||||
|
||||
import nbformat
|
||||
import pandas as pd
|
||||
import papermill as pm
|
||||
from ipykernel.kernelapp import IPKernelApp
|
||||
@@ -85,6 +85,7 @@ REPORT_CHOICES = {
|
||||
"--symbol": {c: None for c in STOCKS_TICKERS + ETF_TICKERS},
|
||||
},
|
||||
}
|
||||
TARGET_TAG = "parameters"
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@@ -157,43 +158,34 @@ def extract_parameters(input_path: str) -> Dict[str, str]:
|
||||
|
||||
input_path = add_ipynb_extension(input_path)
|
||||
|
||||
with open(input_path, encoding="utf-8") as file:
|
||||
notebook_content = file.read()
|
||||
with open(input_path) as f:
|
||||
nb = nbformat.read(f, as_version=nbformat.NO_CONVERT)
|
||||
|
||||
# Look for the metadata cell to understand if there are parameters required by the report
|
||||
metadata_cell = """"metadata": {\n "tags": [\n "parameters"\n ]\n },\n "outputs":"""
|
||||
target_tag = TARGET_TAG
|
||||
|
||||
# Locate position of the data of interest and get parameters
|
||||
if notebook_content.find(metadata_cell) >= 0:
|
||||
position = notebook_content.find(metadata_cell)
|
||||
else:
|
||||
return {}
|
||||
cell_lines = []
|
||||
for cell in nb.cells:
|
||||
# Filter cells by tag
|
||||
if target_tag in cell.metadata.get("tags", []):
|
||||
# Split cell source into separate lines
|
||||
lines = cell.source.split("\n")
|
||||
# Remove empty and commented lines
|
||||
lines = [
|
||||
line for line in lines if line.strip() and not line.startswith("#")
|
||||
]
|
||||
cell_lines.extend(lines)
|
||||
|
||||
metadata = notebook_content[position:] # noqa: E203
|
||||
cell_start = 'source": '
|
||||
cell_end = "]"
|
||||
start_position = metadata.find(cell_start)
|
||||
params = metadata[
|
||||
start_position : metadata.find(cell_end, start_position) + 1 # noqa: E203
|
||||
]
|
||||
parameters_dict = {}
|
||||
for line in cell_lines:
|
||||
# Extract key and value from each line
|
||||
key, value = line.split("=")
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
# Add key-value pair to dictionary
|
||||
parameters_dict[key] = value
|
||||
|
||||
# Make sure that the parameters provided are relevant
|
||||
if "parameters" in notebook_content:
|
||||
parameters_names = [
|
||||
param.split("=")[0][:-1]
|
||||
for param in literal_eval(params.strip('source": '))
|
||||
if param[0] not in ["#", "\n"]
|
||||
]
|
||||
parameters_values = [
|
||||
param.split("=")[1][2:-2]
|
||||
for param in literal_eval(params.strip('source": '))
|
||||
if param[0] not in ["#", "\n"]
|
||||
]
|
||||
|
||||
if "report_name" in parameters_names:
|
||||
parameters_names.remove("report_name")
|
||||
|
||||
parameters_dict = dict(zip(parameters_names, parameters_values))
|
||||
if "report_name" in parameters_dict:
|
||||
parameters_dict.pop("report_name")
|
||||
|
||||
return parameters_dict
|
||||
|
||||
|
||||
2306
openbb_terminal/reports/templates/crypto.ipynb
vendored
2306
openbb_terminal/reports/templates/crypto.ipynb
vendored
File diff suppressed because it is too large
Load Diff
1487
openbb_terminal/reports/templates/economy.ipynb
vendored
1487
openbb_terminal/reports/templates/economy.ipynb
vendored
File diff suppressed because it is too large
Load Diff
2771
openbb_terminal/reports/templates/equity.ipynb
vendored
2771
openbb_terminal/reports/templates/equity.ipynb
vendored
File diff suppressed because it is too large
Load Diff
712
openbb_terminal/reports/templates/etf.ipynb
vendored
712
openbb_terminal/reports/templates/etf.ipynb
vendored
@@ -1,350 +1,364 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"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.reports import widget_helpers as widgets\n",
|
||||
"from openbb_terminal.sdk import openbb\n",
|
||||
"from openbb_terminal.core.config.paths import REPOSITORY_DIRECTORY\n",
|
||||
"from openbb_terminal import OpenBBFigure, theme\n",
|
||||
"from openbb_terminal.helper_classes import TerminalStyle\n",
|
||||
"\n",
|
||||
"warnings.filterwarnings(\"ignore\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "36091f30",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"stylesheet = widgets.html_report_stylesheet()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 = \"VTI\"\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"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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\")\n",
|
||||
"weights_df.columns = [\"Percentage\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "324e2d4b-b2f6-4da3-bac4-ef785ad4e436",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"weights_chart = \"\"\n",
|
||||
"\n",
|
||||
"if len(weights_df[weights_df[\"Percentage\"] > 10].index) > 1:\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": "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 = f\"\"\"\n",
|
||||
"<style>\n",
|
||||
"@font-face {{\n",
|
||||
" font-family: \"Fira Code\";\n",
|
||||
" src: url(\"{(OpenBBFigure.plotlyjs_path.parent.parent / \"web\"/\"css\").as_uri()}/fonts/FiraCode-Regular.ttf\") format(\"truetype\");\n",
|
||||
" font-weight: 400 700;\n",
|
||||
" font-stretch: 50%;\n",
|
||||
"}}\n",
|
||||
"</style>\n",
|
||||
"<script src=\"/{OpenBBFigure.plotlyjs_path.as_uri()}\"></script>\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"img = (\n",
|
||||
" str(REPOSITORY_DIRECTORY)\n",
|
||||
" + \"/openbb_terminal/reports/templates/OpenBB_reports_logo.png\"\n",
|
||||
")\n",
|
||||
"floppy_disk_img = (\n",
|
||||
" str(REPOSITORY_DIRECTORY) + \"/openbb_terminal/reports/templates/floppy-disc.png\"\n",
|
||||
")\n",
|
||||
"body += widgets.header(\n",
|
||||
" img,\n",
|
||||
" floppy_disk_img,\n",
|
||||
" author,\n",
|
||||
" report_date,\n",
|
||||
" report_time,\n",
|
||||
" report_timezone,\n",
|
||||
" f\"<b>ETF RESEARCH REPORT:</b> {ticker.upper()}\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"body += widgets.tablinks([\"SUMMARY\"])\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",
|
||||
"body += widgets.tab_clickable_and_save_evt()\n",
|
||||
"\n",
|
||||
"report = widgets.html_report(title=report_name, stylesheet=stylesheet, body=body)\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.9"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "381a209f752e9104bff95ec5e80679ea2e476866b80e4326f1ee6b7658af6049"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
"cells": [
|
||||
{
|
||||
"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.core.config.paths import REPOSITORY_DIRECTORY\n",
|
||||
"from openbb_terminal import OpenBBFigure, theme\n",
|
||||
"from openbb_terminal.helper_classes import TerminalStyle\n",
|
||||
"\n",
|
||||
"warnings.filterwarnings(\"ignore\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "473e83c7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Suppressing sdk logs\n",
|
||||
"cfg.change_logging_suppress(new_value=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",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "36091f30",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"stylesheet = widgets.html_report_stylesheet()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 = \"VTI\"\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"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 \"Percentage\" in weights_df.columns and len(weights_df[weights_df[\"Percentage\"] > 10].index) > 1:\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": "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 = f\"\"\"\n",
|
||||
"<style>\n",
|
||||
"@font-face {{\n",
|
||||
" font-family: \"Fira Code\";\n",
|
||||
" src: url(\"{(OpenBBFigure.plotlyjs_path.parent.parent / \"web\"/\"css\").as_uri()}/fonts/FiraCode-Regular.ttf\") format(\"truetype\");\n",
|
||||
" font-weight: 400 700;\n",
|
||||
" font-stretch: 50%;\n",
|
||||
"}}\n",
|
||||
"</style>\n",
|
||||
"<script src=\"/{OpenBBFigure.plotlyjs_path.as_uri()}\"></script>\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"img = (\n",
|
||||
" str(REPOSITORY_DIRECTORY)\n",
|
||||
" + \"/openbb_terminal/reports/templates/OpenBB_reports_logo.png\"\n",
|
||||
")\n",
|
||||
"floppy_disk_img = (\n",
|
||||
" str(REPOSITORY_DIRECTORY) + \"/openbb_terminal/reports/templates/floppy-disc.png\"\n",
|
||||
")\n",
|
||||
"body += widgets.header(\n",
|
||||
" img,\n",
|
||||
" floppy_disk_img,\n",
|
||||
" author,\n",
|
||||
" report_date,\n",
|
||||
" report_time,\n",
|
||||
" report_timezone,\n",
|
||||
" f\"<b>ETF RESEARCH REPORT:</b> {ticker.upper()}\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"body += widgets.tablinks([\"SUMMARY\"])\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",
|
||||
"body += widgets.tab_clickable_and_save_evt()\n",
|
||||
"\n",
|
||||
"report = widgets.html_report(title=report_name, stylesheet=stylesheet, body=body)\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.9.13"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "381a209f752e9104bff95ec5e80679ea2e476866b80e4326f1ee6b7658af6049"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
630
openbb_terminal/reports/templates/forecast.ipynb
vendored
630
openbb_terminal/reports/templates/forecast.ipynb
vendored
@@ -1,311 +1,321 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "70ba2c8a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Notebook setup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "driven-billion",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import io\n",
|
||||
"import warnings\n",
|
||||
"import datetime\n",
|
||||
"import numpy as np\n",
|
||||
"import base64\n",
|
||||
"\n",
|
||||
"from IPython.display import HTML\n",
|
||||
"\n",
|
||||
"import openbb_terminal.config_terminal as cfg\n",
|
||||
"from openbb_terminal.reports import widget_helpers as widgets\n",
|
||||
"from openbb_terminal.sdk import openbb\n",
|
||||
"from openbb_terminal.helper_classes import TerminalStyle\n",
|
||||
"from openbb_terminal.core.config.paths import REPOSITORY_DIRECTORY\n",
|
||||
"\n",
|
||||
"from openbb_terminal import OpenBBFigure\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"warnings.filterwarnings(\"ignore\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f6d22d4f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"stylesheet = widgets.html_report_stylesheet()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9c3ae3e3-2b91-43a6-aa44-7b10986fd369",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def get_html(func, title, *args, **kwargs):\n",
|
||||
" kwargs[\"external_axes\"] = True\n",
|
||||
" local_fig = func(*args, **kwargs)\n",
|
||||
" # kwargs[\"chart\"] = True\n",
|
||||
" if title:\n",
|
||||
" local_fig.set_title(title)\n",
|
||||
" local_fig.set_xaxis_title(\"Lag\")\n",
|
||||
" local_fig.set_yaxis_title(\"Autocorrelation\")\n",
|
||||
"\n",
|
||||
" return local_fig.to_html()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 = \"VTI\"\n",
|
||||
"report_name = \"Forecast 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=400)\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"author = \"OpenBB\"\n",
|
||||
"report_title = f\"FORECAST 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": "markdown",
|
||||
"id": "f8a0d747",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cb31e9ee-e7ae-4e1b-89b4-bb6f571cfdfa",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"local_fig = openbb.stocks.candle(ticker, ticker_data, external_axes=True)\n",
|
||||
"plot_chart = local_fig.to_html()\n",
|
||||
"\n",
|
||||
"# Prepare date for forecast\n",
|
||||
"ticker_data = ticker_data.reset_index()\n",
|
||||
"ticker_data.columns = [x.lower() for x in ticker_data.columns]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d8bb53c1-147e-4342-af61-0d0a9cc56e59",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"corr_chart = get_html(openbb.forecast.corr_chart, None, ticker_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "74b914a1-ed32-4a17-a943-7879bc8f00df",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"season_chart = get_html(openbb.forecast.season_chart, \"Seasonality Data\", ticker_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "53568c9b-aa06-4ba0-ad86-ede6732e3187",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"expo_chart = get_html(openbb.forecast.expo_chart, None, ticker_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0a919f67-ac9f-4b75-a3b3-102e0fbe5862",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"rnn_chart = get_html(openbb.forecast.rnn_chart, None, ticker_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 = f\"\"\"\n",
|
||||
"<style>\n",
|
||||
"@font-face {{\n",
|
||||
" font-family: \"Fira Code\";\n",
|
||||
" src: url(\"{(OpenBBFigure.plotlyjs_path.parent.parent / \"web\"/\"css\").as_uri()}/fonts/FiraCode-Regular.ttf\") format(\"truetype\");\n",
|
||||
" font-weight: 400 700;\n",
|
||||
" font-stretch: 50%;\n",
|
||||
"}}\n",
|
||||
"</style>\n",
|
||||
"<script src=\"/{OpenBBFigure.plotlyjs_path.as_uri()}\"></script>\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"img = (\n",
|
||||
" str(REPOSITORY_DIRECTORY)\n",
|
||||
" + \"/openbb_terminal/reports/templates/OpenBB_reports_logo.png\"\n",
|
||||
")\n",
|
||||
"floppy_disk_img = (\n",
|
||||
" str(REPOSITORY_DIRECTORY) + \"/openbb_terminal/reports/templates/floppy-disc.png\"\n",
|
||||
")\n",
|
||||
"body += widgets.header(\n",
|
||||
" img,\n",
|
||||
" floppy_disk_img,\n",
|
||||
" author,\n",
|
||||
" report_date,\n",
|
||||
" report_time,\n",
|
||||
" report_timezone,\n",
|
||||
" f\"<b>FORECAST REPORT ON:</b> {ticker.upper()}\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"body += widgets.tablinks([\"SUMMARY\"])\n",
|
||||
"\n",
|
||||
"htmlcode = widgets.h(3, \"Summary\")\n",
|
||||
"htmlcode += widgets.row([widgets.h(3, \"Understand the data\")])\n",
|
||||
"htmlcode += widgets.row([ticker_data.head(10).to_html()])\n",
|
||||
"htmlcode += widgets.row([plot_chart])\n",
|
||||
"htmlcode += widgets.row([widgets.h(3, \"Analyzing the data\")])\n",
|
||||
"htmlcode += widgets.row([corr_chart])\n",
|
||||
"htmlcode += widgets.row([season_chart])\n",
|
||||
"htmlcode += widgets.row([widgets.h(3, \"Creating predictions\")])\n",
|
||||
"htmlcode += widgets.row([expo_chart])\n",
|
||||
"htmlcode += widgets.row([rnn_chart])\n",
|
||||
"\n",
|
||||
"body += widgets.add_tab(\"SUMMARY\", htmlcode)\n",
|
||||
"body += widgets.tab_clickable_and_save_evt()\n",
|
||||
"report = widgets.html_report(title=report_name, stylesheet=stylesheet, body=body)\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.8"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "381a209f752e9104bff95ec5e80679ea2e476866b80e4326f1ee6b7658af6049"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "70ba2c8a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Notebook setup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "driven-billion",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import io\n",
|
||||
"import warnings\n",
|
||||
"import datetime\n",
|
||||
"import numpy as np\n",
|
||||
"import base64\n",
|
||||
"\n",
|
||||
"from IPython.display import HTML\n",
|
||||
"\n",
|
||||
"import openbb_terminal.config_terminal as cfg\n",
|
||||
"from openbb_terminal.helper_classes import TerminalStyle\n",
|
||||
"from openbb_terminal.core.config.paths import REPOSITORY_DIRECTORY\n",
|
||||
"from openbb_terminal import OpenBBFigure\n",
|
||||
"\n",
|
||||
"warnings.filterwarnings(\"ignore\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "632bdfbc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Suppressing sdk logs\n",
|
||||
"cfg.change_logging_suppress(new_value=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",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f6d22d4f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"stylesheet = widgets.html_report_stylesheet()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9c3ae3e3-2b91-43a6-aa44-7b10986fd369",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def get_html(func, title, *args, **kwargs):\n",
|
||||
" kwargs[\"external_axes\"] = True\n",
|
||||
" local_fig = func(*args, **kwargs)\n",
|
||||
" # kwargs[\"chart\"] = True\n",
|
||||
" if title:\n",
|
||||
" local_fig.set_title(title)\n",
|
||||
" local_fig.set_xaxis_title(\"Lag\")\n",
|
||||
" local_fig.set_yaxis_title(\"Autocorrelation\")\n",
|
||||
"\n",
|
||||
" return local_fig.to_html()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 = \"VTI\"\n",
|
||||
"report_name = \"Forecast 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=400)\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"author = \"OpenBB\"\n",
|
||||
"report_title = f\"FORECAST 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": "markdown",
|
||||
"id": "f8a0d747",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cb31e9ee-e7ae-4e1b-89b4-bb6f571cfdfa",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"local_fig = openbb.stocks.candle(ticker, ticker_data, external_axes=True)\n",
|
||||
"plot_chart = local_fig.to_html()\n",
|
||||
"\n",
|
||||
"# Prepare date for forecast\n",
|
||||
"ticker_data = ticker_data.reset_index()\n",
|
||||
"ticker_data.columns = [x.lower() for x in ticker_data.columns]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d8bb53c1-147e-4342-af61-0d0a9cc56e59",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"corr_chart = get_html(openbb.forecast.corr_chart, None, ticker_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "74b914a1-ed32-4a17-a943-7879bc8f00df",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"season_chart = get_html(openbb.forecast.season_chart, \"Seasonality Data\", ticker_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "53568c9b-aa06-4ba0-ad86-ede6732e3187",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"expo_chart = get_html(openbb.forecast.expo_chart, None, ticker_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0a919f67-ac9f-4b75-a3b3-102e0fbe5862",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"rnn_chart = get_html(openbb.forecast.rnn_chart, None, ticker_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 = f\"\"\"\n",
|
||||
"<style>\n",
|
||||
"@font-face {{\n",
|
||||
" font-family: \"Fira Code\";\n",
|
||||
" src: url(\"{(OpenBBFigure.plotlyjs_path.parent.parent / \"web\"/\"css\").as_uri()}/fonts/FiraCode-Regular.ttf\") format(\"truetype\");\n",
|
||||
" font-weight: 400 700;\n",
|
||||
" font-stretch: 50%;\n",
|
||||
"}}\n",
|
||||
"</style>\n",
|
||||
"<script src=\"/{OpenBBFigure.plotlyjs_path.as_uri()}\"></script>\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"img = (\n",
|
||||
" str(REPOSITORY_DIRECTORY)\n",
|
||||
" + \"/openbb_terminal/reports/templates/OpenBB_reports_logo.png\"\n",
|
||||
")\n",
|
||||
"floppy_disk_img = (\n",
|
||||
" str(REPOSITORY_DIRECTORY) + \"/openbb_terminal/reports/templates/floppy-disc.png\"\n",
|
||||
")\n",
|
||||
"body += widgets.header(\n",
|
||||
" img,\n",
|
||||
" floppy_disk_img,\n",
|
||||
" author,\n",
|
||||
" report_date,\n",
|
||||
" report_time,\n",
|
||||
" report_timezone,\n",
|
||||
" f\"<b>FORECAST REPORT ON:</b> {ticker.upper()}\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"body += widgets.tablinks([\"SUMMARY\"])\n",
|
||||
"\n",
|
||||
"htmlcode = widgets.h(3, \"Summary\")\n",
|
||||
"htmlcode += widgets.row([widgets.h(3, \"Understand the data\")])\n",
|
||||
"htmlcode += widgets.row([ticker_data.head(10).to_html()])\n",
|
||||
"htmlcode += widgets.row([plot_chart])\n",
|
||||
"htmlcode += widgets.row([widgets.h(3, \"Analyzing the data\")])\n",
|
||||
"htmlcode += widgets.row([corr_chart])\n",
|
||||
"htmlcode += widgets.row([season_chart])\n",
|
||||
"htmlcode += widgets.row([widgets.h(3, \"Creating predictions\")])\n",
|
||||
"htmlcode += widgets.row([expo_chart])\n",
|
||||
"htmlcode += widgets.row([rnn_chart])\n",
|
||||
"\n",
|
||||
"body += widgets.add_tab(\"SUMMARY\", htmlcode)\n",
|
||||
"body += widgets.tab_clickable_and_save_evt()\n",
|
||||
"report = widgets.html_report(title=report_name, stylesheet=stylesheet, body=body)\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.8"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "381a209f752e9104bff95ec5e80679ea2e476866b80e4326f1ee6b7658af6049"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
1314
openbb_terminal/reports/templates/forex.ipynb
vendored
1314
openbb_terminal/reports/templates/forex.ipynb
vendored
File diff suppressed because it is too large
Load Diff
1031
openbb_terminal/reports/templates/portfolio.ipynb
vendored
1031
openbb_terminal/reports/templates/portfolio.ipynb
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user