diff options
author | Theodore Aptekarev <aptekarev@gmail.com> | 2021-09-27 01:05:17 +0300 |
---|---|---|
committer | Theodore Aptekarev <aptekarev@gmail.com> | 2021-09-27 01:05:17 +0300 |
commit | 0aced707dbc1671bb21e7cd947492c6c5888ea6f (patch) | |
tree | 9ed6e74b34af44aaa791e0762c8c5033f5ce9d63 | |
parent | 3df860c1bf498d2b9d09934d0b395186c54c7376 (diff) | |
parent | b60e34a0f0407840c71ea79312e5f646bc36de9d (diff) |
Merge remote-tracking branch 'upstream/main' into jupyter-kernel
20 files changed, 490 insertions, 33 deletions
diff --git a/README.md b/README.md index 2461ee21146..c756c32378f 100644 --- a/README.md +++ b/README.md @@ -267,6 +267,7 @@ These are the ones where a key is necessary: * Tradier: https://developer.tradier.com/getting_started * Twitter: https://developer.twitter.com * Coinbase Pro API: https://docs.pro.coinbase.com/ +* Whale Alert API: https://docs.whale-alert.io/ When these are obtained, don't forget to update [config_terminal.py](/gamestonk_terminal/config_terminal.py). @@ -290,6 +291,7 @@ Alternatively, you can also set them to the following environment variables: | [Tradier](https://developer.tradier.com) | GT_TRADIER_TOKEN | | [Twitter](https://developer.twitter.com) | GT_API_TWITTER_KEY <br/> GT_API_TWITTER_SECRET_KEY <br/> GT_API_TWITTER_BEARER_TOKEN | | [Coinbase](https://docs.pro.coinbase.com/) | GT_API_COINBASE_KEY <br/> GT_API_COINBASE_SECRET <br/> GT_API_COINBASE_PASS_PHRASE | +| [Whale Alert](https://docs.whale-alert.io/) | GT_API_WHALE_ALERT_KEY | Example: ``` diff --git a/gamestonk_terminal/common/newsapi_view.py b/gamestonk_terminal/common/newsapi_view.py index 64f04b09ee8..a51f2e7daee 100644 --- a/gamestonk_terminal/common/newsapi_view.py +++ b/gamestonk_terminal/common/newsapi_view.py @@ -11,6 +11,7 @@ def news( num: int, s_from: str, show_newest: bool, + sources: str, ): """Display news for a given title. [Source: NewsAPI] @@ -24,14 +25,19 @@ def news( date to start searching articles from formatted YYYY-MM-DD show_newest: bool flag to show newest articles first + sources: str + sources to exclusively show news from """ - # TODO: Add argument to specify news source being used - - response = requests.get( - f"https://newsapi.org/v2/everything?q={term}&from={s_from}" - f"&sortBy=publishedAt&language=en&apiKey={cfg.API_NEWS_TOKEN}", + link = ( + f"https://newsapi.org/v2/everything?q={term}&from={s_from}&sortBy=publishedAt&language=en" + f"&apiKey={cfg.API_NEWS_TOKEN}" ) + if sources: + link += f"&domains={sources}" + + response = requests.get(link) + # Check that the API response was successful if response.status_code == 426: print(f"Error in request: {response.json()['message']}", "\n") diff --git a/gamestonk_terminal/config_terminal.py b/gamestonk_terminal/config_terminal.py index b81493537f8..832b54718e1 100644 --- a/gamestonk_terminal/config_terminal.py +++ b/gamestonk_terminal/config_terminal.py @@ -90,3 +90,9 @@ API_SENTIMENTINVESTOR_TOKEN = ( API_COINBASE_KEY = os.getenv("GT_API_COINBASE_KEY") or "REPLACE_ME" API_COINBASE_SECRET = os.getenv("GT_API_COINBASE_SECRET") or "REPLACE_ME" API_COINBASE_PASS_PHRASE = os.getenv("GT_API_COINBASE_PASS_PHRASE") or "REPLACE_ME" + +# https://alpaca.markets/docs/api-documentation/api-v2/ +# GT_APCA_API_BASE_URL, GT_APCA_API_KEY_ID and GT_APCA_API_SECRET_KEY need to be set as env variable + +# https://docs.whale-alert.io/ +API_WHALE_ALERT_KEY = os.getenv("GT_API_WHALE_ALERT_KEY") or "REPLACE_ME" diff --git a/gamestonk_terminal/cryptocurrency/onchain/onchain_controller.py b/gamestonk_terminal/cryptocurrency/onchain/onchain_controller.py index 547e890323c..f1a4fae3b76 100644 --- a/gamestonk_terminal/cryptocurrency/onchain/onchain_controller.py +++ b/gamestonk_terminal/cryptocurrency/onchain/onchain_controller.py @@ -8,9 +8,14 @@ from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.menu import session -from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn +from gamestonk_terminal.helper_funcs import ( + get_flair, + parse_known_args_and_warn, + check_positive, + check_int_range, +) -from gamestonk_terminal.cryptocurrency.onchain import gasnow_view +from gamestonk_terminal.cryptocurrency.onchain import gasnow_view, whale_alert_view # pylint: disable=R1732 @@ -26,9 +31,7 @@ class OnchainController: "quit", ] - CHOICES_COMMANDS = [ - "gwei", - ] + CHOICES_COMMANDS = ["gwei", "whales"] CHOICES += CHOICES_COMMANDS @@ -123,6 +126,97 @@ class OnchainController: except Exception as e: print(e, "\n") + def call_whales(self, other_args: List[str]): + """Process whales command""" + parser = argparse.ArgumentParser( + add_help=False, + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + prog="wales", + description=""" + Display crypto whales transactions. + [Source: https://docs.whale-alert.io/] + """, + ) + + parser.add_argument( + "-m", + "--min", + dest="min", + type=check_int_range(500000, 100 ** 7), + help="Minimum value of transactions.", + default=1000000, + ) + + parser.add_argument( + "-t", + "--top", + dest="top", + type=check_positive, + help="top N number records", + default=10, + ) + + parser.add_argument( + "-s", + "--sort", + dest="sortby", + type=str, + help="Sort by given column. Default: date", + default="date", + choices=[ + "date", + "symbol", + "blockchain", + "amount", + "amount_usd", + "from", + "to", + ], + ) + parser.add_argument( + "--descend", + action="store_false", + help="Flag to sort in descending order (lowest first)", + dest="descend", + default=True, + ) + + parser.add_argument( + "-a", + "--address", + dest="address", + action="store_true", + help="Flag to show addresses of transaction", + default=False, + ) + + parser.add_argument( + "--export", + choices=["csv", "json", "xlsx"], + default="", + type=str, + dest="export", + help="Export dataframe data to csv,json,xlsx file", + ) + + try: + ns_parser = parse_known_args_and_warn(parser, other_args) + + if not ns_parser: + return + + whale_alert_view.display_whales_transactions( + min_value=ns_parser.min, + top=ns_parser.top, + sortby=ns_parser.sortby, + descend=ns_parser.descend, + show_address=ns_parser.address, + export=ns_parser.export, + ) + + except Exception as e: + print(e) + def print_help(): """Print help""" @@ -133,6 +227,7 @@ def print_help(): print(" quit quit to abandon program") print("") print(" gwei check current eth gas fees") + print(" whales check crypto wales transactions") print("") diff --git a/gamestonk_terminal/cryptocurrency/onchain/whale_alert_model.py b/gamestonk_terminal/cryptocurrency/onchain/whale_alert_model.py new file mode 100644 index 00000000000..06554e95b65 --- /dev/null +++ b/gamestonk_terminal/cryptocurrency/onchain/whale_alert_model.py @@ -0,0 +1,124 @@ +"""Whale Alert model""" +__docformat__ = "numpy" + +from typing import Optional +import textwrap +import requests +import pandas as pd +import numpy as np +import gamestonk_terminal.config_terminal as cfg + + +class ApiKeyException(Exception): + """Api Key Exception object""" + + def __init__(self, message: str): + super().__init__(message) + self.message = message + + def __str__(self) -> str: + return "ApiKeyException: %s" % self.message + + +def make_request(params: Optional[dict] = None) -> dict: + """Helper methods for requests [Source: https://docs.whale-alert.io/] + + Parameters + ---------- + params: dict + additional param + + Returns + ------- + dict: + response from api request + """ + + api_key = cfg.API_WHALE_ALERT_KEY or "" + url = "https://api.whale-alert.io/v1/transactions?api_key=" + api_key + response = requests.get(url, params=params) + + if not 200 <= response.status_code < 300: + raise ApiKeyException("Invalid Authentication: %s" % response.text) + try: + return response.json() + except Exception as e: + raise ValueError("Invalid Response: %s" % response.text) from e + + +def get_whales_transactions(min_value: int = 800000, limit: int = 100) -> pd.DataFrame: + """Whale Alert's API allows you to retrieve live and historical transaction data from major blockchains. + Supported blockchain: Bitcoin, Ethereum, Ripple, NEO, EOS, Stellar and Tron. [Source: https://docs.whale-alert.io/] + + Parameters + ---------- + min_value: int + Minimum value of trade to track. + limit: int + Limit of transactions. Max 100 + + Returns + ------- + pd.DataFrame + Crypto wales transactions + """ + + min_value = 800000 if min_value > 800000 else min_value + limit = 100 if limit > 100 else limit + + params = {"limit": limit, "min_value": min_value} + + response = make_request(params) + data = pd.json_normalize(response["transactions"]).sort_values( + "timestamp", ascending=False + ) + + data["date"] = pd.to_datetime(data["timestamp"], unit="s") + data.columns = [col.replace(".address", "") for col in data.columns] + data["to_address"] = data["to"].apply( + lambda x: "\n".join(textwrap.wrap(x, width=45)) if isinstance(x, str) else x + ) + data["from_address"] = data["from"].apply( + lambda x: "\n".join(textwrap.wrap(x, width=45)) if isinstance(x, str) else x + ) + + data["from"] = data.apply( + lambda x: x["from.owner"] + if x["from.owner"] not in [np.nan, None, np.NaN] + else x["from.owner_type"], + axis=1, + ) + data["to"] = data.apply( + lambda x: x["to.owner"] + if x["to.owner"] not in [np.nan, None, np.NaN] + else x["to.owner_type"], + axis=1, + ) + data.drop( + [ + "id", + "transaction_count", + "from.owner_type", + "to.owner_type", + "to.owner", + "from.owner", + "transaction_type", + "hash", + "timestamp", + ], + axis=1, + inplace=True, + ) + return data[ + [ + "date", + "symbol", + "blockchain", + "amount", + "amount_usd", + "from", + "to", + "from_address", + "to_address", + ] + ] diff --git a/gamestonk_terminal/cryptocurrency/onchain/whale_alert_view.py b/gamestonk_terminal/cryptocurrency/onchain/whale_alert_view.py new file mode 100644 index 00000000000..8747a367ae4 --- /dev/null +++ b/gamestonk_terminal/cryptocurrency/onchain/whale_alert_view.py @@ -0,0 +1,69 @@ +"""Whale Alert view""" +__docformat__ = "numpy" + +import os +from tabulate import tabulate +from gamestonk_terminal.helper_funcs import export_data, long_number_format +from gamestonk_terminal import feature_flags as gtff +from gamestonk_terminal.cryptocurrency.onchain import whale_alert_model + + +def display_whales_transactions( + min_value: int = 800000, + top: int = 100, + sortby: str = "date", + descend: bool = False, + show_address: bool = False, + export: str = "", +) -> None: + """Display huge value transactions from major blockchains. [Source: https://docs.whale-alert.io/] + + Parameters + ---------- + min_value: int + Minimum value of trade to track. + top: int + Limit of transactions. Maximum 100 + sortby: str + Key to sort by. + descend: str + Sort in descending order. + show_address: bool + Flag to show addresses of transactions. + export : str + Export dataframe data to csv,json,xlsx file + """ + + df = whale_alert_model.get_whales_transactions(min_value) + df_data = df.copy() + + df = df.sort_values(by=sortby, ascending=descend) + + if not show_address: + df = df.drop(["from_address", "to_address"], axis=1) + else: + df = df.drop(["from", "to", "blockchain"], axis=1) + + for col in ["amount_usd", "amount"]: + df[col] = df[col].apply(lambda x: long_number_format(x)) + + if gtff.USE_TABULATE_DF: + print( + tabulate( + df.head(top), + headers=df.columns, + floatfmt=".0f", + showindex=False, + tablefmt="fancy_grid", + ), + "\n", + ) + else: + print(df.to_string, "\n") + + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "whales", + df_data, + ) diff --git a/gamestonk_terminal/portfolio/brokers/bro_controller.py b/gamestonk_terminal/portfolio/brokers/bro_controller.py index 066c0a340b3..f6851bc880c 100644 --- a/gamestonk_terminal/portfolio/brokers/bro_controller.py +++ b/gamestonk_terminal/portfolio/brokers/bro_controller.py @@ -36,6 +36,7 @@ class BrokersController: """Print help""" help_string = """ >>BROKERS<< + What would you like to do? cls clear screen ?/help show this menu again @@ -43,13 +44,13 @@ What would you like to do? quit quit to abandon program, logs out of brokers Brokers: - >ally Ally Invest Menu - >alpaca Alpaca Menu - >degiro Degiro Menu - >rh Robinhood Menu +> ally Ally Invest Menu +> alpaca Alpaca Menu +> degiro Degiro Menu +> rh Robinhood Menu Crypto Brokers: - >cb Coinbase Pro Menu +> cb Coinbase Pro Menu """ print(help_string) @@ -164,7 +165,7 @@ def menu(): "does not take advantage of your data.\n" " - HOWEVER, our project imports almost 200 different open source python modules. Therefore, it " "is impossible for us to check the coding standards and security of each of these modules. " - "Hence why adding this disclaimer here.\n" + "Hence why adding this disclaimer here." ) bro_controller.print_help() diff --git a/gamestonk_terminal/portfolio/portfolio_controller.py b/gamestonk_terminal/portfolio/portfolio_controller.py index 5475d586ef8..4a5a7045177 100644 --- a/gamestonk_terminal/portfolio/portfolio_controller.py +++ b/gamestonk_terminal/portfolio/portfolio_controller.py @@ -49,7 +49,6 @@ class PortfolioController: def print_help(self): """Print help""" help_text = """ - >> PORTFOLIO << What do you want to do? diff --git a/gamestonk_terminal/resources/resources_controller.py b/gamestonk_terminal/resources/resources_controller.py index 5d57f18c7f9..d556cb83de0 100644 --- a/gamestonk_terminal/resources/resources_controller.py +++ b/gamestonk_terminal/resources/resources_controller.py @@ -31,6 +31,7 @@ class ResourceCollectionController: "edgar", "fred", "learn", + "econiverse", ] CHOICES += CHOICES_COMMANDS @@ -61,6 +62,7 @@ What do you want to do? edgar online public database from SEC fred economic research data learn trading analysis, tips and resources + econiverse compilation of free knowledge and educational resources """ print(help_str) @@ -141,6 +143,11 @@ What do you want to do? webbrowser.open("https://moongangcapital.com/free-stock-market-resources/") print("") + def call_econiverse(self, _): + """Process econiverse command""" + webbrowser.open("https://econiverse.github.io") + print("") + def menu(): """Resource Collection Menu""" diff --git a/gamestonk_terminal/stocks/README.md b/gamestonk_terminal/stocks/README.md index 34a8ed31cab..819fa8617a3 100644 --- a/gamestonk_terminal/stocks/README.md +++ b/gamestonk_terminal/stocks/README.md @@ -4,6 +4,7 @@ * [Load](#Load) * [Quote](#Quote) * [Candle](#Candle) + * [News](#News) * [Discover Stocks](#Discover-Stocks-) * [Behavioural Analysis](#Behavioural-Analysis-) * [Research](#Research-) @@ -49,6 +50,22 @@ Visualize candles historical data, with support and resistance bars, and moving ![nio](https://user-images.githubusercontent.com/25267873/111053397-4d609e00-845b-11eb-9c94-89b8892a8e81.png) +#### News + +```text +news [-n N_NUM] [-d N_START_DATE] [-o] [-s N_SOURCES [N_SOURCES ...]] +``` + +Prints latest news about company, including date, title and web link. [Source: News API] + +* -n : Number of latest news being printed. Default 5. +* -d : The starting date (format YYYY-MM-DD) to search articles from. +* -o : Show oldest articles first. +* -s : Show news only from the sources specified (e.g bbc yahoo.com) + +<img width="770" alt="Captura de ecrã 2021-03-22, às 22 47 42" src="https://user-images.githubusercontent.com/25267873/112070935-b2587a00-8b66-11eb-8dfb-0353fc83311d.png"> + + ## [Discover Stocks »»](discovery/README.md) Command|Description|Source diff --git a/gamestonk_terminal/stocks/due_diligence/README.md b/gamestonk_terminal/stocks/due_diligence/README.md index 40d9fb36e89..c1b13345d60 100644 --- a/gamestonk_terminal/stocks/due_diligence/README.md +++ b/gamestonk_terminal/stocks/due_diligence/README.md @@ -2,8 +2,6 @@ This menu aims to help in due-diligence of a pre-loaded stock, and the usage of the following commands along with an example will be exploited below. -* [news](#news) - * latest news of the company [News API] * [red](#red) * gets due diligence from another user's post [Reddit] * [analyst](#analyst) @@ -39,19 +37,6 @@ This menu aims to help in due-diligence of a pre-loaded stock, and the usage of * [customer](#customer) * list of customers [csimarket] -## news <a name="news"></a> - -```text -news [-n N_NUM] -``` - -Prints latest news about company, including date, title and web link. [Source: News API] - -* -n : Number of latest news being printed. Default 10. - -<img width="770" alt="Captura de ecrã 2021-03-22, às 22 47 42" src="https://user-images.githubusercontent.com/25267873/112070935-b2587a00-8b66-11eb-8dfb-0353fc83311d.png"> - - ## red <a name="red"></a> ```text diff --git a/gamestonk_terminal/stocks/fundamental_analysis/eclect_us_model.py b/gamestonk_terminal/stocks/fundamental_analysis/eclect_us_model.py new file mode 100644 index 00000000000..d462867cf78 --- /dev/null +++ b/gamestonk_terminal/stocks/fundamental_analysis/eclect_us_model.py @@ -0,0 +1,48 @@ +"""Eclect.us model""" +__docformat__ = "numpy" + +import requests +from colorama import Style + +# pylint: disable=R1718 + + +def get_filings_analysis(ticker: str) -> str: + """Save time reading SEC filings with the help of machine learning. [Source: https://eclect.us] + + Parameters + ---------- + ticker: str + Ticker to see analysis of filings + + Returns + ------- + str + Analysis of filings text + """ + result = requests.get(f"https://api.eclect.us/symbol/{ticker.lower()}?page=1") + + if result.status_code == 200: + if result.json(): + rf_highlights = f"{Style.BRIGHT}\n\tRISK FACTORS:{Style.RESET_ALL}\n" + rf_highlights_txt = "\n\n".join( + {sentence["sentence"] for sentence in result.json()[0]["rf_highlights"]} + ) + + daa_highlights = ( + f"{Style.BRIGHT}\n\tDISCUSSION AND ANALYSIS:{Style.RESET_ALL}\n" + ) + daa_highlights += "\n\n".join( + { + sentence["sentence"] + for sentence in result.json()[0]["daa_highlights"] + } + ) + + return ( + rf_highlights + rf_highlights_txt + "\n" + daa_highlights + if rf_highlights_txt + else daa_highlights + ) + + return "" diff --git a/gamestonk_terminal/stocks/fundamental_analysis/eclect_us_view.py b/gamestonk_terminal/stocks/fundamental_analysis/eclect_us_view.py new file mode 100644 index 00000000000..a67570ad920 --- /dev/null +++ b/gamestonk_terminal/stocks/fundamental_analysis/eclect_us_view.py @@ -0,0 +1,24 @@ +"""Eclect.us view""" +__docformat__ = "numpy" + +from gamestonk_terminal.stocks.fundamental_analysis import eclect_us_model + + +def display_analysis( + ticker: str, +) -> None: + """Display analysis of SEC filings based on NLP model. [Source: https://eclect.us] + + Parameters + ---------- + ticker: str + Ticker to do SEC filings analysis from + """ + + analysis = eclect_us_model.get_filings_analysis(ticker) + + if analysis: + print(analysis) + else: + print("No SEC filings analysis found for this ticker") + print("") diff --git a/gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py b/gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py index 80fdda20e70..ed58366de0b 100644 --- a/gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py +++ b/gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py @@ -11,6 +11,7 @@ from gamestonk_terminal.stocks.fundamental_analysis.financial_modeling_prep impo fmp_view, ) from gamestonk_terminal.stocks.fundament |