mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 20:42:26 +00:00
Improve some of the DPS commands based on user review (#700)
* fix dps/psi quandl source * improve dps/prom * improve ats/otc based on user request * remove unused file
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
""" Disc Controller """
|
||||
""" Dark Pool Shorts Controller """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import argparse
|
||||
@@ -266,12 +266,33 @@ Quandl/Stockgrid:
|
||||
default=5,
|
||||
help="List of tickers from most promising with better linear regression slope.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--tier",
|
||||
action="store",
|
||||
dest="tier",
|
||||
type=str,
|
||||
choices=["T1", "T2", "OTCE"],
|
||||
default="",
|
||||
help="Tier to process data from.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
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
|
||||
|
||||
finra_view.darkpool_otc(num=ns_parser.n_num, promising=ns_parser.n_top)
|
||||
finra_view.darkpool_otc(
|
||||
num=ns_parser.n_num,
|
||||
promising=ns_parser.n_top,
|
||||
tier=ns_parser.tier,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e, "\n")
|
||||
@@ -387,6 +408,13 @@ Quandl/Stockgrid:
|
||||
prog="dpotc",
|
||||
description="Display barchart of dark pool (ATS) and OTC (Non ATS) data. [Source: FINRA]",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
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:
|
||||
@@ -395,7 +423,10 @@ Quandl/Stockgrid:
|
||||
print("No ticker loaded.\n")
|
||||
return
|
||||
|
||||
finra_view.darkpool_ats_otc(ticker=self.ticker)
|
||||
finra_view.darkpool_ats_otc(
|
||||
ticker=self.ticker,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e, "\n")
|
||||
@@ -546,7 +577,7 @@ Quandl/Stockgrid:
|
||||
action="store",
|
||||
dest="n_days",
|
||||
type=check_positive,
|
||||
default=10,
|
||||
default=10 if "-r" in other_args else 120,
|
||||
help="Number of latest days to print data.",
|
||||
)
|
||||
else:
|
||||
@@ -558,13 +589,13 @@ Quandl/Stockgrid:
|
||||
default=10 if "-r" in other_args else 120,
|
||||
dest="num",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Flag to print raw data instead",
|
||||
dest="raw",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Flag to print raw data instead",
|
||||
dest="raw",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
@@ -583,9 +614,9 @@ Quandl/Stockgrid:
|
||||
if "quandl" in other_args:
|
||||
quandl_view.short_interest(
|
||||
ticker=self.ticker,
|
||||
start=self.start,
|
||||
nyse=ns_parser.b_nyse,
|
||||
days=ns_parser.n_days,
|
||||
raw=ns_parser.raw,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
else:
|
||||
|
||||
@@ -199,13 +199,15 @@ def getFINRAdata(
|
||||
)
|
||||
|
||||
|
||||
def getATSdata(num_tickers_to_filter: int) -> Tuple[pd.DataFrame, Dict]:
|
||||
def getATSdata(num_tickers_to_filter: int, tier_ats: str) -> Tuple[pd.DataFrame, Dict]:
|
||||
"""Get all FINRA ATS data, and parse most promising tickers based on linear regression
|
||||
|
||||
Parameters
|
||||
----------
|
||||
num_tickers_to_filter : int
|
||||
Number of tickers to filter from entire ATS data based on the sum of the total weekly shares quantity
|
||||
tier_ats : int
|
||||
Tier to process data from
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -214,7 +216,10 @@ def getATSdata(num_tickers_to_filter: int) -> Tuple[pd.DataFrame, Dict]:
|
||||
Dict
|
||||
Tickers from Dark Pools with better regression slope
|
||||
"""
|
||||
tiers = ["T1", "T2", "OTCE"]
|
||||
if tier_ats:
|
||||
tiers = [tier_ats]
|
||||
else:
|
||||
tiers = ["T1", "T2", "OTCE"]
|
||||
df_ats = pd.DataFrame()
|
||||
|
||||
for tier in tiers:
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
""" FINRA View """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import os
|
||||
from typing import List
|
||||
import pandas as pd
|
||||
from matplotlib import pyplot as plt
|
||||
import matplotlib.dates as mdates
|
||||
from gamestonk_terminal.stocks.dark_pool_shorts import finra_model
|
||||
from gamestonk_terminal.config_plot import PLOT_DPI
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.helper_funcs import plot_autoscale
|
||||
from gamestonk_terminal.helper_funcs import plot_autoscale, export_data
|
||||
|
||||
|
||||
def plot_dark_pools(ticker: str, ats: pd.DataFrame, otc: pd.DataFrame):
|
||||
@@ -83,6 +85,8 @@ def plot_dark_pools(ticker: str, ats: pd.DataFrame, otc: pd.DataFrame):
|
||||
plt.ylabel("Shares per Trade")
|
||||
plt.grid(b=True, which="major", color="#666666", linestyle="-", alpha=0.2)
|
||||
plt.gcf().autofmt_xdate()
|
||||
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%m/%d"))
|
||||
plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=4))
|
||||
plt.xlabel("Weeks")
|
||||
|
||||
if gtff.USE_ION:
|
||||
@@ -91,13 +95,15 @@ def plot_dark_pools(ticker: str, ats: pd.DataFrame, otc: pd.DataFrame):
|
||||
plt.show()
|
||||
|
||||
|
||||
def darkpool_ats_otc(ticker: str):
|
||||
"""Display barchart of dark pool (ATS) and OTC (Non ATS) data
|
||||
def darkpool_ats_otc(ticker: str, export: str):
|
||||
"""Display barchart of dark pool (ATS) and OTC (Non ATS) data. [Source: FINRA]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ticker : str
|
||||
Stock ticker
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
df_ats, df_otc = finra_model.getTickerFINRAdata(ticker)
|
||||
|
||||
@@ -107,6 +113,19 @@ def darkpool_ats_otc(ticker: str):
|
||||
plot_dark_pools(ticker, df_ats, df_otc)
|
||||
print("")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"dpotc_ats",
|
||||
df_ats,
|
||||
)
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"dpotc_otc",
|
||||
df_otc,
|
||||
)
|
||||
|
||||
|
||||
def plot_dark_pools_ats(ats: pd.DataFrame, top_ats_tickers: List):
|
||||
"""Plots promising tickers based on growing ATS data
|
||||
@@ -142,8 +161,8 @@ def plot_dark_pools_ats(ats: pd.DataFrame, top_ats_tickers: List):
|
||||
plt.show()
|
||||
|
||||
|
||||
def darkpool_otc(num: int, promising: int):
|
||||
"""Display dark pool (ATS) data of tickers with growing trades activity
|
||||
def darkpool_otc(num: int, promising: int, tier: str, export: str):
|
||||
"""Display dark pool (ATS) data of tickers with growing trades activity. [Source: FINRA]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@@ -153,8 +172,12 @@ def darkpool_otc(num: int, promising: int):
|
||||
promising : int
|
||||
Number of tickers to display from most promising with
|
||||
better linear regression slope
|
||||
tier : int
|
||||
Tier to process data from
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
df_ats, d_ats_reg = finra_model.getATSdata(num)
|
||||
df_ats, d_ats_reg = finra_model.getATSdata(num, tier)
|
||||
|
||||
top_ats_tickers = list(
|
||||
dict(sorted(d_ats_reg.items(), key=lambda item: item[1], reverse=True)).keys()
|
||||
@@ -162,3 +185,10 @@ def darkpool_otc(num: int, promising: int):
|
||||
|
||||
plot_dark_pools_ats(df_ats, top_ats_tickers)
|
||||
print("")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"prom",
|
||||
df_ats,
|
||||
)
|
||||
|
||||
@@ -5,6 +5,7 @@ import os
|
||||
import matplotlib.ticker
|
||||
from matplotlib import pyplot as plt
|
||||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
from gamestonk_terminal.stocks.dark_pool_shorts import quandl_model
|
||||
from gamestonk_terminal.helper_funcs import (
|
||||
long_number_format,
|
||||
@@ -12,9 +13,7 @@ from gamestonk_terminal.helper_funcs import (
|
||||
)
|
||||
|
||||
|
||||
def plot_short_interest(
|
||||
ticker: str, start: str, nyse: bool, days: int, df_short_interest: pd.DataFrame
|
||||
):
|
||||
def plot_short_interest(ticker: str, nyse: bool, df_short_interest: pd.DataFrame):
|
||||
"""Plots the short interest of a stock. This corresponds to the
|
||||
number of shares that have been sold short but have not yet been
|
||||
covered or closed out. Either NASDAQ or NYSE [Source: Quandl]
|
||||
@@ -27,21 +26,9 @@ def plot_short_interest(
|
||||
start date to start displaying short interest volume
|
||||
nyse : bool
|
||||
data from NYSE if true, otherwise NASDAQ
|
||||
days : int
|
||||
Number of past days to show short interest
|
||||
df_short_interest: pd.DataFrame
|
||||
Short interest dataframe
|
||||
"""
|
||||
df_short_interest = df_short_interest[start:] # type: ignore
|
||||
df_short_interest.columns = [
|
||||
"".join(" " + char if char.isupper() else char.strip() for char in idx).strip()
|
||||
for idx in df_short_interest.columns.tolist()
|
||||
]
|
||||
df_short_interest["% of Volume Shorted"] = round(
|
||||
100 * df_short_interest["Short Volume"] / df_short_interest["Total Volume"],
|
||||
2,
|
||||
)
|
||||
|
||||
_, ax = plt.subplots()
|
||||
ax.bar(df_short_interest.index, df_short_interest["Short Volume"], 0.3, color="r")
|
||||
ax.bar(
|
||||
@@ -53,15 +40,9 @@ def plot_short_interest(
|
||||
)
|
||||
ax.set_ylabel("Shares")
|
||||
ax.set_xlabel("Date")
|
||||
ax.set_title(f"{('NASDAQ', 'NYSE')[nyse]} Short Interest on {ticker}")
|
||||
|
||||
if start:
|
||||
ax.set_title(
|
||||
f"{('NASDAQ', 'NYSE')[nyse]} Short Interest on {ticker} from {start.date()}" # type: ignore
|
||||
)
|
||||
else:
|
||||
ax.set_title(f"{('NASDAQ', 'NYSE')[nyse]} Short Interest on {ticker}")
|
||||
|
||||
ax.legend(labels=["Short Volume", "Total Volume"])
|
||||
ax.legend(labels=["Short Volume", "Total Volume"], loc="best")
|
||||
ax.tick_params(axis="both", which="major")
|
||||
ax.yaxis.set_major_formatter(matplotlib.ticker.EngFormatter())
|
||||
ax_twin = ax.twinx()
|
||||
@@ -75,21 +56,12 @@ def plot_short_interest(
|
||||
ax_twin.tick_params(axis="y", which="major", color="green")
|
||||
ax_twin.yaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter("%.0f%%"))
|
||||
plt.xlim([df_short_interest.index[0], df_short_interest.index[-1]])
|
||||
plt.gcf().autofmt_xdate()
|
||||
|
||||
df_short_interest["% of Volume Shorted"] = df_short_interest[
|
||||
"% of Volume Shorted"
|
||||
].apply(lambda x: f"{x/100:.2%}")
|
||||
df_short_interest = df_short_interest.applymap(
|
||||
lambda x: long_number_format(x)
|
||||
).sort_index(ascending=False)
|
||||
|
||||
pd.set_option("display.max_colwidth", 70)
|
||||
print(df_short_interest.head(n=days).to_string())
|
||||
print("")
|
||||
plt.show()
|
||||
|
||||
|
||||
def short_interest(ticker: str, start: str, nyse: bool, days: int, export: str):
|
||||
def short_interest(ticker: str, nyse: bool, days: int, raw: bool, export: str):
|
||||
"""Plots the short interest of a stock. This corresponds to the
|
||||
number of shares that have been sold short but have not yet been
|
||||
covered or closed out. Either NASDAQ or NYSE [Source: Quandl]
|
||||
@@ -98,22 +70,59 @@ def short_interest(ticker: str, start: str, nyse: bool, days: int, export: str):
|
||||
----------
|
||||
ticker : str
|
||||
ticker to get short interest from
|
||||
start : str
|
||||
start date to start displaying short interest volume
|
||||
nyse : bool
|
||||
data from NYSE if true, otherwise NASDAQ
|
||||
days : int
|
||||
Number of past days to show short interest
|
||||
raw : bool
|
||||
Flag to print raw data instead
|
||||
export : str
|
||||
Export dataframe data to csv,json,xlsx file
|
||||
"""
|
||||
df_short_interest = quandl_model.get_short_interest(ticker, nyse)
|
||||
|
||||
plot_short_interest(ticker, start, nyse, days, df_short_interest)
|
||||
df_short_interest = df_short_interest.tail(days)
|
||||
|
||||
df_short_interest.columns = [
|
||||
"".join(" " + char if char.isupper() else char.strip() for char in idx).strip()
|
||||
for idx in df_short_interest.columns.tolist()
|
||||
]
|
||||
pd.options.mode.chained_assignment = None
|
||||
vol_pct = (
|
||||
100
|
||||
* df_short_interest["Short Volume"].values
|
||||
/ df_short_interest["Total Volume"].values
|
||||
)
|
||||
df_short_interest["% of Volume Shorted"] = [round(pct, 2) for pct in vol_pct]
|
||||
|
||||
if raw:
|
||||
df_short_interest["% of Volume Shorted"] = df_short_interest[
|
||||
"% of Volume Shorted"
|
||||
].apply(lambda x: f"{x/100:.2%}")
|
||||
df_short_interest = df_short_interest.applymap(
|
||||
lambda x: long_number_format(x)
|
||||
).sort_index(ascending=False)
|
||||
|
||||
df_short_interest.index = df_short_interest.index.date
|
||||
|
||||
print(
|
||||
tabulate(
|
||||
df_short_interest,
|
||||
headers=df_short_interest.columns,
|
||||
floatfmt=".2f",
|
||||
showindex=True,
|
||||
tablefmt="fancy_grid",
|
||||
)
|
||||
)
|
||||
|
||||
else:
|
||||
plot_short_interest(ticker, nyse, df_short_interest)
|
||||
|
||||
print("")
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"shortint(quandl)",
|
||||
"psi(quandl)",
|
||||
df_short_interest,
|
||||
)
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
""" Market Watch View """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import argparse
|
||||
from typing import List
|
||||
import requests
|
||||
import pandas as pd
|
||||
from bs4 import BeautifulSoup
|
||||
from gamestonk_terminal.helper_funcs import (
|
||||
check_positive,
|
||||
get_user_agent,
|
||||
parse_known_args_and_warn,
|
||||
)
|
||||
|
||||
# pylint: disable=too-many-branches
|
||||
|
||||
|
||||
def sec_fillings(other_args: List[str], ticker: str):
|
||||
"""Display SEC filings for a given stock ticker
|
||||
|
||||
Parameters
|
||||
----------
|
||||
other_args : List[str]
|
||||
argparse other args - ["-n", "10"]
|
||||
ticker : str
|
||||
Stock ticker
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
prog="sec",
|
||||
description="""
|
||||
Prints SEC filings of the company. The following fields are expected: Filing Date,
|
||||
Document Date, Type, Category, Amended, and Link. [Source: Market Watch]
|
||||
""",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-n",
|
||||
"--num",
|
||||
action="store",
|
||||
dest="n_num",
|
||||
type=check_positive,
|
||||
default=5,
|
||||
help="number of latest SEC filings.",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
if not ns_parser:
|
||||
return
|
||||
|
||||
pd.set_option("display.max_colwidth", None)
|
||||
|
||||
url_financials = f"https://www.marketwatch.com/investing/stock/{ticker}/financials/secfilings"
|
||||
|
||||
text_soup_financials = BeautifulSoup(
|
||||
requests.get(url_financials, headers={"User-Agent": get_user_agent()}).text,
|
||||
"lxml",
|
||||
)
|
||||
|
||||
# a_financials_header = []
|
||||
df_financials = None
|
||||
b_ready_to_process_info = False
|
||||
soup_financials = text_soup_financials.findAll("tr", {"class": "table__row"})
|
||||
for financials_info in soup_financials:
|
||||
a_financials = financials_info.text.split("\n")
|
||||
|
||||
# If header has been processed and dataframe created ready to populate the SEC information
|
||||
if b_ready_to_process_info:
|
||||
l_financials_info = [a_financials[2]]
|
||||
l_financials_info.extend(a_financials[5:-1])
|
||||
l_financials_info.append(financials_info.a["href"])
|
||||
# Append data values to financials
|
||||
df_financials.loc[len(df_financials.index)] = l_financials_info # type: ignore
|
||||
|
||||
if "Filing Date" in a_financials:
|
||||
l_financials_header = [a_financials[2]]
|
||||
l_financials_header.extend(a_financials[5:-1])
|
||||
l_financials_header.append("Link")
|
||||
|
||||
df_financials = pd.DataFrame(columns=l_financials_header)
|
||||
df_financials.set_index("Filing Date")
|
||||
b_ready_to_process_info = True
|
||||
|
||||
# Set Filing Date as index
|
||||
df_financials = df_financials.set_index("Filing Date") # type: ignore
|
||||
|
||||
print(df_financials.head(n=ns_parser.n_num).to_string())
|
||||
print("")
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("")
|
||||
return
|
||||
Reference in New Issue
Block a user