Add intro command + improve plot style + internationalisation consistency (#2899)

* improve style of plots

* remove the blend which doesnt look nice in some machines

* remove translation for arguments to be coherent

* Add intro command

* add check to understand if its first time user to run intro by default

* intro doesnt require docs

* silly catch

* fix line length

* anoter lengthy line

* unused import

* unused import

* words

* allow to quit earlier

* style

* fix thing for u didi

* actual fix

* last try

Co-authored-by: Colin Delahunty <72827203+colin99d@users.noreply.github.com>
Co-authored-by: james <jmaslek11@gmail.com>
This commit is contained in:
DidierRLopes
2022-10-20 01:35:23 +01:00
committed by GitHub
parent 52dd7a1f66
commit 3762693df7
7 changed files with 226 additions and 54 deletions

View File

@@ -27,7 +27,7 @@ jobs:
key: ${{ runner.os }}-v1-linting
restore-keys: ${{ runner.os }}-v1-linting
- run: python custom_pre_commit/check_doc.py --ignore-files=settings_controller.py,keys_controller.py,featflags_controller.py,degiro_controller.py,oanda_controller.py --ignore-commands=login,al_swe,info_swe,goodness,resources,yf,yolo,featflags,guess,settings,survey
- run: python custom_pre_commit/check_doc.py --ignore-files=settings_controller.py,keys_controller.py,featflags_controller.py,degiro_controller.py,oanda_controller.py --ignore-commands=login,al_swe,info_swe,goodness,resources,yf,yolo,featflags,guess,settings,survey,intro
- run: pip install bandit black codespell flake8 mypy pyupgrade safety pylint==2.15.2
- run: pip install types-pytz types-requests types-termcolor types-tabulate types-PyYAML types-python-dateutil types-setuptools types-six
- run: bandit -x ./tests -r . || true

View File

@@ -56,6 +56,20 @@ class KeysController(BaseController): # pylint: disable=too-many-public-methods
for api in tqdm(self.API_LIST, desc="Checking keys status"):
self.status_dict[api] = getattr(keys_model, "check_" + str(api) + "_key")()
def is_there_at_least_one_key_defined(self) -> bool:
"""Check if there is at least 1 API key defined.
This is a good proxy to understand whether we are in presence of a first time user or not
Returns
-------
bool
True if at least 1 key is defined, False otherwise
"""
for api in self.API_LIST:
if getattr(keys_model, "check_" + str(api) + "_key")() != "not defined":
return True
return False
def print_help(self):
"""Print help"""
self.check_keys_status()

View File

@@ -13,6 +13,7 @@ en:
wiki: search for an expression in Wikipedia (https://www.wikipedia.org/)
record: record session to be converted into a .openbb routine
stop: stop session recording
intro: introduction on the OpenBB Terminal
_configure_: Configure your own terminal
_main_menu_: Main menu
keys/_keys_: This menu allows you to set your own API keys. Type 'about' for more information
@@ -85,31 +86,13 @@ en:
dashboards: interactive dashboards using voila and jupyter notebooks
reports: customizable research reports through jupyter notebooks
stocks/search: search a specific stock ticker for analysis
stocks/SEARCH: Show companies matching the search query
stocks/SEARCH_query: The search term used to find company tickers
stocks/SEARCH_country: Search by country to find stocks matching the criteria
stocks/SEARCH_sector: Search by sector to find stocks matching the criteria
stocks/SEARCH_industry: Search by industry to find stocks matching the criteria
stocks/SEARCH_exchange: Search by a specific exchange country to find stocks matching the criteria
stocks/load: load a specific stock ticker and additional info for analysis
stocks/_ticker: Stock
stocks/quote: view the current price for a specific stock ticker
stocks/tob: view top of book for loaded ticker (US exchanges only)
stocks/QUOTE: Current quote for stock ticker
stocks/QUOTE_ticker: Stock ticker
stocks/candle: view a candle chart for a specific stock ticker
stocks/CANDLE: Shows historic data for a stock
stocks/CANDLE_plotly: Flag to show interactive plotly chart
stocks/CANDLE_sort: Choose a column to sort by. Only works when raw data is displayed.
stocks/CANDLE_descending: Sort selected column descending. Only works when raw data is displayed.
stocks/CANDLE_raw: Shows raw data instead of chart. If sort is set those are the top ones, otherwise we grab latest data to date
stocks/CANDLE_trend: Flag to add high and low trends to candle
stocks/CANDLE_mov_avg: Add moving average in number of days to plot and separate by a comma
stocks/news: latest news of the company
stocks/codes: FIGI, SIK and SIC codes codes
stocks/NEWS_date: The starting date (format YYYY-MM-DD) to search articles from
stocks/NEWS_oldest: Show oldest articles first
stocks/NEWS_article: Show news only from the sources specified (e.g bbc yahoo.com)
stocks/th: trading hours, check open markets
stocks/options: options menu, chains, open interest, greeks, parity
stocks/disc: discover trending stocks, map, sectors, high short interest

View File

@@ -2,7 +2,7 @@
# LINES
# http://matplotlib.org/api/artist_api.html#module-matplotlib.lines
lines.linewidth: 1.1
lines.linewidth: 3
lines.color: F5EFF3
lines.linestyle: -
lines.marker: None
@@ -26,7 +26,7 @@ font.style: normal
font.variant: normal
font.weight: medium
font.stretch: normal
font.size: 13
font.size: 20
text.color: F5EFF3
@@ -34,7 +34,7 @@ axes.spines.left: true
axes.spines.bottom: true
axes.spines.top: true
axes.spines.right: true
axes.linewidth: 0.2
axes.linewidth: 0.4
axes.labelsize: small
axes.titlelocation: left

View File

@@ -8,7 +8,6 @@ from typing import Tuple
from rich import panel
from rich.console import Console, Theme
from rich.text import Text
from rich.color import Color
import i18n
from openbb_terminal.core.config.paths import MISCELLANEOUS_DIRECTORY
from openbb_terminal import config_terminal as cfg
@@ -291,15 +290,7 @@ class ConsoleAndPanel:
if kwargs and "text" in list(kwargs) and "menu" in list(kwargs):
if not os.getenv("TEST_MODE"):
if obbff.ENABLE_RICH_PANEL:
version = self.blend_text(
f"OpenBB Terminal v{obbff.VERSION}",
Color.parse("#00AAFF").triplet,
Color.parse("#E4003A").triplet,
)
link = " (https://openbb.co)"
link_text = Text(link)
link_text.stylize("#FCED00", 0, len(link))
version += link_text
version = f"[param]OpenBB Terminal v{obbff.VERSION}[/param] (https://openbb.co)"
self.console.print(
panel.Panel(
"\n" + kwargs["text"],

View File

@@ -227,7 +227,7 @@ class StocksController(StockBaseController):
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="search",
description=translate("stocks/SEARCH"),
description="Show companies matching the search query",
)
parser.add_argument(
"-q",
@@ -237,7 +237,7 @@ class StocksController(StockBaseController):
type=str.lower,
default="",
nargs="+",
help=translate("stocks/SEARCH_query"),
help="The search term used to find company tickers",
)
parser.add_argument(
"-c",
@@ -246,7 +246,7 @@ class StocksController(StockBaseController):
nargs=argparse.ONE_OR_MORE,
action=choice_check_after_action(AllowArgsWithWhiteSpace, self.country),
dest="country",
help=translate("stocks/SEARCH_country"),
help="Search by country to find stocks matching the criteria",
)
parser.add_argument(
"-s",
@@ -255,7 +255,7 @@ class StocksController(StockBaseController):
nargs=argparse.ONE_OR_MORE,
action=choice_check_after_action(AllowArgsWithWhiteSpace, self.sector),
dest="sector",
help=translate("stocks/SEARCH_sector"),
help="Search by sector to find stocks matching the criteria",
)
parser.add_argument(
"-i",
@@ -264,7 +264,7 @@ class StocksController(StockBaseController):
nargs=argparse.ONE_OR_MORE,
action=choice_check_after_action(AllowArgsWithWhiteSpace, self.industry),
dest="industry",
help=translate("stocks/SEARCH_industry"),
help="Search by industry to find stocks matching the criteria",
)
parser.add_argument(
"-e",
@@ -272,7 +272,7 @@ class StocksController(StockBaseController):
default="",
choices=list(stocks_helper.market_coverage_suffix.keys()),
dest="exchange_country",
help=translate("stocks/SEARCH_exchange"),
help="Search by a specific exchange country to find stocks matching the criteria",
)
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-q")
@@ -336,7 +336,7 @@ class StocksController(StockBaseController):
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="quote",
description=translate("stocks/QUOTE"),
description="Current quote for stock ticker",
)
if self.ticker:
parser.add_argument(
@@ -345,7 +345,7 @@ class StocksController(StockBaseController):
action="store",
dest="s_ticker",
default=ticker,
help=translate("stocks/QUOTE_ticker"),
help="Stock ticker",
)
else:
parser.add_argument(
@@ -386,7 +386,7 @@ class StocksController(StockBaseController):
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="candle",
description=translate("stocks/CANDLE"),
description="Shows historic data for a stock",
)
parser.add_argument(
"-p",
@@ -394,7 +394,7 @@ class StocksController(StockBaseController):
dest="plotly",
action="store_false",
default=True,
help=translate("stocks/CANDLE_plotly"),
help="Flag to show interactive plotly chart",
)
parser.add_argument(
"--sort",
@@ -402,7 +402,7 @@ class StocksController(StockBaseController):
default="",
type=str,
dest="sort",
help=translate("stocks/CANDLE_sort"),
help="Choose a column to sort by. Only works when raw data is displayed.",
)
parser.add_argument(
"-d",
@@ -410,28 +410,28 @@ class StocksController(StockBaseController):
action="store_false",
dest="descending",
default=True,
help=translate("stocks/CANDLE_descending"),
help="Sort selected column descending. Only works when raw data is displayed.",
)
parser.add_argument(
"--raw",
action="store_true",
dest="raw",
default=False,
help=translate("stocks/CANDLE_raw"),
help="Shows raw data instead of chart.",
)
parser.add_argument(
"-t",
"--trend",
action="store_true",
default=False,
help=translate("stocks/CANDLE_trend"),
help="Flag to add high and low trends to candle",
dest="trendlines",
)
parser.add_argument(
"--ma",
dest="mov_avg",
type=str,
help=translate("stocks/CANDLE_mov_avg"),
help="Add moving average in number of days to plot and separate by a comma",
default=None,
)
parser.add_argument(
@@ -514,7 +514,7 @@ class StocksController(StockBaseController):
parser = argparse.ArgumentParser(
add_help=False,
prog="news",
description=translate("stocks/news"),
description="latest news of the company",
)
parser.add_argument(
"-d",
@@ -523,7 +523,7 @@ class StocksController(StockBaseController):
dest="n_start_date",
type=valid_date,
default=datetime.now() - timedelta(days=7),
help=translate("stocks/NEWS_date"),
help="The starting date (format YYYY-MM-DD) to search articles from",
)
parser.add_argument(
"-o",
@@ -531,7 +531,7 @@ class StocksController(StockBaseController):
action="store_false",
dest="n_oldest",
default=True,
help=translate("stocks/NEWS_oldest"),
help="Show oldest articles first",
)
parser.add_argument(
"-s",
@@ -539,7 +539,7 @@ class StocksController(StockBaseController):
dest="sources",
default=[],
nargs="+",
help=translate("stocks/NEWS_sources"),
help="Show news only from the sources specified (e.g bbc yahoo.com)",
)
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-l")

View File

@@ -11,6 +11,7 @@ import sys
import webbrowser
from typing import List
import dotenv
from rich import panel
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import NestedCompleter
@@ -19,7 +20,9 @@ from prompt_toolkit.formatted_text import HTML
import pandas as pd
from openbb_terminal import feature_flags as obbff
from openbb_terminal import keys_controller
from openbb_terminal.terminal_helper import is_packaged_application
from openbb_terminal.core.config.paths import (
HOME_DIRECTORY,
MISCELLANEOUS_DIRECTORY,
@@ -39,7 +42,7 @@ from openbb_terminal.loggers import setup_logging
from openbb_terminal.core.log.generation.settings_logger import log_all_settings
from openbb_terminal.menu import session
from openbb_terminal.parent_classes import BaseController
from openbb_terminal.rich_config import console, MenuText, translate
from openbb_terminal.rich_config import console, MenuText
from openbb_terminal.terminal_helper import (
bootup,
check_for_updates,
@@ -53,7 +56,8 @@ from openbb_terminal.terminal_helper import (
from openbb_terminal.helper_funcs import parse_and_split_input
from openbb_terminal.common import feedparser_view
# pylint: disable=too-many-public-methods,import-outside-toplevel,too-many-branches,no-member,C0302
# pylint: disable=too-many-public-methods,import-outside-toplevel
# pylint: disable=too-many-branches,no-member,C0302,too-many-return-statements
logger = logging.getLogger(__name__)
@@ -72,6 +76,7 @@ class TerminalController(BaseController):
"exe",
"guess",
"news",
"intro",
]
CHOICES_MENUS = [
"stocks",
@@ -135,6 +140,7 @@ class TerminalController(BaseController):
"""Print help"""
mt = MenuText("")
mt.add_info("_home_")
mt.add_cmd("intro")
mt.add_cmd("about")
mt.add_cmd("support")
mt.add_cmd("survey")
@@ -177,7 +183,7 @@ class TerminalController(BaseController):
parse = argparse.ArgumentParser(
add_help=False,
prog="news",
description=translate("news"),
description="display news articles based on term and data sources",
)
parse.add_argument(
"-t",
@@ -450,6 +456,180 @@ class TerminalController(BaseController):
self.queue = self.load_class(SourcesController, self.queue)
def call_intro(self, _):
"""Process intro command"""
console.print(panel.Panel("[purple]Welcome to the OpenBB Terminal.[/purple]"))
console.print(
"\nThe following walkthrough will guide you towards making the most out of the OpenBB Terminal.\n\n"
"Press Enter to continue or 'q' followed by Enter to exit."
)
if input("") == "q":
return
console.print("\n")
console.print(panel.Panel("[purple]#1 - Commands vs menu.[/purple]"))
console.print(
"\nMenus are a collection of 'commands' and 'sub-menus'.\n"
"You can identify them through their distinct color and a '>' at the beginning of the line\n\n"
"For instance:\n"
"[menu]> stocks access historical pricing data, options, sector [/menu]"
"[menu]and industry, and overall due diligence [/menu]\n\n\n"
"Commands are expected to return data either as a chart or table.\n"
"You can identify them through their distinct color\n\n"
"For instance:\n"
"[cmds]> news display news articles based on term and data sources [/cmds]"
)
if input("") == "q":
return
console.print("\n")
console.print(panel.Panel("[purple]#2 - Using commands[/purple]"))
console.print(
"\nCommands throughout the terminal can have additional arguments.\n\n"
"Let's say that in the current menu, you want to have more information about the command 'news'. \n\n"
"You can either see the available arguments in the terminal, using: [param]news -h[/param]\n\n",
"or you can find out more about it with an output example on the browser, using: [param]about news[/param]",
)
if input("") == "q":
return
console.print("\n")
console.print(panel.Panel("[purple]#3 - Setting API Keys[/purple]"))
console.print(
"\nThe OpenBB Terminal does not own any of the data you have access to.\n\n"
"Instead, we provide the infrastructure to access over 100 different data sources from a single location.\n\n"
"Thus, it is necessary for each user to set their own API keys for the various third party sources\n\n"
"You can find more about this on the '[param]keys[/param]' menu.\n\n"
"For many commands, there are multiple data sources that can be selected.\n\n"
"The help menu shows the data sources supported by each command.\n\n"
"For instance:\n"
"[cmds] load load a specific stock ticker and additional info for analysis [/cmds]"
"[src][YahooFinance, IEXCloud, AlphaVantage, Polygon, EODHD] [/src]\n\n"
"The user can go into the '[param]sources[/param]' menu and select their preferred default data source."
)
if input("") == "q":
return
console.print("\n")
console.print(
panel.Panel("[purple]#4 - Symbol dependent menus and commands[/purple]")
)
console.print(
"\nThroughout the terminal, you will see commands and menus greyed out.\n\n"
"These menus or commands cannot be accessed until an object is loaded.\n\n"
"Let's take as an example the '[param]stocks[/param]' menu.\n\n"
"You will see that the command '[param]disc[/param]' is available as its goal is to discover new tickers:\n"
"[menu]> stocks access historical pricing data, options, sector [/menu]\n\n"
"On the other hand, '[param]fa[/param]' menu (fundamental analysis) requires a ticker to be loaded.\n\n"
"And therefore, appears as:\n"
"[dim]> fa fundamental analysis of loaded ticker [/dim]\n\n"
"Once a ticker is loaded with: [param]load TSLA[/param]\n\n"
"The '[param]fa[/param]' menu will be available as:\n"
"[menu]> fa fundamental analysis of loaded ticker [/menu]"
)
if input("") == "q":
return
console.print("\n")
console.print(panel.Panel("[purple]#5 - Terminal Navigation[/purple]"))
console.print(
"\nThe terminal has a tree like structure, where menus branch off into new menus.\n\n"
"The users current location is displayed before the text prompt.\n\n"
"For instance, if the user is inside the menu disc which is inside stocks, the following prompt "
"will appear: \n2022 Oct 18, 21:53 (🦋) [param]/stocks/disc/[/param] $\n\n"
"If the user wants to go back to the menu above, all they need to do is type '[param]q[/param]'.\n\n"
"If the user wants to go back to the home of the terminal, they can type '[param]/[/param]' instead.\n\n"
"Note: Always type '[param]h[/param]' to know what commands are available in each menu"
)
if input("") == "q":
return
console.print("\n")
console.print(panel.Panel("[purple]#6 - Command Pipeline[/purple]"))
console.print(
"\nThe terminal offers the capability of allowing users to speed up their navigation and command execution."
"\n\nTherefore, typing the following prompt is valid:\n"
"2022 Oct 18, 21:53 (🦋) / $ [param]stocks/load TSLA/dd/pt[/param]\n\n"
"In this example, the terminal - in a single action - will go into '[param]stocks[/param]' menu, "
"run command '[param]load[/param]' with '[param]TSLA[/param]' as input, \n"
"go into sub-menu '[param]dd[/param]' (due diligence) and run the command '[param]pt[/param]' (price target)."
)
if input("") == "q":
return
console.print("\n")
console.print(panel.Panel("[purple]#6 - OpenBB Scripts[/purple]"))
console.print(
"\nThe command pipeline capability is great, but the user experience wasn't great copy-pasting large "
"lists of commands.\n\n"
"We allow the user to create a text file of the form:\n\n"
"[param]FOLDER_PATH/my_script.openbb[/param]\n"
"stocks\nload TSLA\ndd\npt\n\n"
"which can be run through the '[param]exe[/param]' command in the home menu, with:\n"
"2022 Oct 18, 22:33 (🦋) / $ [param]exe FOLDER_PATH/my_script.openbb[/param]\n\n"
)
if input("") == "q":
return
console.print("\n")
console.print(
panel.Panel("[purple]#7 - OpenBB Scripts with Arguments[/purple]")
)
console.print(
"\nThe user can create a script that includes arguments for the commands.\n\n"
"Example:\n\n"
"[param]FOLDER_PATH/my_script_with_variable_input.openbb[/param]\n"
"stocks\n# this is a comment\nload $ARGV[0]\ndd\npt\nq\nload $ARGV[1]\ncandle\n\n"
"and then, if this script is run with:\n"
"2022 Oct 18, 22:33 (🦋) / $ [param]exe FOLDER_PATH/my_script_with_variable_input.openbb "
"-i AAPL,MSFT[/param]\n\n"
"This means that the [param]pt[/param] will run on [param]AAPL[/param] while "
"[param]candle[/param] on [param]MSFT[/param]"
)
if input("") == "q":
return
console.print("\n")
console.print(panel.Panel("[purple]#8 - OpenBB Script Generation/purple]"))
console.print(
"\n"
"To make it easier for users to create scripts, we have created a "
"command that 'records' user commands "
"directly into a script.\n\n"
"From the home menu, the user can run:\n"
"2022 Oct 18, 22:33 (🦋) / $ [param]record[/param]\n\n"
"and then perform your typical investment research workflow before entering\n\n"
"2022 Oct 18, 22:33 (🦋) / $ [param]stop[/param]\n\n"
"After stopping, the script will be saved to the 'scripts' folder."
)
if input("") == "q":
return
console.print("\n")
console.print(panel.Panel("[purple]#9 - Terminal Customization[/purple]"))
console.print(
"\nUsers should explore the [param]settings[/param] and [param]featflags[/param] menus "
"to configure their terminal.\n\n"
"The fact that our terminal is fully open source allows users to be able to customize "
"anything they want.\n\n"
"If you are interested in contributing to the project, please check:\n"
"[param]https://github.com/OpenBB-finance/OpenBBTerminal[/param]"
)
if input("") == "q":
return
console.print("\n")
console.print(panel.Panel("[purple]#10 - Support[/purple]"))
console.print(
"\n"
"We are nothing without our community, hence we put a lot of effort in being here for you.\n\n"
"If you find any bug that you wish to report to improve the terminal you can do so with:\n"
"2022 Oct 18, 22:33 (🦋) / $ [param]support CMD[/param]\n\n"
"which should open a form in your browser where you can report the bug in said 'CMD'.\n\n"
"If you want to know more, or have any further question. Please join us on Discord:\n"
"[param]https://openbb.co/discord[/param]"
)
def call_exe(self, other_args: List[str]):
"""Process exe command"""
# Merge rest of string path to other_args and remove queue since it is a dir
@@ -638,6 +818,10 @@ def terminal(jobs_cmds: List[str] = None, test_mode=False):
bootup()
if not jobs_cmds:
welcome_message()
if not keys_controller.KeysController().is_there_at_least_one_key_defined():
t_controller.call_intro(None)
t_controller.print_help()
check_for_updates()