Skip to content

Commit

Permalink
Display the help menu whenever users move to a different menu (#1968)
Browse files Browse the repository at this point in the history
* switch auto print_help on exits

* display help when home called from home directory

* change in test to expect help cmd

* change in test to expect help cmd

* sets autoexithelp flag on conftest

* supress help string print on quit

* adapt tests to expect help

* adds help on 3 tests missing

* run black

* respect literal bool type

* second attemp to respect literal bool

Co-authored-by: minhhoang1023 <40023817+minhhoang1023@users.noreply.github.com>
  • Loading branch information
montezdesousa and minhhoang1023 authored Jun 22, 2022
1 parent cb66db1 commit 57b61d1
Show file tree
Hide file tree
Showing 49 changed files with 283 additions and 165 deletions.
2 changes: 1 addition & 1 deletion openbb_terminal/feature_flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
OPEN_REPORT_AS_HTML = strtobool(os.getenv("OPENBB_OPEN_REPORT_AS_HTML", "True"))

# Enable auto print_help when exiting menus
ENABLE_EXIT_AUTO_HELP = strtobool(os.getenv("OPENBB_ENABLE_EXIT_AUTO_HELP", "False"))
ENABLE_EXIT_AUTO_HELP = strtobool(os.getenv("OPENBB_ENABLE_EXIT_AUTO_HELP", "True"))

# Remember contexts during session
REMEMBER_CONTEXTS = strtobool(os.getenv("OPENBB_REMEMBER_CONTEXTS", "True"))
Expand Down
3 changes: 3 additions & 0 deletions openbb_terminal/parent_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ def call_home(self, _) -> None:
"""Process home command"""
self.save_class()
console.print("")
if self.PATH.count("/") == 1 and obbff.ENABLE_EXIT_AUTO_HELP:
self.print_help()
for _ in range(self.PATH.count("/") - 1):
self.queue.insert(0, "quit")

Expand Down Expand Up @@ -512,6 +514,7 @@ def menu(self, custom_path_menu_above: str = ""):
if (
an_input
and an_input != "home"
and an_input != "help"
and an_input.split(" ")[0] in self.controller_choices
):
console.print(f"{get_flair()} {self.PATH} $ {an_input}")
Expand Down
180 changes: 146 additions & 34 deletions openbb_terminal/reports/equity.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"try:\n",
" openbb.stocks.pred.models\n",
"except Exception as e:\n",
" predictions = False\n"
" predictions = False"
]
},
{
Expand Down Expand Up @@ -93,6 +93,7 @@
"source": [
"if \".\" in ticker:\n",
" import sys\n",
"\n",
" sys.exit(0)"
]
},
Expand All @@ -103,13 +104,15 @@
"metadata": {},
"outputs": [],
"source": [
"ticker_data = openbb.stocks.load(ticker, start=datetime.datetime.now() - datetime.timedelta(days=4*30))\n",
"ticker_data = openbb.stocks.load(\n",
" ticker, start=datetime.datetime.now() - datetime.timedelta(days=4 * 30)\n",
")\n",
"ticker_data = openbb.stocks.process_candle(ticker_data)\n",
"\n",
"author = \"Didier Rodrigues Lopes\"\n",
"report_title = f\"INVESTMENT 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_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"
]
Expand Down Expand Up @@ -351,7 +354,14 @@
"outputs": [],
"source": [
"df = openbb.stocks.dd.models.business_insider.get_price_target_from_analysts(ticker)\n",
"avg_ratings_last_30_days = round(np.mean(df[datetime.datetime.now() - datetime.timedelta(days=30):][\"Price Target\"].values), 2)\n",
"avg_ratings_last_30_days = round(\n",
" np.mean(\n",
" df[datetime.datetime.now() - datetime.timedelta(days=30) :][\n",
" \"Price Target\"\n",
" ].values\n",
" ),\n",
" 2,\n",
")\n",
"last_price = round(ticker_data[\"Close\"][-1], 2)"
]
},
Expand Down Expand Up @@ -411,7 +421,11 @@
"outputs": [],
"source": [
"from sklearn.linear_model import LinearRegression\n",
"model = LinearRegression().fit(np.array(range(len(ticker_data[\"Close\"][-30:].index))).reshape(-1,1), ticker_data[\"Close\"][-30:].values)\n",
"\n",
"model = LinearRegression().fit(\n",
" np.array(range(len(ticker_data[\"Close\"][-30:].index))).reshape(-1, 1),\n",
" ticker_data[\"Close\"][-30:].values,\n",
")\n",
"regression_slope = round(model.coef_[0], 2)"
]
},
Expand All @@ -423,13 +437,18 @@
"outputs": [],
"source": [
"import pandas as pd\n",
"df_insider = pd.DataFrame.from_dict(openbb.stocks.ins.models.finviz.get_last_insider_activity(ticker)).head(10)\n",
"df_insider[\"Val ($)\"] = df_insider[\"Value ($)\"].replace({',': ''}, regex=True)\n",
"\n",
"df_insider = pd.DataFrame.from_dict(\n",
" openbb.stocks.ins.models.finviz.get_last_insider_activity(ticker)\n",
").head(10)\n",
"df_insider[\"Val ($)\"] = df_insider[\"Value ($)\"].replace({\",\": \"\"}, regex=True)\n",
"df_insider[\"Trade\"] = df_insider.apply(\n",
" lambda row: (-1*float(row[\"Val ($)\"])) if row[\"Transaction\"] == \"Sale\" else (float(row[\"Val ($)\"]) if row[\"Transaction\"] == \"Buy\" else 0),\n",
" axis=1,\n",
" )\n",
"last_10_insider_trading = round(sum(df_insider[\"Trade\"])/1_000_000, 2)\n",
" lambda row: (-1 * float(row[\"Val ($)\"]))\n",
" if row[\"Transaction\"] == \"Sale\"\n",
" else (float(row[\"Val ($)\"]) if row[\"Transaction\"] == \"Buy\" else 0),\n",
" axis=1,\n",
")\n",
"last_10_insider_trading = round(sum(df_insider[\"Trade\"]) / 1_000_000, 2)\n",
"df_insider = df_insider.drop(columns=[\"Val ($)\", \"Trade\"])\n",
"df_insider"
]
Expand Down Expand Up @@ -467,7 +486,12 @@
"metadata": {},
"outputs": [],
"source": [
"watchlist_count, n_cases, n_bull, n_bear = openbb.stocks.ba.models.stocktwits.get_bullbear(ticker)\n",
"(\n",
" watchlist_count,\n",
" n_cases,\n",
" n_bull,\n",
" n_bear,\n",
") = openbb.stocks.ba.models.stocktwits.get_bullbear(ticker)\n",
"stocktwits_sentiment = f\"Watchlist count: {watchlist_count}</br>\"\n",
"if n_cases > 0:\n",
" stocktwits_sentiment += f\"\\nLast {n_cases} sentiment messages:</br>\"\n",
Expand Down Expand Up @@ -499,7 +523,9 @@
"metadata": {},
"outputs": [],
"source": [
"ticker_data_all = openbb.stocks.load(ticker, start=datetime.datetime.now() - datetime.timedelta(days=5*12*21))\n",
"ticker_data_all = openbb.stocks.load(\n",
" ticker, start=datetime.datetime.now() - datetime.timedelta(days=5 * 12 * 21)\n",
")\n",
"ticker_data_all[\"Returns\"] = ticker_data_all[\"Adj Close\"].pct_change()"
]
},
Expand Down Expand Up @@ -541,7 +567,12 @@
"outputs": [],
"source": [
"if predictions:\n",
" regression_val = round(openbb.stocks.pred.models.regression.get_regression_model(ticker_data_all[\"Close\"], 1, 80, 20, 1)[0][-1], 2)\n",
" regression_val = round(\n",
" openbb.stocks.pred.models.regression.get_regression_model(\n",
" ticker_data_all[\"Close\"], 1, 80, 20, 1\n",
" )[0][-1],\n",
" 2,\n",
" )\n",
" regression_val"
]
},
Expand All @@ -554,7 +585,9 @@
"source": [
"if predictions:\n",
" fig, ax = plt.subplots(figsize=(11, 3), dpi=150)\n",
" openbb.stocks.pred.regression(ticker, ticker_data_all[\"Close\"], 1, 80, 20, 1, external_axes=[ax])\n",
" openbb.stocks.pred.regression(\n",
" ticker, ticker_data_all[\"Close\"], 1, 80, 20, 1, external_axes=[ax]\n",
" )\n",
" fig.tight_layout()\n",
" f = io.BytesIO()\n",
" fig.savefig(f, format=\"svg\")\n",
Expand Down Expand Up @@ -586,7 +619,9 @@
"source": [
"if predictions:\n",
" fig, ax = plt.subplots(figsize=(11, 3), dpi=150)\n",
" openbb.stocks.pred.regression(ticker, ticker_data_all[\"Close\"], 1, 80, 20, 1, external_axes=[ax])\n",
" openbb.stocks.pred.regression(\n",
" ticker, ticker_data_all[\"Close\"], 1, 80, 20, 1, external_axes=[ax]\n",
" )\n",
" fig.tight_layout()\n",
" f = io.BytesIO()\n",
" fig.savefig(f, format=\"svg\")\n",
Expand All @@ -611,36 +646,106 @@
"body = \"\"\n",
"\n",
"img = f'<img src=\"data:image/png;base64,{openbb_image_encoded.decode()}\" alt=\"OpenBB\" style=\"width:144px;\">'\n",
"body += openbb.widgets.header(img, author, report_date, report_time, report_timezone, f'<b>INVESTMENT RESEARCH REPORT:</b> {ticker}')\n",
"body += openbb.widgets.header(\n",
" img,\n",
" author,\n",
" report_date,\n",
" report_time,\n",
" report_timezone,\n",
" f\"<b>INVESTMENT RESEARCH REPORT:</b> {ticker}\",\n",
")\n",
"\n",
"body += openbb.widgets.tablinks([\"SUMMARY\", \"Overview\", \"Analyst Opinions\", \"Fundamental Analysis\", \"Dark Pool and Shorts\", \"Technical Analysis\", \"Insider Trading\", \"Behavioural Analysis\", \"Quantitative Analysis\", \"Prediction Techniques\"])\n",
"body += openbb.widgets.tablinks(\n",
" [\n",
" \"SUMMARY\",\n",
" \"Overview\",\n",
" \"Analyst Opinions\",\n",
" \"Fundamental Analysis\",\n",
" \"Dark Pool and Shorts\",\n",
" \"Technical Analysis\",\n",
" \"Insider Trading\",\n",
" \"Behavioural Analysis\",\n",
" \"Quantitative Analysis\",\n",
" \"Prediction Techniques\",\n",
" ]\n",
")\n",
"\n",
"htmlcode = openbb.widgets.h(3, \"KPIs\")\n",
"htmlcode += openbb.widgets.kpi([last_price], [\"Last closing price is above the average price ratings of last 30 days\", \"Average price ratings of last 30 day is above last closing price\"], avg_ratings_last_30_days)\n",
"htmlcode += openbb.widgets.kpi(\n",
" [last_price],\n",
" [\n",
" \"Last closing price is above the average price ratings of last 30 days\",\n",
" \"Average price ratings of last 30 day is above last closing price\",\n",
" ],\n",
" avg_ratings_last_30_days,\n",
")\n",
"if predictions:\n",
" htmlcode += openbb.widgets.kpi([0], [\"Regression (dollars per market day) on last 30 market days is negative\", \"Regression (dollars per market day) on last 30 market days is positive\"], regression_slope)\n",
"htmlcode += openbb.widgets.kpi([30, 70], [\"RSI level is oversold\", \"RSI level is normal\", \"RSI level is overbought\"], rsi_value) \n",
"htmlcode += openbb.widgets.kpi([0], [\"The sum of last 10 insider trading (in millions) was negative\", \"The sum of last 10 insider trading (in millions) was positive\"], last_10_insider_trading)\n",
"htmlcode += openbb.widgets.kpi([-.1, .1], [\"Last FinBrain sentiment is bearish\", \" Last FinBrain sentiment is neutral\", \"Last FinBrain sentiment is bullish\"], finbrain_sentiment_val) \n",
" htmlcode += openbb.widgets.kpi(\n",
" [0],\n",
" [\n",
" \"Regression (dollars per market day) on last 30 market days is negative\",\n",
" \"Regression (dollars per market day) on last 30 market days is positive\",\n",
" ],\n",
" regression_slope,\n",
" )\n",
"htmlcode += openbb.widgets.kpi(\n",
" [30, 70],\n",
" [\"RSI level is oversold\", \"RSI level is normal\", \"RSI level is overbought\"],\n",
" rsi_value,\n",
")\n",
"htmlcode += openbb.widgets.kpi(\n",
" [0],\n",
" [\n",
" \"The sum of last 10 insider trading (in millions) was negative\",\n",
" \"The sum of last 10 insider trading (in millions) was positive\",\n",
" ],\n",
" last_10_insider_trading,\n",
")\n",
"htmlcode += openbb.widgets.kpi(\n",
" [-0.1, 0.1],\n",
" [\n",
" \"Last FinBrain sentiment is bearish\",\n",
" \" Last FinBrain sentiment is neutral\",\n",
" \"Last FinBrain sentiment is bullish\",\n",
" ],\n",
" finbrain_sentiment_val,\n",
")\n",
"if predictions:\n",
" htmlcode += openbb.widgets.kpi([0], [\"The regression for the next 20th market price is below closing price\", \"The regression for the next 20th market price is above closing price\"], round(regression_val - last_price, 2)) \n",
" htmlcode += openbb.widgets.kpi(\n",
" [0],\n",
" [\n",
" \"The regression for the next 20th market price is below closing price\",\n",
" \"The regression for the next 20th market price is above closing price\",\n",
" ],\n",
" round(regression_val - last_price, 2),\n",
" )\n",
"body += openbb.widgets.add_tab(\"SUMMARY\", htmlcode)\n",
"\n",
"htmlcode = openbb.widgets.row([price_chart])\n",
"htmlcode += openbb.widgets.row([openbb.widgets.h(3, \"Description\") + openbb.widgets.p(overview)])\n",
"htmlcode += openbb.widgets.row(\n",
" [openbb.widgets.h(3, \"Description\") + openbb.widgets.p(overview)]\n",
")\n",
"body += openbb.widgets.add_tab(\"Overview\", htmlcode)\n",
"\n",
"htmlcode = openbb.widgets.row([price_target_chart])\n",
"htmlcode += openbb.widgets.row([ratings_over_time_chart])\n",
"htmlcode += openbb.widgets.row([df_analyst.to_html()])\n",
"body += openbb.widgets.add_tab(\"Analyst Opinions\", htmlcode)\n",
"\n",
"htmlcode = openbb.widgets.row([openbb.widgets.h(3, \"Estimates\") + df_year_estimates.head().to_html()])\n",
"htmlcode += openbb.widgets.row([openbb.widgets.h(3, \"Earnings\") + df_quarter_earnings.head().to_html()])\n",
"htmlcode += openbb.widgets.row([openbb.widgets.h(3, \"Revenues\") + df_quarter_revenues.head().to_html()])\n",
"htmlcode += openbb.widgets.row([openbb.widgets.h(3, \"SEC filings\") + df_sec_filings.head().to_html()])\n",
"htmlcode = openbb.widgets.row(\n",
" [openbb.widgets.h(3, \"Estimates\") + df_year_estimates.head().to_html()]\n",
")\n",
"htmlcode += openbb.widgets.row(\n",
" [openbb.widgets.h(3, \"Earnings\") + df_quarter_earnings.head().to_html()]\n",
")\n",
"htmlcode += openbb.widgets.row(\n",
" [openbb.widgets.h(3, \"Revenues\") + df_quarter_revenues.head().to_html()]\n",
")\n",
"htmlcode += openbb.widgets.row(\n",
" [openbb.widgets.h(3, \"SEC filings\") + df_sec_filings.head().to_html()]\n",
")\n",
"body += openbb.widgets.add_tab(\"Fundamental Analysis\", htmlcode)\n",
" \n",
"\n",
"htmlcode = openbb.widgets.row([net_short_position])\n",
"htmlcode += openbb.widgets.row([price_vs_short_interest])\n",
"htmlcode += openbb.widgets.row([dark_pools])\n",
Expand All @@ -649,12 +754,19 @@
"\n",
"body += openbb.widgets.add_tab(\"Technical Analysis\", openbb.widgets.row([ta_rsi]))\n",
"\n",
"htmlcode = openbb.widgets.row([openbb.widgets.h(3, \"Last Activity\") + df_insider.head(10).to_html(col_space='75px')])\n",
"htmlcode = openbb.widgets.row(\n",
" [\n",
" openbb.widgets.h(3, \"Last Activity\")\n",
" + df_insider.head(10).to_html(col_space=\"75px\")\n",
" ]\n",
")\n",
"body += openbb.widgets.add_tab(\"Insider Trading\", htmlcode)\n",
"\n",
"htmlcode = openbb.widgets.row([finbrain_sentiment])\n",
"htmlcode += openbb.widgets.row([snews])\n",
"htmlcode += openbb.widgets.row([openbb.widgets.h(3, \"Stocktwits\") + stocktwits_sentiment])\n",
"htmlcode += openbb.widgets.row(\n",
" [openbb.widgets.h(3, \"Stocktwits\") + stocktwits_sentiment]\n",
")\n",
"body += openbb.widgets.add_tab(\"Behavioural Analysis\", htmlcode)\n",
"\n",
"htmlcode = openbb.widgets.row([bw_month])\n",
Expand All @@ -673,7 +785,7 @@
"report = openbb.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",
"with open(report_name + \".html\", \"w\", encoding=\"utf-8\") as fh:\n",
" fh.write(report)"
]
},
Expand Down
3 changes: 3 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import pathlib
from typing import Any, Dict, List, Optional, Type
from distutils.util import strtobool

# IMPORTATION THIRDPARTY
import pandas as pd
Expand All @@ -16,6 +17,7 @@

# IMPORTATION INTERNAL
from openbb_terminal import decorators, helper_funcs
from openbb_terminal import feature_flags as obbff

# pylint: disable=redefined-outer-name

Expand All @@ -31,6 +33,7 @@
os.environ["OPENBB_IMG_HOST_ACTIVE"] = "False"
os.environ["OPENBB_DISCORD_BOT_TOKEN"] = "123"
os.environ["OPENBB_IMGUR_CLIENT_ID"] = "123"
obbff.ENABLE_EXIT_AUTO_HELP = strtobool("True")


class Record:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
@pytest.mark.parametrize(
"queue, expected",
[
(["load", "help"], []),
(["load", "help"], ["help"]),
(["quit", "help"], ["help"]),
],
)
Expand Down Expand Up @@ -66,7 +66,7 @@ def test_menu_without_queue_completion(mocker):

result_menu = covid_controller.CovidController(queue=None).menu()

assert result_menu == []
assert result_menu == ["help"]


@pytest.mark.vcr(record_mode="none")
Expand Down Expand Up @@ -110,7 +110,7 @@ def __call__(self, *args, **kwargs):

result_menu = covid_controller.CovidController(queue=None).menu()

assert result_menu == []
assert result_menu == ["help"]


@pytest.mark.vcr(record_mode="none")
Expand Down
Loading

0 comments on commit 57b61d1

Please sign in to comment.