Files
OpenBB/openbb_terminal/stocks/tradinghours/tradinghours_controller.py
montezdesousa 475ebb5acd [WIP] Migrate user, feature flags and configurations to dataclass (#4309)
* implement user and change is guest

* replace User methods

* move remaining functions to user

* fix bug

* portfolio test

* fix tests

* fix tests

* uncomment skip

* ruff

* start credentials model implementation

* change deault structure

* refacto quandl

* change default struct and file names

* bug

* start using global user

* add comments

* move update flair

* change cfg references in keys model

* reddit & fmp

* refactore additional keys

* remaing config keys

* remove unsude imports and fix hub keys

* ruff

* fix line too long

* unblock unittests

* fix keys model tests

* remove os patch

* fix account controller tests

* fix account controller tests

* fix account model

* account fixed

* fix user tests

* User Model

* User Model

* User Model

* Move session folder

* User Model : grouping the models

* User Model : fix bugs

* Config Plot + bug fix

* User Model : Refactoring plots

* Feature flags

* Remove dup

* clean comments a fix some vars

* fix feature flags controller

* refactor obbff from settings controller

* refactor a bunch of obbff variables

* fix bug blocking terminal

* fix integration tests

* refactor controllers with obbff

* refactor remaining ffs

* remove comments

* log not started

* mispelled variable

* set current user on local model

* User Model : moving files + updating

* User Preferences

* User : Refactor is_guest function + bug fix

* User : refactor is_guest function

* Fix conftest.py

* remove lost obbffs

* typo on fileoverwrite

* Plot config: move variables and start plot dpi

* User : tests

* refactor plot dpi references

* remove plot dpi imports

* refactor some config terminal leftover

* /account/sync : fix bug

* remove configs reload

* start path refactor

* installation paths vs user paths

* remove cfg_plot

* Tests : User Refactoring

* user prefix only for preferences

* user prefix only for preferences

* move user paths

* remove comment

* update apply remote configs

* fix tz not updating

* save some copys

* small fix

* create interface for credentials and preferences

* wrong docstrings fixed

* ruff core

* fix some pref setting

* login is better

* ruff

* ruff

* remove Literal

* add small comment

* Tests : User Refactoring

* Credentials Model : add DataBento

* Fix helper_funcs

* Fixing code

* Tests : fixing

* User Model : freezing the models

* Fixed Income + Databento

* Tests : fixing keys

* black

* ruff

* Tests : user model

* Tests : user model

* Fix linting

* Fix linting

* Linting

* Linting

* Fixing code and tests

* Fix tests

* mypy

* SDK

* Clean ruff cache

* Fix syntax issue

* Update fred_view

* Black

* Linting

* Update code

* Update tests

* Linting

* Linting

* Tests

* Black

* Linting

* Linting

* Mock os.listdir to avoid looking for file that doesnt exist

* Mock options paths

* lint

* Tests : fix

* Code : update

* Tests + Linting

* Tests

* Ruff

* Code : update

* Tests

* Code : update

* Fix workflow

* Code : update

---------

Co-authored-by: Chavithra PARANA <chavithra@gmail.com>
Co-authored-by: luqazino@gmail.com <luqazino@gmail.com>
Co-authored-by: James Maslek <jmaslek11@gmail.com>
2023-03-05 00:37:19 +01:00

290 lines
9.9 KiB
Python

"""Trading Hours Controller."""
__docformat__ = "numpy"
import argparse
import logging
import os
from datetime import date
from typing import List, Optional
import pandas as pd
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
from openbb_terminal.helper_funcs import get_user_timezone_or_invalid
from openbb_terminal.menu import session
from openbb_terminal.parent_classes import BaseController
from openbb_terminal.rich_config import MenuText, console
from openbb_terminal.stocks.tradinghours import bursa_view
from openbb_terminal.stocks.tradinghours.bursa_model import get_open
from openbb_terminal.stocks.tradinghours.pandas_market_cal_view import (
display_exchange_holidays,
get_all_holiday_exchange_short_names,
)
from openbb_terminal.stocks.tradinghours.tradinghours_helper import (
get_exchanges_short_names,
get_fd_equities_list,
)
logger = logging.getLogger(__name__)
# pylint: disable=R0902
class TradingHoursController(BaseController):
"""Trading Hours Controller class."""
CHOICES_COMMANDS = ["symbol", "open", "closed", "all", "exchange", "holidays"]
PATH = "/stocks/th/"
FILE_PATH = os.path.join(os.path.dirname(__file__), "README.md")
CHOICES_GENERATION = True
def __init__(self, ticker: str = "", queue: Optional[List[str]] = None):
"""Construct Data."""
super().__init__(queue)
self.equities = get_fd_equities_list()
self.equity_tickers = sorted(list(self.equities.keys()))
short_names_df = get_exchanges_short_names()
short_names_index = short_names_df.index.values
short_names = short_names_df["short_name"].values
all_short_names = list(short_names) + list(short_names_index)
self.all_exchange_short_names = sorted(list(all_short_names))
self.all_holiday_exchange_short_names = sorted(
list(get_all_holiday_exchange_short_names()["short_name"].values)
)
self.symbol = None
self.symbol_name = None
self.symbol_market_open = False
self.exchange = None
if ticker:
if ticker in self.equities.index:
self.symbol = ticker
self.symbol_name = self.equities.loc[ticker]["name"]
self.exchange = self.equities.loc[ticker]["exchange"]
open_ex = get_open()
if self.exchange in open_ex.index:
self.symbol_market_open = True
else:
self.symbol_market_open = False
else:
console.print(f"The ticker {ticker} was not found in the database.")
self.source = "YahooFinance"
self.data = pd.DataFrame()
self.timezone = get_user_timezone_or_invalid()
if session and get_current_user().preferences.USE_PROMPT_TOOLKIT:
choices: dict = self.choices_default
self.completer = NestedCompleter.from_nested_dict(choices)
def print_help(self):
exchange_opened = (
("OPENED" if self.symbol_market_open else "CLOSED")
if self.symbol is not None
else ""
)
mt = MenuText("stocks/th/")
mt.add_cmd("open")
mt.add_cmd("closed")
mt.add_cmd("all")
mt.add_cmd("exchange")
mt.add_cmd("holidays")
mt.add_raw("\n")
mt.add_cmd("symbol")
mt.add_raw("\n")
mt.add_param("_symbol_name", self.symbol_name or "")
mt.add_param("_symbol", self.symbol_name or "")
mt.add_param("_exchange", exchange_opened)
console.print(text=mt.menu_text, menu="Stocks - Trading Hours")
@log_start_end(log=logger)
def call_symbol(self, other_args: List[str]):
"""Process 'symbol' command."""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="symbol",
description="Select the symbol you wish to trade",
)
parser.add_argument(
"-n",
"--name",
help="Symbol",
type=str.upper,
dest="symbol",
)
if (
other_args
and "-n" not in other_args[0]
and "--name" not in other_args[0]
and "-h" not in other_args
):
other_args.insert(0, "-n")
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
self.symbol = ns_parser.symbol
if ns_parser.symbol in self.equities.index:
self.symbol_name = self.equities.loc[self.symbol]["name"]
self.exchange = self.equities.loc[self.symbol]["exchange"]
open_ex = get_open()
if self.exchange in open_ex.index:
self.symbol_market_open = True
else:
self.symbol_market_open = False
# add currency
console.print(
f"\nSelected symbol\nSymbol: {self.symbol}\n"
f"Name: {self.symbol_name}\n"
f"Market open: {self.symbol_market_open}\n"
)
else:
console.print("[red]Symbol not found on database.[/red]\n")
@log_start_end(log=logger)
def call_exchange(self, other_args: List[str]):
"""Process 'exchange' command."""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="exchange",
description="Select the exchange you want see open hours for",
)
parser.add_argument(
"-n",
"--name",
help="Exchange short name",
type=str.upper,
choices=self.all_exchange_short_names,
dest="exchange",
)
if (
other_args
and "-n" not in other_args[0]
and "--name" not in other_args[0]
and "-h" not in other_args
):
other_args.insert(0, "-n")
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
if ns_parser.exchange:
bursa_view.display_exchange(ns_parser.exchange)
else:
logger.error("Select the exchange you want to know about.")
console.print(
"[red]Select the exchange you want to know about.[/red]\n"
)
@log_start_end(log=logger)
def call_open(self, other_args: List[str]):
"""Process 'symbol' command."""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="exchange",
description="Show currently open exchanges",
)
if other_args and "-h" not in other_args:
other_args.insert(0, "-n")
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
bursa_view.display_open()
@log_start_end(log=logger)
def call_closed(self, other_args: List[str]):
"""Process 'symbol' command."""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="exchange",
description="Show currently closed exchanges",
)
if other_args and "-h" not in other_args:
other_args.insert(0, "-n")
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
bursa_view.display_closed()
@log_start_end(log=logger)
def call_all(self, other_args: List[str]):
"""Process 'symbol' command."""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="exchange",
description="Show all exchanges",
)
if other_args and "-h" not in other_args:
other_args.insert(0, "-n")
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
bursa_view.display_all()
@log_start_end(log=logger)
def call_holidays(self, other_args: List[str]):
"""Process 'holidays' command."""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="exchange",
description="Select the exchange and year you want see holidays for",
)
parser.add_argument(
"-n",
"--name",
help="Exchange short name",
dest="exchange",
required=True,
type=str.upper,
choices=self.all_holiday_exchange_short_names,
metavar="LSE",
)
parser.add_argument(
"-y",
"--year",
help="Year",
nargs="?",
type=int,
const=date.today().year,
dest="year",
metavar="year",
)
if (
other_args
and "-n" not in other_args[0]
and "--name" not in other_args[0]
and "-h" not in other_args
):
other_args.insert(0, "-n")
other_args.insert(2, "-y")
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser:
if ns_parser.exchange:
if ns_parser.year:
display_exchange_holidays(ns_parser.exchange, ns_parser.year)
else:
display_exchange_holidays(ns_parser.exchange, date.today().year)
else:
logger.error("Select the exchange and year you want holiday calendar for.")
console.print(
"[red]Select the exchange and year you want holiday calendar for.[/red]\n"
)