Add the Finance Database to ETFs and Stocks section (#869)

* Add the Finance Database to the ETF menu

* Add the Finance Database to the stocks/discovery menu

* Update website with Finance Database info

* Update website sections of the Finance Database

* Update Finance Database functions to match layout of controller modules

* Merge website links

* Add missing thepassiveinvestor dependency

* Fix website bug

* Name change

* Update website with include exchanges parameter

* Add include_exchanges, make searching less case sensitive, change market cap to millions and minor improvements

* Change help message a bit
This commit is contained in:
Jeroen Bouma
2021-10-29 17:57:24 +02:00
committed by GitHub
parent 03011aa312
commit 9e5b86086e
9 changed files with 402 additions and 3 deletions

View File

@@ -11,7 +11,12 @@ from prompt_toolkit.completion import NestedCompleter
from thepassiveinvestor import create_ETF_report
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.etf import screener_view, stockanalysis_view, wsj_view
from gamestonk_terminal.etf import (
screener_view,
stockanalysis_view,
wsj_view,
financedatabase_view,
)
from gamestonk_terminal.helper_funcs import (
get_flair,
parse_known_args_and_warn,
@@ -45,6 +50,7 @@ class ETFController:
"decliners",
"active",
"pir",
"fds",
]
CHOICES += CHOICES_COMMANDS
@@ -80,6 +86,9 @@ Wall St. Journal:
The Passive Investor:
pir create ETF report of multiple tickers
Finance Database:
fds advanced ETF search based on category, name and/or description
"""
print(help_str)
@@ -400,6 +409,79 @@ The Passive Investor:
f"Created ETF report as {ns_parser.filename} in folder {ns_parser.folder} \n"
)
@try_except
def call_fds(self, other_args):
"""Process fds command"""
parser = argparse.ArgumentParser(
description="Display a selection of ETFs based on category, name and/or description filtered by total "
"assets. Returns the top ETFs when no argument is given. [Source: Finance Database]",
add_help=False,
)
parser.add_argument(
"-c",
"--category",
default=None,
nargs="+",
dest="category",
help="Specify the ETF selection based on a category",
)
parser.add_argument(
"-n",
"--name",
default=None,
nargs="+",
dest="name",
help="Specify the ETF selection based on the name",
)
parser.add_argument(
"-d",
"--description",
default=None,
nargs="+",
dest="description",
help="Specify the ETF selection based on the description (not shown in table)",
)
parser.add_argument(
"-ie",
"--include_exchanges",
action="store_false",
help="When used, data from different exchanges is also included. This leads to a much larger "
"pool of data due to the same ETF being listed on multiple exchanges",
)
parser.add_argument(
"-a",
"--amount",
default=10,
type=int,
dest="amount",
help="Enter the number of ETFs you wish to see in the Tabulate window",
)
parser.add_argument(
"-o",
"--options",
action="store_true",
help="Obtain the available categories",
)
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
financedatabase_view.show_etfs(
category=ns_parser.category,
name=ns_parser.name,
description=ns_parser.description,
include_exchanges=ns_parser.include_exchanges,
amount=ns_parser.amount,
options=ns_parser.options,
)
def menu():
etf_controller = ETFController()

View File

@@ -0,0 +1,75 @@
"""Finance Database view"""
__docformat__ = "numpy"
import financedatabase as fd
import pandas as pd
from tabulate import tabulate
from gamestonk_terminal import feature_flags as gtff
def show_etfs(
category: str,
name: str,
description: str,
include_exchanges: bool,
amount: int,
options: str,
):
"""
Display a selection of ETFs based on category, name and/or description filtered by total assets.
Returns the top ETFs when no argument is given. [Source: Finance Database]
Parameters
----------
category: str
Search by category to find ETFs matching the criteria.
name: str
Search by name to find ETFs matching the criteria.
description: str
Search by description to find ETFs matching the criteria.
include_exchanges: bool
When you wish to include different exchanges use this boolean.
amount : int
Number of ETFs to display, default is 10.
options : str
Show the category options.
"""
if options:
for option in fd.show_options("etfs"):
print(option)
return
if category is not None:
data = fd.select_etfs(
category=" ".join(category).title(), exclude_exchanges=include_exchanges
)
else:
data = fd.select_etfs(category=category, exclude_exchanges=include_exchanges)
if name is not None:
print(name)
data = fd.search_products(data, query=" ".join(name), search="long_name")
if description is not None:
data = fd.search_products(data, query=" ".join(description), search="summary")
tabulate_data = pd.DataFrame(data).T[
["long_name", "family", "category", "total_assets"]
]
tabulate_data_sorted = tabulate_data.sort_values(by="total_assets", ascending=False)
tabulate_data_sorted["total_assets"] = (
tabulate_data_sorted["total_assets [M]"] / 1e6
)
if gtff.USE_TABULATE_DF:
print(
tabulate(
tabulate_data_sorted.iloc[:amount],
showindex=True,
headers=["Name", "Family", "Category", "Total Assets [M]"],
floatfmt=".2f",
tablefmt="fancy_grid",
),
"\n",
)
else:
print(tabulate_data_sorted.iloc[:amount].to_string(), "\n")

View File

@@ -1,17 +1,17 @@
""" Disc Controller """
__docformat__ = "numpy"
# pylint:disable=too-many-lines
import argparse
import os
from typing import List
from datetime import datetime
from typing import List
from matplotlib import pyplot as plt
from prompt_toolkit.completion import NestedCompleter
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.helper_funcs import get_flair
from gamestonk_terminal.menu import session
from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
check_non_negative,
@@ -20,6 +20,7 @@ from gamestonk_terminal.helper_funcs import (
check_int_range,
try_except,
)
from gamestonk_terminal.menu import session
from gamestonk_terminal.stocks.discovery import (
ark_view,
fidelity_view,
@@ -28,6 +29,7 @@ from gamestonk_terminal.stocks.discovery import (
yahoofinance_view,
finnhub_view,
geekofwallstreet_view,
financedatabase_view,
)
@@ -61,6 +63,7 @@ class DiscoveryController:
"lowfloat",
"hotpenny",
"rtearn",
"fds",
]
CHOICES += CHOICES_COMMANDS
@@ -107,6 +110,8 @@ shortinterest.com
lowfloat low float stocks under 10M shares float
pennystockflow.com
hotpenny today's hot penny stocks
Finance Database:
fds advanced Equities search based on country, sector, industry, name and/or description
"""
print(help_text)
@@ -881,6 +886,103 @@ pennystockflow.com
export=ns_parser.export,
)
@try_except
def call_fds(self, other_args: List[str]):
"""Process fds command"""
parser = argparse.ArgumentParser(
description="Display a selection of Equities based on country, sector, industry, name and/or description "
"filtered by market cap. If no arguments are given, return the equities with the highest "
"market cap. [Source: Finance Database]",
add_help=False,
)
parser.add_argument(
"-c",
"--country",
default=None,
nargs="+",
dest="country",
help="Specify the Equities selection based on a country",
)
parser.add_argument(
"-s",
"--sector",
default=None,
nargs="+",
dest="sector",
help="Specify the Equities selection based on a sector",
)
parser.add_argument(
"-i",
"--industry",
default=None,
nargs="+",
dest="industry",
help="Specify the Equities selection based on an industry",
)
parser.add_argument(
"-n",
"--name",
default=None,
nargs="+",
dest="name",
help="Specify the Equities selection based on the name",
)
parser.add_argument(
"-d",
"--description",
default=None,
nargs="+",
dest="description",
help="Specify the Equities selection based on the description (not shown in table)",
)
parser.add_argument(
"-ie",
"--include_exchanges",
action="store_false",
help="When used, data from different exchanges is also included. This leads to a much larger "
"pool of data due to the same company being listed on multiple exchanges",
)
parser.add_argument(
"-a",
"--amount",
default=10,
type=int,
dest="amount",
help="Enter the number of Equities you wish to see in the Tabulate window",
)
parser.add_argument(
"-o",
"--options ",
choices=["countries", "sectors", "industries"],
default=None,
dest="options",
help="Obtain the available options for country, sector and industry",
)
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
financedatabase_view.show_equities(
country=ns_parser.country,
sector=ns_parser.sector,
industry=ns_parser.industry,
name=ns_parser.name,
description=ns_parser.description,
include_exchanges=ns_parser.include_exchanges,
amount=ns_parser.amount,
options=ns_parser.options,
)
def menu():
"""Discovery Menu"""

View File

@@ -0,0 +1,103 @@
"""Finance Database view"""
__docformat__ = "numpy"
import financedatabase as fd
import pandas as pd
from tabulate import tabulate
from gamestonk_terminal import feature_flags as gtff
def show_equities(
country: str,
sector: str,
industry: str,
name: str,
description: str,
amount: int,
include_exchanges: bool,
options: str,
):
"""
Display a selection of Equities based on country, sector, industry, name and/or description filtered
by market cap. If no arguments are given, return the equities with the highest market cap.
[Source: Finance Database]
Parameters
----------
country: str
Search by country to find stocks matching the criteria.
sector : str
Search by sector to find stocks matching the criteria.
industry : str
Search by industry to find stocks matching the criteria.
name : str
Search by name to find stocks matching the criteria.
description : str
Search by description to find stocks matching the criteria.
amount : int
Number of stocks to display, default is 10.
include_exchanges: bool
When you wish to include different exchanges use this boolean.
options : str
Show the country, sector or industry options.
"""
if options is not None:
for option in fd.show_options("equities", options):
print(option)
return
if country is not None:
country = " ".join(country).title()
if sector is not None:
sector = " ".join(sector).title()
if industry is not None:
industry = " ".join(industry).title()
data = fd.select_equities(
country=country,
sector=sector,
industry=industry,
exclude_exchanges=include_exchanges,
)
if name is not None:
data = fd.search_products(data, query=" ".join(name), search="long_name")
if description is not None:
data = fd.search_products(data, query=" ".join(description), search="summary")
tabulate_data = pd.DataFrame(data).T[
[
"long_name",
"sector",
"industry",
"country",
"city",
"website",
"market_cap",
]
]
tabulate_data_sorted = tabulate_data.sort_values(by="market_cap", ascending=False)
tabulate_data_sorted["market_cap"] = tabulate_data_sorted["market_cap"] / 1e6
if gtff.USE_TABULATE_DF:
print(
tabulate(
tabulate_data_sorted.iloc[:amount],
showindex=True,
headers=[
"Name",
"Sector",
"Industry",
"Country",
"City",
"Website",
"Market Cap [M]",
],
floatfmt=".2f",
tablefmt="fancy_grid",
),
"\n",
)
else:
print(tabulate_data_sorted.iloc[:amount].to_string(), "\n")

View File

@@ -223,6 +223,7 @@ termcolor==1.1.0
terminado==0.12.1; python_version >= "3.6"
testpath==0.5.0; python_version >= "3.7"
textwrap3==0.9.2; python_version >= "3.6"
thepassiveinvestor==1.0.9
threadpoolctl==3.0.0; python_version >= "3.7"
timeseries-cv==0.1.4; python_version >= "3.6" and python_version < "4.0"
tokenize-rt==4.2.1; python_full_version >= "3.6.1"

1
requirements.txt vendored
View File

@@ -200,6 +200,7 @@ termcolor==1.1.0
terminado==0.12.1; python_version >= "3.6"
testpath==0.5.0; python_version >= "3.7"
textwrap3==0.9.2; python_version >= "3.6"
thepassiveinvestor==1.0.9
threadpoolctl==3.0.0; python_version >= "3.7"
timeseries-cv==0.1.4; python_version >= "3.6" and python_version < "4.0"
tokenize-rt==4.2.1; python_full_version >= "3.6.1"

14
website/content/etf/fds/_index.md vendored Normal file
View File

@@ -0,0 +1,14 @@
```
usage: fds [-c --category CATEGORY [CATEGORY ...]] [-n --name NAME [NAME ...]]
[-d --description DESCRIPTION [DESCRIPTION ...]] [-ie --include_exchanges]
[-a --amount AMOUNT] [-o --options] [-h]
```
Display a selection of ETFs based on category, name and/or description filtered by total assets. Returns the top ETFs
when no argument is given.
* -c --category: Specify the ETF selection based on a category
* -n --name: Specify the ETF selection based on the name
* -d --description: Specify the ETF selection based on the description (not shown in table)
* -ie --include_exchanges: If used, you also obtain ETFs from different exchanges (a lot of data)
* -a --amount: Enter the number of ETFs you wish to see in the Tabulate window
* -o --options: Obtain the available categories

View File

@@ -0,0 +1,17 @@
```
usage: fds [-c --country COUNTRY [COUNTRY ...]] [-s --sector SECTOR [SECTOR ...]]
[-i --industry INDUSTRY [INDUSTRY ...]] [-n --name NAME [NAME ...]]
[-d --description DESCRIPTION [DESCRIPTION ...]] [-ie --include_exchanges] [-a --amount AMOUNT]
[-o --options {countries,sectors,industries}] [-h]
```
Display a selection of Equities based on country, sector, industry, name and/or description filtered by market cap.
If no arguments are given, return the equities with the highest market cap.
* -c --country: Specify the Equities selection based on a country
* -s --sector: Specify the Equities selection based on a sector
* -i --industry: Specify the Equities selection based on an industry
* -n --name: Specify the Equities selection based on the name
* -d --description: Specify the Equities selection based on the description (not shown in table)
* -ie --include_exchanges: If used, you also obtain Equities from different exchanges (a lot of data)
* -a --amount: Enter the number of Equities you wish to see in the Tabulate window
* -o --options: Obtain the available options for country, sector and industry

View File

@@ -48,6 +48,8 @@ main:
ref: "/stocks/discovery/lowfloat"
- name: hotpenny
ref: "/stocks/discovery/hotpenny"
- name: fds
ref: "/stocks/discovery/fds"
- name: dark pool shorts
ref: "/stocks/dark_pool_shorts"
sub:
@@ -804,6 +806,8 @@ main:
ref: "/etf/active"
- name: pir
ref: "/etf/pir"
- name: fds
ref: "/etf/fds"
- name: portfolio
ref: "/portfolio"
sub: