diff options
author | teh_coderer <me@tehcoderer.com> | 2023-03-08 08:22:16 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-08 08:22:16 -0600 |
commit | 0d219fdb6e243ffefb5068925261af448c21f7ee (patch) | |
tree | 6dfd8116019da9c2dea93b5a90ecb90c5fe5d2ac | |
parent | 20ca67c19b59e748df0dc962eeb79fc443caabc7 (diff) | |
parent | 5656dacff624563f733688e823ee3ed52c4aecfa (diff) |
Merge branch 'develop' into feature/tables
27 files changed, 315 insertions, 190 deletions
diff --git a/openbb_terminal/common/quantitative_analysis/qa_view.py b/openbb_terminal/common/quantitative_analysis/qa_view.py index 8e22af157db..bff259487b6 100644 --- a/openbb_terminal/common/quantitative_analysis/qa_view.py +++ b/openbb_terminal/common/quantitative_analysis/qa_view.py @@ -830,6 +830,7 @@ def display_raw( df1 = pd.DataFrame(data) if isinstance(data, pd.Series) else data.copy() if sortby: + sortby = sortby.replace("_", " ") try: sort_col = [x.lower().replace(" ", "") for x in df1.columns].index( sortby.lower().replace(" ", "") diff --git a/openbb_terminal/fixedincome/fixedincome_controller.py b/openbb_terminal/fixedincome/fixedincome_controller.py index 061c24b7506..f2442d46d75 100644 --- a/openbb_terminal/fixedincome/fixedincome_controller.py +++ b/openbb_terminal/fixedincome/fixedincome_controller.py @@ -77,10 +77,10 @@ class FixedIncomeController(BaseController): # These values need to work with multi options which # is why they are defined here self.choices["treasury"]["--short"] = { - c: None for c in oecd_model.COUNTRY_TO_CODE + c: None for c in oecd_model.COUNTRY_TO_CODE_SHORT } self.choices["treasury"]["--long"] = { - c: None for c in oecd_model.COUNTRY_TO_CODE + c: None for c in oecd_model.COUNTRY_TO_CODE_LONG } self.choices["spot"]["--maturity"] = { diff --git a/openbb_terminal/fixedincome/oecd_model.py b/openbb_terminal/fixedincome/oecd_model.py index cfea4861a84..cedae5a5a94 100644 --- a/openbb_terminal/fixedincome/oecd_model.py +++ b/openbb_terminal/fixedincome/oecd_model.py @@ -11,8 +11,57 @@ from openbb_terminal.decorators import log_start_end logger = logging.getLogger(__name__) +COUNTRY_TO_CODE_SHORT = { + "australia": "AUS", + "austria": "AUT", + "belgium": "BEL", + "bulgaria": "BGR", + "canada": "CAN", + "switzerland": "CHE", + "chile": "CHL", + "china": "CHN", + "colombia": "COL", + "costa_rica": "CRI", + "czech_republic": "CZE", + "germany": "DEU", + "denmark": "DNK", + "euro_area": "EA19", + "spain": "ESP", + "estonia": "EST", + "finland": "FIN", + "france": "FRA", + "united_kingdom": "GBR", + "greece": "GRC", + "croatia": "HRV", + "hungary": "HUN", + "indonesia": "IDN", + "india": "IND", + "ireland": "IRL", + "iceland": "ISL", + "israel": "ISR", + "italy": "ITA", + "japan": "JPN", + "korea": "KOR", + "lithuania": "LTU", + "luxembourg": "LUX", + "latvia": "LVA", + "mexico": "MEX", + "netherlands": "NLD", + "norway": "NOR", + "new_zealand": "NZL", + "poland": "POL", + "portugal": "PRT", + "romania": "ROU", + "russia": "RUS", + "slovak_republic": "SVK", + "slovenia": "SVN", + "sweden": "SWE", + "united_states": "USA", + "south_africa": "ZAF", +} -COUNTRY_TO_CODE = { + +COUNTRY_TO_CODE_LONG = { "australia": "AUS", "austria": "AUT", "belgium": "BEL", @@ -27,6 +76,7 @@ COUNTRY_TO_CODE = { "czech_republic": "CZE", "germany": "DEU", "denmark": "DNK", + "euro_area": "EA19", "spain": "ESP", "estonia": "EST", "finland": "FIN", @@ -112,7 +162,7 @@ def get_interest_rate_data( elif len(end_date) > 8: end_date = end_date[:8] df = pd.read_csv( - f"https://stats.oecd.org/sdmx-json/data/DP_LIVE/.LTINT.TOT.PC_PA.M/OECD?contentType=csv&detail=code" + f"https://stats.oecd.org/sdmx-json/data/DP_LIVE/.STINT.TOT.PC_PA.M/OECD?contentType=csv&detail=code" f"&separator=comma&csv-lang=en&startPeriod={start_date}&endPeriod={end_date}", index_col=5, ) @@ -131,11 +181,12 @@ def get_interest_rate_data( month = int(end_date[5:7]) end_date = end_date[:4] + "-Q" + str((month - 1) // 3 + 1) df = pd.read_csv( - f"https://stats.oecd.org/sdmx-json/data/DP_LIVE/.LTINTFORECAST.TOT.PC_PA.Q/OECD?contentType=csv&detail" + f"https://stats.oecd.org/sdmx-json/data/DP_LIVE/.STINTFORECAST.TOT.PC_PA.Q/OECD?contentType=csv&detail" f"=code&separator=comma&csv-lang=en&startPeriod={start_date}&endPeriod={end_date}", index_col=5, ) data_name = "3 month with forecast" + elif data == "long": if isinstance(start_date, datetime): start_date = start_date.strftime("%Y-%m") @@ -146,7 +197,7 @@ def get_interest_rate_data( elif len(end_date) > 8: end_date = end_date[:8] df = pd.read_csv( - f"https://stats.oecd.org/sdmx-json/data/DP_LIVE/.STINT.TOT.PC_PA.M/OECD?contentType=csv&detail=code" + f"https://stats.oecd.org/sdmx-json/data/DP_LIVE/.LTINT.TOT.PC_PA.M/OECD?contentType=csv&detail=code" f"&separator=comma&csv-lang=en&startPeriod={start_date}&endPeriod={end_date}", index_col=5, ) @@ -165,7 +216,7 @@ def get_interest_rate_data( month = int(end_date[5:7]) end_date = end_date[:4] + "-Q" + str((month - 1) // 3 + 1) df = pd.read_csv( - f"https://stats.oecd.org/sdmx-json/data/DP_LIVE/.STINTFORECAST.TOT.PC_PA.Q/OECD?contentType=csv&detail" + f"https://stats.oecd.org/sdmx-json/data/DP_LIVE/.LTINTFORECAST.TOT.PC_PA.Q/OECD?contentType=csv&detail" f"=code&separator=comma&csv-lang=en&startPeriod={start_date}&endPeriod={end_date}", index_col=5, ) @@ -176,7 +227,14 @@ def get_interest_rate_data( result = pd.DataFrame() for country in countries: # type: ignore - temp = pd.DataFrame(df[df["LOCATION"] == COUNTRY_TO_CODE[country]]["Value"]) + if data in ["short", "short_forecast"]: + temp = pd.DataFrame( + df[df["LOCATION"] == COUNTRY_TO_CODE_SHORT[country]]["Value"] + ) + else: + temp = pd.DataFrame( + df[df["LOCATION"] == COUNTRY_TO_CODE_LONG[country]]["Value"] + ) temp.columns = [f"{country} ({data_name})"] result = pd.concat([result, temp], axis=1) diff --git a/openbb_terminal/helper_funcs.py b/openbb_terminal/helper_funcs.py index 7d4e3aebf4e..0d2f762d635 100644 --- a/openbb_terminal/helper_funcs.py +++ b/openbb_terminal/helper_funcs.py @@ -1986,7 +1986,7 @@ def update_news_from_tweet_to_be_displayed() -> str: url = f"https://twitter.com/x/status/{last_tweet.id_str}" # In case the handle provided doesn't exist, we skip it - except tweepy.errors.NotFound: + except (tweepy.errors.NotFound, tweepy.errors.Unauthorized): pass if last_tweet_dt and news_tweet_to_use: diff --git a/openbb_terminal/miscellaneous/data_sources_default.json b/openbb_terminal/miscellaneous/data_sources_default.json index 3e34d30783a..d0b9da7f165 100644 --- a/openbb_terminal/miscellaneous/data_sources_default.json +++ b/openbb_terminal/miscellaneous/data_sources_default.json @@ -8,12 +8,12 @@ "news": ["Feedparser", "NewsApi"], "load": ["YahooFinance", "AlphaVantage", "Polygon", "EODHD", "Intrinio", "DataBento"], "th": { - "symbol": ["FinanceDatabase"], "open": ["Bursa"], "closed": ["Bursa"], "all": ["Bursa"], "exchange": ["Bursa"], - "holidays":["PandasMarketCalendars"] + "holidays":["PandasMarketCalendars"], + "symbol": ["FinanceDatabase"] }, "options": { "unu": ["FDScanner"], @@ -28,7 +28,6 @@ "pcr": ["AlphaQuery"], "info": ["Barchart"], "chains": ["YahooFinance", "Tradier", "Nasdaq", "Intrinio"], - "eodchain":["Intrinio"], "oi": ["YahooFinance", "Tradier", "Nasdaq"], "vol": ["YahooFinance", "Tradier", "Nasdaq"], "voi": ["YahooFinance", "Tradier", "Nasdaq"], @@ -39,6 +38,7 @@ "parity": ["YahooFinance"], "binom": ["YahooFinance"], "greeks": ["YahooFinance"], + "eodchain":["Intrinio"], "pricing": { "add": [], "rmv": [], @@ -65,7 +65,6 @@ "active": ["YahooFinance"], "ulc": ["YahooFinance"], "asc": ["YahooFinance"], - "ford": ["Fidelity"], "arkord": ["CathiesArk"], "upcoming": ["SeekingAlpha"], "trending": ["SeekingAlpha"], @@ -122,9 +121,6 @@ "view": [], "set": [], "filter": ["OpenInsider"], - "stats": ["OpenInsider"], - "act": ["BusinessInsider"], - "lins": ["Finviz"], "lcb": ["OpenInsider"], "lpsb": ["OpenInsider"], "lit": ["OpenInsider"], @@ -144,7 +140,10 @@ "tippm": ["OpenInsider"], "tist": ["OpenInsider"], "tispw": ["OpenInsider"], - "tispm": ["OpenInsider"] + "tispm": ["OpenInsider"], + "stats": ["OpenInsider"], + "act": ["BusinessInsider"], + "lins": ["Finviz"] }, "gov": { "load": ["YahooFinance", "AlphaVantage", "Polygon", "EODHD"], @@ -164,11 +163,7 @@ "headlines": ["FinBrain"], "snews": ["Finnhub"], "wsb": ["Reddit"], - "watchlist": ["Reddit"], - "popular": ["Reddit"], "spacc": ["Reddit"], - "spac": ["Reddit"], - "getdd": ["Reddit"], "redditsent": ["Reddit"], "trending": ["Stocktwits"], "stalker": ["Stocktwits"], @@ -180,11 +175,7 @@ "regions": ["Google"], "interest": ["Google"], "queries": ["Google"], - "rise": ["Google"], - "trend": ["SentimentInvestor"], - "hist": ["SentimentInvestor"], - "jcdr": ["JimCramer"], - "jctr": ["JimCramer"] + "rise": ["Google"] }, "ca": { "load": ["YahooFinance", "AlphaVantage", "Polygon", "EODHD"], @@ -210,6 +201,18 @@ }, "fa": { "load": ["YahooFinance", "AlphaVantage", "Polygon", "EODHD"], + "enterprise": ["FinancialModelingPrep", "YahooFinance"], + "overview": ["Finviz", "FinancialModelingPrep", "AlphaVantage", "YahooFinance"], + "divs": ["YahooFinance"], + "splits": ["YahooFinance"], + "rating": ["Finviz", "FinancialModelingPrep"], + "rot": ["Finnhub"], + "score": ["FinancialModelingPrep"], + "warnings": ["MarketWatch"], + "mgmt": ["BusinessInsider"], + "shrs": ["YahooFinance"], + "supplier": ["CSIMarket"], + "customer": ["CSIMarket"], "income": [ "FinancialModelingPrep", "Polygon", @@ -231,35 +234,20 @@ "EODHD", "YahooFinance" ], - "overview": ["Finviz", "FinancialModelingPrep", "AlphaVantage", "YahooFinance"], - "mgmt": ["BusinessInsider"], - "analysis": ["Elect"], - "score": ["FinancialModelingPrep"], - "quote": ["FinancialModelingPrep"], - "enterprise": ["FinancialModelingPrep", "YahooFinance"], + "growth": ["FinancialModelingPrep"], "metrics": ["FinancialModelingPrep", "AlphaVantage"], "ratios": ["FinancialModelingPrep"], - "growth": ["FinancialModelingPrep"], - "revfc": ["SeekingAlpha"], - "epsfc": ["SeekingAlpha"], - "warnings": ["MarketWatch"], - "dcf": ["StockAnalysis"], - "dcfc": ["FinancialModelingPrep"], - "info": ["YahooFinance"], - "shrs": ["YahooFinance"], - "cal": ["YahooFinance"], - "divs": ["YahooFinance"], - "splits": ["YahooFinance"], - "earnings": ["AlphaVantage", "YahooFinance"], - "fraud": ["AlphaVantage"], "dupont": ["AlphaVantage"], - "rating": ["Finviz", "FinancialModelingPrep"], - "rot": ["Finnhub"], - "pt": ["BusinessInsider"], - "est": ["BusinessInsider"], + "fraud": ["AlphaVantage"], "sec": ["MarketWatch", "FinancialModelingPrep"], - "supplier": ["CSIMarket"], - "customer": ["CSIMarket"] + "analysis": ["Elect"], + "earnings": ["AlphaVantage", "YahooFinance"], + "epsfc": ["SeekingAlpha"], + "revfc": ["SeekingAlpha"], + "est": ["BusinessInsider"], + "pt": ["BusinessInsider"], + "dcf": ["StockAnalysis"], + "dcfc": ["FinancialModelingPrep"] }, "bt": { "load": ["YahooFinance", "AlphaVantage", "Polygon", "EODHD"], @@ -267,16 +255,13 @@ }, "ta": { "load": ["YahooFinance", "AlphaVantage", "Polygon", "EODHD"], - "tv": ["TradingView"], "recom": ["TradingView"], - "view": ["Finviz"], - "summary": ["FinBrain"] + "summary": ["FinBrain"], + "tv": ["TradingView"], + "view": ["Finviz"] }, "qa": { "load": ["YahooFinance", "AlphaVantage", "Polygon", "EODHD"] - }, - "pred": { - "load": ["YahooFinance", "AlphaVantage", "Polygon", "EODHD"] } }, "crypto": { @@ -336,6 +321,9 @@ "ueat": ["BitQuery"], "ttcp": ["BitQuery"], "baas": ["BitQuery"], + "dt": ["Shroom"], + "ds": ["Shroom"], + "tvl": ["Shroom"], "address": ["Ethplorer"], "top": ["Ethplorer"], "balance": ["Ethplorer"], @@ -344,14 +332,10 @@ "holders": ["Ethplorer"], "th": ["Ethplorer"], "prices": ["Ethplorer"], - "tx": ["Ethplorer"], - "dt": ["Shroom"], - "ds": ["Shroom"], - "tvl": ["Shroom"] + "tx": ["Ethplorer"] }, "defi": { "newsletter": ["Substack"], - "dpi": ["DeFiPulse"], "vaults": ["Coindix"], "tokens": ["TheGraph"], "stats": ["TheGraph"], @@ -362,8 +346,6 @@ "gdapps": ["DeFiLlama"], "stvl": ["DeFiLlama"], "dtvl": ["DeFiLlama"], - "aterra": ["TerraEngineer"], - "ayr": ["TerraEngineer"], "sinfo": ["TerraFCD"], "validators": ["TerraFCD"], "gacc": ["TerraFCD"], @@ -391,6 +373,7 @@ "gov": ["Messari"], "basic": ["CoinPaprika"], "stats": ["Coinbase"], + "desc": ["TokenTerminal"], "market": ["CoinGecko"], "mkt": ["CoinPaprika"], "ex": ["CoinPaprika"], @@ -407,6 +390,7 @@ "ps": ["CoinPaprika"], "mcapdom": ["Messari"], "mt": ["Messari"], + "funot": ["TokenTerminal"], "team": ["Messari"], "inv": ["Messari"], "tk": ["Messari"], @@ -419,9 +403,7 @@ "social": ["CoinGecko"], "score": ["CoinGecko"], "dev": ["CoinGecko"], - "gh": ["Santiment"], - "desc": ["TokenTerminal"], - "funot": ["TokenTerminal"] + "gh": ["Santiment"] }, "ta": { "load": ["YahooFinance", "CoinGecko", "CCXT"], @@ -429,28 +411,21 @@ }, "qa": { "load": ["YahooFinance", "CoinGecko", "CCXT"] - }, - "pred": { - "load": ["YahooFinance", "CoinGecko", "CCXT"] } }, "etf": { "search": ["FinanceDatabase", "StockAnalysis"], "load": ["YahooFinance"], - "overview": ["StockAnalysis"], - "holdings": ["StockAnalysis"], - "weights": ["FinancialModelingPrep"], - "news": ["NewsApi"], - "compare": ["StockAnalysis"], "disc": { "gainers": ["WallStreetJournal"], "decliners": ["WallStreetJournal"], "active": ["WallStreetJournal"] }, - "screen": { - "screen": ["StockAnalysis"], - "sbc": ["FinanceDatabase"] - } + "overview": ["StockAnalysis"], + "holdings": ["StockAnalysis"], + "weights": ["FinancialModelingPrep"], + "news": ["NewsApi"], + "compare": ["StockAnalysis"] }, "economy": { "overview": ["WallStreetJournal"], diff --git a/openbb_terminal/miscellaneous/i18n/en.yml b/openbb_terminal/miscellaneous/i18n/en.yml index 6e56e1c5726..74887da3e25 100644 --- a/openbb_terminal/miscellaneous/i18n/en.yml +++ b/openbb_terminal/miscellaneous/i18n/en.yml @@ -412,6 +412,7 @@ en: stocks/bt/rsi: buy when RSI < low and sell when RSI > high stocks/bt/load: load a specific stock ticker for analysis stocks/ta/_ticker: Ticker + stocks/ta/load: load a specific stock ticker for analysis stocks/ta/view: view historical data and trendlines stocks/ta/summary: technical summary report stocks/ta/recom: recommendation based on technical indicators diff --git a/openbb_terminal/parent_classes.py b/openbb_terminal/parent_classes.py index 0106f98f317..14dc812c902 100644 --- a/openbb_terminal/parent_classes.py +++ b/openbb_terminal/parent_classes.py @@ -1089,6 +1089,13 @@ class StockBaseController(BaseController, metaclass=ABCMeta): self.suffix = "" # To hold suffix for Yahoo Finance self.add_info = stocks_helper.additional_info_about_ticker("") self.TRY_RELOAD = True + self.USER_IMPORT_FILES = { + filepath.name: filepath + for file_type in ["csv"] + for filepath in ( + get_current_user().preferences.USER_CUSTOM_IMPORTS_DIRECTORY / "stocks" + ).rglob(f"*.{file_type}") + } def call_load(self, other_args: List[str]): """Process load command.""" @@ -1209,25 +1216,10 @@ class StockBaseController(BaseController, metaclass=ABCMeta): # This seems to block the .exe since the folder needs to be manually created # This block makes sure that we only look for the file if the -f flag is used # Adding files in the argparse choices, will fail for the .exe even without -f - STOCKS_CUSTOM_IMPORTS = ( - get_current_user().preferences.USER_CUSTOM_IMPORTS_DIRECTORY - / "stocks" - ) - try: - file_list = [x.name for x in STOCKS_CUSTOM_IMPORTS.iterdir()] - if ns_parser.filepath not in file_list: - console.print( - f"[red]{ns_parser.filepath} not found in custom_imports/stocks/ " - "folder[/red]." - ) - return - except Exception as e: - console.print(e) - return - - df_stock_candidate = stocks_helper.load_custom( - str(STOCKS_CUSTOM_IMPORTS / ns_parser.filepath) + file_location = self.USER_IMPORT_FILES.get( + ns_parser.filepath, ns_parser.filepath ) + df_stock_candidate = stocks_helper.load_custom(str(file_location)) if df_stock_candidate.empty: return is_df = isinstance(df_stock_candidate, pd.DataFrame) diff --git a/openbb_terminal/stocks/backtesting/bt_controller.py b/openbb_terminal/stocks/backtesting/bt_controller.py index 6bf94957bdc..12904fb0df6 100644 --- a/openbb_terminal/stocks/backtesting/bt_controller.py +++ b/openbb_terminal/stocks/backtesting/bt_controller.py @@ -63,15 +63,16 @@ class BacktestingController(StockBaseController): def print_help(self): """Print help""" mt = MenuText("stocks/bt/") + mt.add_raw("") + mt.add_param("_ticker", self.ticker.upper() or "No Ticker Loaded") mt.add_raw("\n") - mt.add_param("_ticker", self.ticker.upper()) mt.add_cmd("load") mt.add_raw("\n") - mt.add_cmd("whatif") + mt.add_cmd("whatif", self.ticker) mt.add_raw("\n") - mt.add_cmd("ema") - mt.add_cmd("emacross") - mt.add_cmd("rsi") + mt.add_cmd("ema", self.ticker) + mt.add_cmd("emacross", self.ticker) + mt.add_cmd("rsi", self.ticker) console.print(text=mt.menu_text, menu="Stocks - Backtesting") def custom_reset(self): diff --git a/openbb_terminal/stocks/comparison_analysis/ca_controller.py b/openbb_terminal/stocks/comparison_analysis/ca_controller.py index 5c6fee46e10..57de3392c4a 100644 --- a/openbb_terminal/stocks/comparison_analysis/ca_controller.py +++ b/openbb_terminal/stocks/comparison_analysis/ca_controller.py @@ -346,7 +346,8 @@ class ComparisonAnalysisController(BaseController): ) else: console.print( - "You need to 'set' a ticker to get similar companies from first!" + |