mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 04:52:07 +00:00
Add dark pools (ATS) vs Non-ATS data over time
This commit is contained in:
@@ -13,6 +13,7 @@ from gamestonk_terminal.due_diligence import market_watch_view as mw_view
|
||||
from gamestonk_terminal.due_diligence import quandl_view as q_view
|
||||
from gamestonk_terminal.due_diligence import reddit_view as r_view
|
||||
from gamestonk_terminal.due_diligence import news_view
|
||||
from gamestonk_terminal.due_diligence import finra_view
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.helper_funcs import get_flair
|
||||
from gamestonk_terminal.menu import session
|
||||
@@ -37,6 +38,7 @@ class DueDiligenceController:
|
||||
"analyst",
|
||||
"warnings",
|
||||
"sec",
|
||||
"dp",
|
||||
]
|
||||
|
||||
def __init__(self, stock: DataFrame, ticker: str, start: str, interval: str):
|
||||
@@ -97,6 +99,7 @@ class DueDiligenceController:
|
||||
print(
|
||||
" warnings company warnings according to Sean Seah book [Market Watch]"
|
||||
)
|
||||
print(" dp dark pools vs OTC data [FINRA]")
|
||||
print("")
|
||||
|
||||
def switch(self, an_input: str):
|
||||
@@ -175,6 +178,10 @@ class DueDiligenceController:
|
||||
""" Process short command """
|
||||
q_view.short_interest(other_args, self.ticker, self.start)
|
||||
|
||||
def call_dp(self, other_args: List[str]):
|
||||
""" Process dp command """
|
||||
finra_view.dark_pool(other_args, self.ticker)
|
||||
|
||||
|
||||
def menu(stock: DataFrame, ticker: str, start: str, interval: str):
|
||||
"""Due Diligence Menu
|
||||
|
||||
272
gamestonk_terminal/due_diligence/finra_view.py
Normal file
272
gamestonk_terminal/due_diligence/finra_view.py
Normal file
@@ -0,0 +1,272 @@
|
||||
""" FINRA View """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import argparse
|
||||
from typing import List
|
||||
import requests
|
||||
import pandas as pd
|
||||
from matplotlib import pyplot as plt
|
||||
import matplotlib.dates as mdates
|
||||
from gamestonk_terminal.config_plot import PLOT_DPI
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.helper_funcs import parse_known_args_and_warn, plot_autoscale
|
||||
|
||||
|
||||
def getFINRAweeks(tier, is_ats) -> List:
|
||||
"""Get FINRA weeks
|
||||
|
||||
Parameters
|
||||
----------
|
||||
tier : str
|
||||
Stock tier between T1, T2, or OTCE
|
||||
is_ats : bool
|
||||
ATS data if true, NON-ATS otherwise
|
||||
|
||||
Returns
|
||||
----------
|
||||
List
|
||||
List of response data
|
||||
"""
|
||||
req_hdr = {"Accept": "application/json", "Content-Type": "application/json"}
|
||||
|
||||
req_data = {
|
||||
"compareFilters": [
|
||||
{
|
||||
"compareType": "EQUAL",
|
||||
"fieldName": "summaryTypeCode",
|
||||
"fieldValue": "ATS_W_SMBL" if is_ats else "OTC_W_SMBL",
|
||||
},
|
||||
{
|
||||
"compareType": "EQUAL",
|
||||
"fieldName": "tierIdentifier",
|
||||
"fieldValue": tier,
|
||||
},
|
||||
],
|
||||
"delimiter": "|",
|
||||
"fields": ["weekStartDate"],
|
||||
"limit": 27,
|
||||
"quoteValues": False,
|
||||
"sortFields": ["-weekStartDate"],
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
"https://api.finra.org/data/group/otcMarket/name/weeklyDownloadDetails",
|
||||
headers=req_hdr,
|
||||
json=req_data,
|
||||
)
|
||||
|
||||
return response.json() if response.status_code == 200 else list()
|
||||
|
||||
|
||||
def getFINRAdata(weekStartDate, tier, ticker, is_ats) -> List:
|
||||
"""Get FINRA data
|
||||
|
||||
Parameters
|
||||
----------
|
||||
weekStartDate : str
|
||||
Weekly data to get FINRA data
|
||||
tier : str
|
||||
Stock tier between T1, T2, or OTCE
|
||||
ticker : str
|
||||
Stock ticker to get data from
|
||||
is_ats : bool
|
||||
ATS data if true, NON-ATS otherwise
|
||||
|
||||
Returns
|
||||
----------
|
||||
str
|
||||
Status code from request
|
||||
List
|
||||
List of response data
|
||||
"""
|
||||
req_hdr = {"Accept": "application/json", "Content-Type": "application/json"}
|
||||
|
||||
l_cmp_filters = [
|
||||
{
|
||||
"compareType": "EQUAL",
|
||||
"fieldName": "weekStartDate",
|
||||
"fieldValue": weekStartDate,
|
||||
},
|
||||
{"compareType": "EQUAL", "fieldName": "tierIdentifier", "fieldValue": tier},
|
||||
{
|
||||
"compareType": "EQUAL",
|
||||
"description": "",
|
||||
"fieldName": "summaryTypeCode",
|
||||
"fieldValue": "ATS_W_SMBL" if is_ats else "OTC_W_SMBL",
|
||||
},
|
||||
]
|
||||
|
||||
if ticker:
|
||||
l_cmp_filters.append(
|
||||
{
|
||||
"compareType": "EQUAL",
|
||||
"fieldName": "issueSymbolIdentifier",
|
||||
"fieldValue": ticker,
|
||||
}
|
||||
)
|
||||
|
||||
req_data = {
|
||||
"compareFilters": l_cmp_filters,
|
||||
"delimiter": "|",
|
||||
"fields": [
|
||||
"issueSymbolIdentifier",
|
||||
"totalWeeklyShareQuantity",
|
||||
"totalWeeklyTradeCount",
|
||||
"lastUpdateDate",
|
||||
],
|
||||
"limit": 5000,
|
||||
"quoteValues": False,
|
||||
"sortFields": ["totalWeeklyShareQuantity"],
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
"https://api.finra.org/data/group/otcMarket/name/weeklySummary",
|
||||
headers=req_hdr,
|
||||
json=req_data,
|
||||
)
|
||||
|
||||
return (
|
||||
response.status_code,
|
||||
response.json() if response.status_code == 200 else list(),
|
||||
)
|
||||
|
||||
|
||||
def getTickerFINRAdata(ticker):
|
||||
"""Get all FINRA data associated with a ticker
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ticker : str
|
||||
Stock ticker to get data from
|
||||
|
||||
Returns
|
||||
----------
|
||||
pd.DataFrame
|
||||
Dark Pools (ATS) Data
|
||||
pd.DataFrame
|
||||
OTC (Non-ATS) Data
|
||||
"""
|
||||
tiers = ["T1", "T2", "OTCE"]
|
||||
|
||||
l_data = list()
|
||||
for tier in tiers:
|
||||
for d_week in getFINRAweeks(tier, is_ats=True):
|
||||
status_code, response = getFINRAdata(
|
||||
d_week["weekStartDate"], tier, ticker, True
|
||||
)
|
||||
if status_code == 200:
|
||||
if response:
|
||||
d_data = response[0]
|
||||
d_data.update(d_week)
|
||||
l_data.append(d_data)
|
||||
else:
|
||||
break
|
||||
|
||||
df_ats = pd.DataFrame(l_data)
|
||||
df_ats = df_ats.sort_values("weekStartDate")
|
||||
df_ats = df_ats.set_index("weekStartDate")
|
||||
|
||||
l_data = list()
|
||||
for tier in tiers:
|
||||
for d_week in getFINRAweeks(tier, is_ats=False):
|
||||
status_code, response = getFINRAdata(
|
||||
d_week["weekStartDate"], tier, ticker, False
|
||||
)
|
||||
if status_code == 200:
|
||||
if response:
|
||||
d_data = response[0]
|
||||
d_data.update(d_week)
|
||||
l_data.append(d_data)
|
||||
else:
|
||||
break
|
||||
|
||||
df_otc = pd.DataFrame(l_data)
|
||||
df_otc = df_otc.sort_values("weekStartDate")
|
||||
df_otc = df_otc.set_index("weekStartDate")
|
||||
|
||||
return df_ats, df_otc
|
||||
|
||||
|
||||
def plot_dark_pools(ticker: str, ats: pd.DataFrame, otc: pd.DataFrame):
|
||||
"""Plots ATS and NON-ATS data
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ticker : str
|
||||
Stock ticker to get data from
|
||||
ats : pd.DataFrame
|
||||
Dark Pools (ATS) Data
|
||||
otc : pd.DataFrame
|
||||
OTC (Non-ATS) Data
|
||||
"""
|
||||
_, axData = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
|
||||
|
||||
plt.subplot(3, 1, (1, 2))
|
||||
plt.bar(
|
||||
ats.index,
|
||||
(ats["totalWeeklyShareQuantity"] + otc["totalWeeklyShareQuantity"]) / 1_000_000,
|
||||
color="tab:orange",
|
||||
)
|
||||
plt.bar(otc.index, otc["totalWeeklyShareQuantity"] / 1_000_000, color="tab:blue")
|
||||
plt.ylabel("Total Weekly Shares [Million]")
|
||||
plt.legend(["ATS", "OTC"])
|
||||
plt.grid(b=True, which="major", color="#666666", linestyle="-", alpha=0.2)
|
||||
plt.title(f"Dark Pools (ATS) vs OTC (Non-ATS) Data for {ticker}")
|
||||
|
||||
# _ = axData.twinx()
|
||||
plt.subplot(313)
|
||||
plt.plot(
|
||||
ats.index,
|
||||
ats["totalWeeklyShareQuantity"] / ats["totalWeeklyTradeCount"],
|
||||
color="tab:orange",
|
||||
)
|
||||
plt.plot(
|
||||
otc.index,
|
||||
otc["totalWeeklyShareQuantity"] / otc["totalWeeklyTradeCount"],
|
||||
color="tab:blue",
|
||||
)
|
||||
plt.ylabel("Shares per Trade")
|
||||
plt.legend(["ATS", "OTC"])
|
||||
plt.grid(b=True, which="major", color="#666666", linestyle="-", alpha=0.2)
|
||||
plt.gcf().autofmt_xdate()
|
||||
plt.xlabel("Weeks")
|
||||
|
||||
if gtff.USE_ION:
|
||||
plt.ion()
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
def dark_pool(other_args: List[str], ticker: str):
|
||||
"""Display barchart of dark pool (ATS) and OTC (Non ATS) data
|
||||
|
||||
Parameters
|
||||
----------
|
||||
other_args : List[str]
|
||||
argparse other args
|
||||
ticker : str
|
||||
Stock ticker
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
prog="dp",
|
||||
description="Display barchart of dark pool (ATS) and OTC (Non ATS) data [Source: FINRA]",
|
||||
)
|
||||
|
||||
if 1:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
if not ns_parser:
|
||||
return
|
||||
|
||||
df_ats, df_otc = getTickerFINRAdata(ticker)
|
||||
|
||||
plot_dark_pools(ticker, df_ats, df_otc)
|
||||
|
||||
print("")
|
||||
|
||||
"""
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("")
|
||||
return
|
||||
"""
|
||||
Reference in New Issue
Block a user