summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Aptekarev <aptekarev@gmail.com>2021-09-27 01:05:17 +0300
committerTheodore Aptekarev <aptekarev@gmail.com>2021-09-27 01:05:17 +0300
commit0aced707dbc1671bb21e7cd947492c6c5888ea6f (patch)
tree9ed6e74b34af44aaa791e0762c8c5033f5ce9d63
parent3df860c1bf498d2b9d09934d0b395186c54c7376 (diff)
parentb60e34a0f0407840c71ea79312e5f646bc36de9d (diff)
Merge remote-tracking branch 'upstream/main' into jupyter-kernel
-rw-r--r--README.md2
-rw-r--r--gamestonk_terminal/common/newsapi_view.py16
-rw-r--r--gamestonk_terminal/config_terminal.py6
-rw-r--r--gamestonk_terminal/cryptocurrency/onchain/onchain_controller.py105
-rw-r--r--gamestonk_terminal/cryptocurrency/onchain/whale_alert_model.py124
-rw-r--r--gamestonk_terminal/cryptocurrency/onchain/whale_alert_view.py69
-rw-r--r--gamestonk_terminal/portfolio/brokers/bro_controller.py13
-rw-r--r--gamestonk_terminal/portfolio/portfolio_controller.py1
-rw-r--r--gamestonk_terminal/resources/resources_controller.py7
-rw-r--r--gamestonk_terminal/stocks/README.md17
-rw-r--r--gamestonk_terminal/stocks/due_diligence/README.md15
-rw-r--r--gamestonk_terminal/stocks/fundamental_analysis/eclect_us_model.py48
-rw-r--r--gamestonk_terminal/stocks/fundamental_analysis/eclect_us_view.py24
-rw-r--r--gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py21
-rw-r--r--gamestonk_terminal/stocks/stocks_controller.py13
-rw-r--r--images/gst_logo_green_white_background.pngbin0 -> 180500 bytes
-rw-r--r--website/content/cryptocurrency/onchain/whales/_index.md23
-rwxr-xr-xwebsite/content/stocks/fundamental_analysis/analysis/_index.md10
-rwxr-xr-xwebsite/content/stocks/news/_index.md7
-rwxr-xr-xwebsite/data/menu/main.yml2
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