diff --git a/gamestonk_terminal/due_diligence/README.md b/gamestonk_terminal/due_diligence/README.md
index 70bfb49340b..297d07428fa 100644
--- a/gamestonk_terminal/due_diligence/README.md
+++ b/gamestonk_terminal/due_diligence/README.md
@@ -24,6 +24,8 @@ This menu aims to help in due-diligence of a pre-loaded stock, and the usage of
* short interest [Quandl]
* [warnings](#warnings)
* company warnings according to Sean Seah book [Market Watch]
+* [ftd](#ftd)
+ * fails-to-deliver data [SEC]
## news
@@ -157,3 +159,15 @@ Sean Seah warnings. Check: Consistent historical earnings per share; Consistentl
* -d : print insights into warnings calculation. Default False.
+
+## ftd
+
+```text
+usage: ftd [-n]
+```
+
+The fails-to-deliver data collected by SEC. Fails to deliver on a given day are a cumulative number of all fails outstanding until that day, plus new fails that occur that day, less fails that settle that day. See . [Source: SEC]
+
+* -n : number of latest fails-to-deliver being printed. Default 10.
+
+
diff --git a/gamestonk_terminal/due_diligence/dd_controller.py b/gamestonk_terminal/due_diligence/dd_controller.py
index 14ecab8fc40..808df2ef426 100644
--- a/gamestonk_terminal/due_diligence/dd_controller.py
+++ b/gamestonk_terminal/due_diligence/dd_controller.py
@@ -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 sec_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",
+ "ftd",
]
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(" ftd fails-to-deliver data [SEC]")
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_ftd(self, other_args: List[str]):
+ """ Process ftd command """
+ sec_view.fails_to_deliver(other_args, self.ticker)
+
def menu(stock: DataFrame, ticker: str, start: str, interval: str):
"""Due Diligence Menu
diff --git a/gamestonk_terminal/due_diligence/sec_view.py b/gamestonk_terminal/due_diligence/sec_view.py
new file mode 100644
index 00000000000..35f19df8b1c
--- /dev/null
+++ b/gamestonk_terminal/due_diligence/sec_view.py
@@ -0,0 +1,89 @@
+""" SEC 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 (
+ get_user_agent,
+ check_positive,
+ parse_known_args_and_warn,
+)
+
+
+def fails_to_deliver(other_args: List[str], ticker: str):
+ """Display fails-to-deliver data for a given ticker
+
+ Parameters
+ ----------
+ other_args : List[str]
+ argparse other args - ["-n", "10"]
+ ticker : str
+ Stock ticker
+ """
+
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="ftd",
+ description="""Prints latest fails-to-deliver data. [Source: SEC]""",
+ )
+ parser.add_argument(
+ "-n",
+ "--num",
+ action="store",
+ dest="n_num",
+ type=check_positive,
+ default=10,
+ help="number of latest fails-to-deliver being printed",
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ url_ftds = "https://www.sec.gov/data/foiadocsfailsdatahtm"
+ text_soup_ftds = BeautifulSoup(
+ requests.get(url_ftds, headers={"User-Agent": get_user_agent()}).text,
+ "lxml",
+ )
+
+ table = text_soup_ftds.find("table", {"class": "list"})
+ links = table.findAll("a")
+ link_idx = 0
+ ftds_data = pd.DataFrame()
+ while len(ftds_data) < ns_parser.n_num:
+ if link_idx > len(links):
+ break
+ link = links[link_idx]
+ url = "https://www.sec.gov" + link["href"]
+ all_ftds = pd.read_csv(
+ url,
+ compression="zip",
+ sep="|",
+ engine="python",
+ skipfooter=2,
+ usecols=[0, 2, 3, 5],
+ dtype={"QUANTITY (FAILS)": "int"},
+ )
+ tmp_ftds = all_ftds[all_ftds["SYMBOL"] == ticker]
+ del tmp_ftds["PRICE"]
+ del tmp_ftds["SYMBOL"]
+ # merge the data from this archive
+ ftds_data = pd.concat([ftds_data, tmp_ftds], ignore_index=True)
+ link_idx += 1
+
+ # clip away extra rows
+ ftds_data = ftds_data.sort_values("SETTLEMENT DATE", ascending=False)[
+ 0 : ns_parser.n_num
+ ]
+ print(
+ ftds_data.rename(
+ columns={"SETTLEMENT DATE": "Date", "QUANTITY (FAILS)": "Quantity"}
+ ).to_string(index=False)
+ )
+
+ except Exception as e:
+ print(e, "\n")