mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 21:12:16 +00:00
Merge branch 'main' into ca
This commit is contained in:
29
ROADMAP.md
29
ROADMAP.md
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
133
gamestonk_terminal/discovery/ark_api.py
Normal file
133
gamestonk_terminal/discovery/ark_api.py
Normal 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("")
|
||||
@@ -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)
|
||||
|
||||
|
||||
7
gamestonk_terminal/menu.py
Normal file
7
gamestonk_terminal/menu.py
Normal 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))
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.5"
|
||||
"version": "3.8.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
48
terminal.py
48
terminal.py
@@ -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:
|
||||
|
||||
10
tests/test_discovery_ark_api.py
Normal file
10
tests/test_discovery_ark_api.py
Normal 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"])
|
||||
Reference in New Issue
Block a user