Merge branch 'main' into ca

This commit is contained in:
DidierRLopes
2021-03-10 21:53:33 +00:00
committed by GitHub
13 changed files with 235 additions and 68 deletions

View File

@@ -21,92 +21,78 @@
## Discovery
### Short term
* Add Cathy's ARK trading activity (@aia)
* Top Losers (@didier)
### Medium term
* Add screeners (@didier)
### Long term
* Add screeners (@didier)
## Behavioral Analysis
### Short term
* Implement a better Twitter client (@aia)
### Medium term:
* Add Stocktwits (@aia)
### Long term
* Add Stocktwits (@aia)
## Sell-side Equity Research
### Short term
### Medium term
### Long term
## Fundamental Analysis
### Short term
* Multi-ticker comparison (@didier)
### Medium term
* Rearrange FA menu to have AV and FMP as submenus (@didier)
### Long term
## Technical Analysis
### Short term
### Medium term
* Add auto-recognition of major TA patterns (@didier)
### Long term
## Due Diligence
### Short term
### Medium term
### Long term
## Prediction Techniques
### Short term
* Implement several exponential smoothing methods (@didier)
### Medium term
### Long term
### Reports
## Reports
### Short term
* Expand Due Diligence report
* Add multi-ticker comparison report
### Medium term
### Long term
## Portfolio Analysis
### Short term
### Medium term
### Long term
## Credit Analysis
### Short term
### Medium term
### Long term
## Cryptocurrencies
### Short term
### Medium term
### Long term
## Backend
### Short term
### Medium term
### Long term
* Add caching
* APIs
### Long term
* GraphQL
## Frontend
### Short term
### Medium term
### Long term
## Developer Experience
@@ -114,13 +100,10 @@
### Short term
* Add Windows CI (@aia)
* Write a developer guide
### Medium term
### Long term
## User Experience
### Short term
### Medium term
* Add a WHL installation
### Long term
* Add a WHL installation

View File

@@ -10,6 +10,8 @@ This menu aims to discover new stocks, and the usage of the following commands a
* show latest top gainers [Yahoo Finance]
* [orders](#orders)
* orders by Fidelity Customers [Fidelity]
* [ark_orders](#ark_orders)
* orders by ARK Investment Management LLC [https://cathiesark.com]
* [up_earnings](#up_earnings)
* upcoming earnings release dates [Seeking Alpha]
* [high_short](#high_short)
@@ -70,6 +72,19 @@ Orders by Fidelity customers. Information shown in the table below is based on t
<img width="945" alt="Captura de ecrã 2021-02-20, às 11 45 43" src="https://user-images.githubusercontent.com/25267873/108594318-45886f00-7371-11eb-919f-fd1bce6d4001.png">
## ark_orders <a name="ark_orders"></a>
```shell
usage: ark_orders [-n N_NUM]
```
Orders by ARK Investment Management LLC - https://ark-funds.com/. [Source: https://cathiesark.com]
* -n : Last N orders to be printed. Default 20.
<img width="957" alt="Captura de ecrã 2021-03-10, às 21 36 38" src="https://user-images.githubusercontent.com/25267873/110701322-ef2c8480-81e8-11eb-85a2-7ebfa3fa0680.png">
## up_earnings <a name="up_earnings"></a>
```shell

View File

@@ -0,0 +1,133 @@
import argparse
from datetime import timedelta
import json
import requests
from colorama import Fore, Style
from bs4 import BeautifulSoup
import numpy as np
import pandas as pd
from pandas.core.frame import DataFrame
import yfinance as yf
from gamestonk_terminal.helper_funcs import (
check_positive,
get_user_agent,
patch_pandas_text_adjustment,
parse_known_args_and_warn,
)
from gamestonk_terminal.config_terminal import USE_COLOR
def direction_color_red_green(val: str) -> str:
if val == "Buy":
ret = Fore.GREEN + val + Style.RESET_ALL
elif val == "Sell":
ret = Fore.RED + val + Style.RESET_ALL
else:
ret = val
return ret
def get_ark_orders() -> DataFrame:
url_orders = "https://cathiesark.com/ark-funds-combined/trades"
raw_page = requests.get(url_orders, headers={"User-Agent": get_user_agent()}).text
parsed_script = BeautifulSoup(raw_page, "lxml").find(
"script", {"id": "__NEXT_DATA__"}
)
parsed_json = json.loads(parsed_script.string)
df_orders = pd.json_normalize(parsed_json["props"]["pageProps"]["arkTrades"])
df_orders.drop(
[
"everything",
"everything.profile.customThumbnail",
"hidden",
"images.thumbnail",
],
axis=1,
inplace=True,
)
df_orders["date"] = pd.to_datetime(df_orders["date"], format="%Y-%m-%dZ").dt.date
return df_orders
def add_order_total(df_orders: DataFrame) -> DataFrame:
start_date = df_orders["date"].iloc[-1] - timedelta(days=1)
tickers = " ".join(df_orders["ticker"].unique())
print("")
prices = yf.download(tickers, start=start_date, progress=False)
for i, candle in enumerate(["Volume", "Open", "Close", "High", "Low", "Total"]):
df_orders.insert(i + 3, candle.lower(), 0)
for i, _ in df_orders.iterrows():
if np.isnan(
prices["Open"][df_orders.loc[i, "ticker"]][
df_orders.loc[i, "date"].strftime("%Y-%m-%d")
]
):
for candle in ["Volume", "Open", "Close", "High", "Low", "Total"]:
df_orders.loc[i, candle.lower()] = 0
continue
for candle in ["Volume", "Open", "Close", "High", "Low"]:
df_orders.loc[i, candle.lower()] = prices[candle][
df_orders.loc[i, "ticker"]
][df_orders.loc[i, "date"].strftime("%Y-%m-%d")]
df_orders.loc[i, "total"] = (
df_orders.loc[i, "close"] * df_orders.loc[i, "shares"]
)
return df_orders
def ark_orders(l_args):
parser = argparse.ArgumentParser(
prog="ARK Orders",
description="""
Orders by ARK Investment Management LLC - https://ark-funds.com/. [Source: https://cathiesark.com]
""",
)
parser.add_argument(
"-n",
"--num",
action="store",
dest="n_num",
type=check_positive,
default=20,
help="Last N orders.",
)
ns_parser = parse_known_args_and_warn(parser, l_args)
df_orders = get_ark_orders()
pd.set_option("mode.chained_assignment", None)
df_orders = add_order_total(df_orders.head(ns_parser.n_num))
if USE_COLOR:
df_orders["direction"] = df_orders["direction"].apply(direction_color_red_green)
patch_pandas_text_adjustment()
df_orders["link"] = "https://finviz.com/quote.ashx?t=" + df_orders["ticker"]
pd.set_option("display.max_colwidth", None)
pd.set_option("display.max_rows", None)
pd.set_option("display.float_format", "{:,.2f}".format)
print("")
print("Orders by ARK Investment Management LLC")
print("")
print(df_orders.to_string(index=False))
print("")

View File

@@ -5,12 +5,16 @@ from gamestonk_terminal.discovery import finviz_api
from gamestonk_terminal.discovery import short_interest_api
from gamestonk_terminal.discovery import seeking_alpha_api
from gamestonk_terminal.discovery import fidelity_api
from gamestonk_terminal.discovery import ark_api
from gamestonk_terminal.discovery import simply_wallst_api
from gamestonk_terminal.discovery import spachero_api
from gamestonk_terminal.discovery import unusual_whales_api
from gamestonk_terminal.helper_funcs import get_flair
from gamestonk_terminal.menu import session
from prompt_toolkit.completion import WordCompleter
def print_discovery():
""" Print help """
@@ -24,6 +28,7 @@ def print_discovery():
print(" sectors show sectors performance [Alpha Vantage]")
print(" gainers show latest top gainers [Yahoo Finance]")
print(" orders orders by Fidelity Customers [Fidelity]")
print(" ark_orders orders by ARK Investment Management LLC")
print(" up_earnings upcoming earnings release dates [Seeking Alpha]")
print(
" high_short show top high short interest stocks of over 20% ratio [www.highshortinterest.com]"
@@ -42,33 +47,36 @@ def disc_menu():
# Add list of arguments that the discovery parser accepts
disc_parser = argparse.ArgumentParser(prog="discovery", add_help=False)
disc_parser.add_argument(
"cmd",
choices=[
"help",
"q",
"quit",
"map",
"sectors",
"gainers",
"spacs",
"orders",
"spachero",
"high_short",
"low_float",
"up_earnings",
"simply_wallst",
"uwhales",
"mill",
],
)
choices = [
"help",
"q",
"quit",
"map",
"sectors",
"gainers",
"spacs",
"orders",
"ark_orders",
"spachero",
"high_short",
"low_float",
"up_earnings",
"simply_wallst",
"uwhales",
"mill",
]
disc_parser.add_argument("cmd", choices=choices)
word_completer = WordCompleter(choices)
print_discovery()
# Loop forever and ever
while True:
# Get input command from user
as_input = input(f"{get_flair()} (disc)> ")
as_input = session.prompt(
f"{get_flair()} (disc)> ",
completer=word_completer,
)
# Parse fundamental analysis command of the list of possible commands
try:
@@ -107,6 +115,9 @@ def disc_menu():
elif ns_known_args.cmd == "orders":
fidelity_api.orders(l_args)
elif ns_known_args.cmd == "ark_orders":
ark_api.ark_orders(l_args)
elif ns_known_args.cmd == "simply_wallst":
simply_wallst_api.simply_wallst(l_args)

View File

@@ -0,0 +1,7 @@
import os
from prompt_toolkit import PromptSession
from prompt_toolkit.history import FileHistory
history_file = os.path.join(os.path.expanduser("~"), ".gamestonk_terminal.his")
session = PromptSession(history=FileHistory(history_file))

View File

@@ -308,7 +308,7 @@ def popular_tickers(l_args):
n_top_stocks += 1
except HTTPError as e:
if e.response.status_code != 404:
print(f"Unexpected exception from Fiviz: {e}")
print(f"Unexpected exception from Finviz: {e}")
except Exception as e:
print(e)

View File

@@ -102,7 +102,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
"version": "3.8.8"
}
},
"nbformat": 4,

View File

@@ -156,3 +156,4 @@ wrapt==1.12.1; python_version >= "3.6" and python_full_version < "3.0.0" or pyth
yarl==1.6.3; python_version >= "3.6"
yfinance==0.1.55
zipp==3.4.1; python_version < "3.8" and python_version >= "3.6"
prompt-toolkit==3.0.16; python_version >= "3.6"

View File

@@ -133,3 +133,4 @@ wrapt==1.12.1; python_version >= "3.6" and python_full_version < "3.0.0" or pyth
yarl==1.6.3; python_version >= "3.6"
yfinance==0.1.55
zipp==3.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_full_version >= "3.2.0" and python_version >= "3.6" and python_version < "3.8"
prompt-toolkit==3.0.16; python_version >= "3.6"

View File

@@ -133,3 +133,4 @@ wrapt==1.12.1; python_version >= "3.6" and python_full_version < "3.0.0" or pyth
yarl==1.6.3; python_version >= "3.6"
yfinance==0.1.55
zipp==3.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_full_version >= "3.2.0" and python_version >= "3.6" and python_version < "3.8"
prompt-toolkit==3.0.16; python_version >= "3.6"

View File

@@ -90,3 +90,4 @@ websocket-client==0.58.0; python_version >= "3.6" and python_full_version < "3.0
yarl==1.6.3; python_version >= "3.6"
yfinance==0.1.55
zipp==3.4.1; python_version < "3.8" and python_version >= "3.6"
prompt-toolkit==3.0.16; python_version >= "3.6"

View File

@@ -16,6 +16,9 @@ from gamestonk_terminal.papermill import papermill_menu as mill
from gamestonk_terminal.comparison_analysis import ca_menu as cam
from gamestonk_terminal import res_menu as rm
from gamestonk_terminal import config_terminal as cfg
from gamestonk_terminal.menu import session
from prompt_toolkit.completion import WordCompleter
# import warnings
# warnings.simplefilter("always")
@@ -43,27 +46,25 @@ def main():
# Add list of arguments that the main parser accepts
menu_parser = argparse.ArgumentParser(prog="gamestonk_terminal", add_help=False)
menu_parser.add_argument(
"opt",
choices=[
"help",
"quit",
"q",
"clear",
"load",
"view",
"export",
"disc",
"mill",
"sen",
"res",
"ca",
"fa",
"ta",
"dd",
"pred",
],
)
choices = [
"help",
"quit",
"q",
"clear",
"load",
"view",
"export",
"disc",
"mill",
"sen",
"res",
"fa",
"ta",
"dd",
"pred",
]
menu_parser.add_argument("opt", choices=choices)
word_completer = WordCompleter(choices)
# Print first welcome message and help
print("\nWelcome to Gamestonk Terminal 🚀\n")
@@ -77,7 +78,10 @@ def main():
should_print_help = False
# Get input command from user
as_input = input(f"{get_flair()}> ")
as_input = session.prompt(
f"{get_flair()}> ",
completer=word_completer,
)
# Is command empty
if not as_input:

View File

@@ -0,0 +1,10 @@
import unittest
from gamestonk_terminal.discovery.ark_api import (
ark_orders,
)
class TestDiscoveryArkApi(unittest.TestCase):
def test_ark_orders(self):
ark_orders(["-n", "2"])