Skip to content

Commit d678b78

Browse files
committed
Update
1 parent 7d579ca commit d678b78

13 files changed

+251
-261
lines changed

finvizfinance/constants.py

+38-1
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,36 @@
154154
88: "Low",
155155
}
156156

157+
CUSTOM_GROUP_COLUMNS = {
158+
0: "No.",
159+
1: "Name",
160+
2: "Market Cap.",
161+
3: "P/E",
162+
4: "Forward P/E",
163+
5: "PEG",
164+
6: "P/S",
165+
7: "P/B",
166+
8: "P/Cash",
167+
9: "P/Free Cash Flow",
168+
10: "Dividend Yield",
169+
11: "EPS growth past 5 years",
170+
12: "EPS growth next 5 years",
171+
13: "Sales growth past 5 years",
172+
14: "Shares Float",
173+
15: "Performance (Week)",
174+
16: "Performance (Month)",
175+
17: "Performance (Quarter)",
176+
18: "Performance (Half Year)",
177+
19: "Performance (Year)",
178+
20: "Performance (YearToDate)",
179+
21: "Analyst Recom.",
180+
22: "Average Volume",
181+
23: "Relative Volume",
182+
24: "Change",
183+
25: "Volume",
184+
26: "Number of Stocks",
185+
}
186+
157187

158188
util_dict = {
159189
"signal": {
@@ -2249,4 +2279,11 @@
22492279

22502280
signal_dict = util_dict['signal']
22512281
filter_dict = util_dict["filter"]
2252-
order_dict = util_dict["order"]
2282+
order_dict = util_dict["order"]
2283+
2284+
group_util_dict = {
2285+
"group": {'Sector': {'g': 'sector'}, 'Industry': {'g': 'industry'}, 'Industry (Basic Materials)': {'g': 'industry', 'sg': 'basicmaterials'}, 'Industry (Communication Services)': {'g': 'industry', 'sg': 'communicationservices'}, 'Industry (Consumer Cyclical)': {'g': 'industry', 'sg': 'consumercyclical'}, 'Industry (Consumer Defensive)': {'g': 'industry', 'sg': 'consumerdefensive'}, 'Industry (Energy)': {'g': 'industry', 'sg': 'energy'}, 'Industry (Financial)': {'g': 'industry', 'sg': 'financial'}, 'Industry (Healthcare)': {'g': 'industry', 'sg': 'healthcare'}, 'Industry (Industrials)': {'g': 'industry', 'sg': 'industrials'}, 'Industry (Real Estate)': {'g': 'industry', 'sg': 'realestate'}, 'Industry (Technology)': {'g': 'industry', 'sg': 'technology'}, 'Industry (Utilities)': {'g': 'industry', 'sg': 'utilities'}, 'Country (U.S. listed stocks only)': {'g': 'country'}, 'Capitalization': {'g': 'capitalization'}},
2286+
"order": {'Name': 'name', 'Market Capitalization': 'marketcap', 'Price/Earnings': 'pe', 'Forward Price/Earnings': 'forwardpe', 'PEG (Price/Earnings/Growth)': 'peg', 'Price/Sales': 'ps', 'Price/Book': 'pb', 'Price/Cash': 'pc', 'Price/Free Cash Flow': 'pfcf', 'Dividend Yield': 'dividendyield', 'EPS growth past 5 years': 'eps5years', 'EPS growth next 5 years': 'estltgrowth', 'Sales growth past 5 years': 'sales5years', 'Short Interest Share': 'shortinterestshare', 'Analyst Recommendation': 'recom', 'Performance (Week)': 'perf1w', 'Performance (Month)': 'perf4w', 'Performance (Quarter)': 'perf13w', 'Performance (Half Year)': 'perf26w', 'Performance (Year)': 'perf52w', 'Performance (Year To Date)': 'perfytd', 'Average Volume (3 Month)': 'averagevolume', 'Relative Volume': 'relativevolume', 'Change': 'change', 'Volume': 'volume', 'Number of Stocks': 'count'}
2287+
}
2288+
group_dict = group_util_dict['group']
2289+
group_order_dict = group_util_dict['order']

finvizfinance/group/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
from finvizfinance.group.performance import Performance
44
from finvizfinance.group.spectrum import Spectrum
55
from finvizfinance.group.valuation import Valuation
6+
from finvizfinance.group.util import (
7+
get_group,
8+
get_orders
9+
)

finvizfinance/group/base.py

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
"""
2+
.. module:: group.overview
3+
:synopsis: group overview table.
4+
5+
.. moduleauthor:: Tianning Li <[email protected]>
6+
"""
7+
import pandas as pd
8+
from finvizfinance.util import web_scrap, number_covert
9+
from finvizfinance.constants import group_dict, group_order_dict
10+
11+
12+
class Base:
13+
"""Base
14+
Getting information from the finviz group page.
15+
"""
16+
17+
v_page = None
18+
url = "https://finviz.com/groups.ashx"
19+
request_params = {}
20+
21+
def __init__(self):
22+
"""initiate module"""
23+
self.request_params = {
24+
"v": self.v_page,
25+
}
26+
27+
def _parse_columns(self, columns):
28+
if not columns:
29+
return
30+
self.request_params['c'] = ",".join(columns)
31+
32+
def screener_view(
33+
self, group="Sector", order="Name", columns=None
34+
):
35+
"""Get screener table.
36+
37+
Args:
38+
group(str): choice of group option.
39+
order(str): sort the table by the choice of order.
40+
columns(list): columns of your choice. Default index: None
41+
Returns:
42+
df(pandas.DataFrame): group information table.
43+
"""
44+
if group not in group_dict:
45+
group_keys = list(group_dict.keys())
46+
raise ValueError(
47+
"Invalid group parameter '{}'. Possible parameter input: {}".format(
48+
group, group_keys
49+
)
50+
)
51+
if order not in group_order_dict:
52+
order_keys = list(group_order_dict.keys())
53+
raise ValueError(
54+
"Invalid order parameter '{}'. Possible parameter input: {}".format(
55+
order, order_keys
56+
)
57+
)
58+
59+
self.request_params = {**self.request_params, **group_dict[group], 'o': group_order_dict[order]}
60+
self._parse_columns(columns)
61+
62+
soup = web_scrap(self.url, self.request_params)
63+
table = soup.find("table", class_="groups_table")
64+
rows = table.find_all("tr")
65+
table_header = [i.text.strip() for i in rows[0].find_all("th")][1:]
66+
frame = []
67+
rows = rows[1:]
68+
num_col_index = list(range(2, len(table_header)))
69+
for row in rows:
70+
cols = row.find_all("td")[1:]
71+
info_dict = {}
72+
for i, col in enumerate(cols):
73+
# check if the col is number
74+
if i not in num_col_index:
75+
info_dict[table_header[i]] = col.text
76+
else:
77+
info_dict[table_header[i]] = number_covert(col.text)
78+
79+
frame.append(info_dict)
80+
return pd.DataFrame(frame)

finvizfinance/group/custom.py

+3-74
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,16 @@
44
55
.. moduleauthor:: Tianning Li <[email protected]>
66
"""
7-
import pandas as pd
8-
from finvizfinance.util import web_scrap, number_covert
9-
from finvizfinance.group.overview import Overview
7+
from finvizfinance.group.base import Base
108

119

12-
COLUMNS = {
13-
0: "No.",
14-
1: "Name",
15-
2: "Market Cap.",
16-
3: "P/E",
17-
4: "Forward P/E",
18-
5: "PEG",
19-
6: "P/S",
20-
7: "P/B",
21-
8: "P/Cash",
22-
9: "P/Free Cash Flow",
23-
10: "Dividend Yield",
24-
11: "EPS growth past 5 years",
25-
12: "EPS growth next 5 years",
26-
13: "Sales growth past 5 years",
27-
14: "Shares Float",
28-
15: "Performance (Week)",
29-
16: "Performance (Month)",
30-
17: "Performance (Quarter)",
31-
18: "Performance (Half Year)",
32-
19: "Performance (Year)",
33-
20: "Performance (YearToDate)",
34-
21: "Analyst Recom.",
35-
22: "Average Volume",
36-
23: "Relative Volume",
37-
24: "Change",
38-
25: "Volume",
39-
26: "Number of Stocks",
40-
}
41-
42-
43-
class Custom(Overview):
10+
class Custom(Base):
4411
"""Custom inherit from overview module.
4512
Getting information from the finviz group custom page.
4613
"""
4714

4815
v_page = 152
4916

50-
def get_columns(self):
51-
"""Get information about the columns
52-
53-
Returns:
54-
columns(dict): return the index and column name.
55-
"""
56-
return COLUMNS
57-
5817
def screener_view(
5918
self, group="Sector", order="Name", columns=[0, 1, 2, 3, 10, 22, 24, 25, 26]
6019
):
@@ -67,34 +26,4 @@ def screener_view(
6726
Returns:
6827
df(pandas.DataFrame): group information table.
6928
"""
70-
if group not in self.group_dict:
71-
raise ValueError()
72-
if order not in self.order_dict:
73-
raise ValueError()
74-
self.url = (
75-
self.BASE_URL.format(group=self.group_dict[group], v_page=self.v_page)
76-
+ "&"
77-
+ self.order_dict[order]
78-
)
79-
columns = [str(i) for i in columns]
80-
self.url += "&c=" + ",".join(columns)
81-
82-
soup = web_scrap(self.url)
83-
table = soup.find("table", class_="table-light")
84-
rows = table.find_all("tr")
85-
table_header = [i.text.strip() for i in rows[0].find_all("td")][1:]
86-
frame = []
87-
rows = rows[1:]
88-
num_col_index = list(range(2, len(table_header)))
89-
for row in rows:
90-
cols = row.find_all("td")[1:]
91-
info_dict = {}
92-
for i, col in enumerate(cols):
93-
# check if the col is number
94-
if i not in num_col_index:
95-
info_dict[table_header[i]] = col.text
96-
else:
97-
info_dict[table_header[i]] = number_covert(col.text)
98-
99-
frame.append(info_dict)
100-
return pd.DataFrame(frame)
29+
return Base.screener_view(group, order, columns)

finvizfinance/group/overview.py

+2-99
Original file line numberDiff line numberDiff line change
@@ -4,109 +4,12 @@
44
55
.. moduleauthor:: Tianning Li <[email protected]>
66
"""
7-
import pandas as pd
8-
from finvizfinance.util import web_scrap, number_covert
7+
from finvizfinance.group.base import Base
98

109

11-
class Overview:
10+
class Overview(Base):
1211
"""Overview
1312
Getting information from the finviz group overview page.
1413
"""
1514

1615
v_page = 110
17-
18-
def __init__(self):
19-
"""initiate module"""
20-
self.BASE_URL = "https://finviz.com/groups.ashx?{group}&v={v_page}"
21-
self.url = self.BASE_URL.format(group="g=sector", v_page=self.v_page)
22-
self._load_setting()
23-
24-
def _load_setting(self):
25-
"""load all the groups."""
26-
soup = web_scrap(self.url)
27-
selects = soup.find_all("select")
28-
29-
# group
30-
options = selects[0].find_all("option")
31-
key = [i.text.strip() for i in options]
32-
value = []
33-
for option in options:
34-
temp = option["value"].split("?")[1].split("&")
35-
if len(temp) == 4:
36-
temp = "&".join(temp[:2])
37-
else:
38-
temp = temp[0]
39-
value.append(temp)
40-
self.group_dict = dict(zip(key, value))
41-
42-
# order
43-
options = selects[1].find_all("option")
44-
key = [i.text.strip() for i in options]
45-
value = [i["value"].split("&")[-1] for i in options]
46-
self.order_dict = dict(zip(key, value))
47-
48-
def get_group(self):
49-
"""Get groups.
50-
51-
Returns:
52-
groups(list): all the available groups.
53-
"""
54-
return list(self.group_dict.keys())
55-
56-
def get_orders(self):
57-
"""Get orders.
58-
59-
Returns:
60-
orders(list): all the available orders.
61-
"""
62-
return list(self.order_dict.keys())
63-
64-
def screener_view(self, group="Sector", order="Name"):
65-
"""Get screener table.
66-
67-
Args:
68-
group(str): choice of group option.
69-
order(str): sort the table by the choice of order.
70-
71-
Returns:
72-
df(pandas.DataFrame): group information table.
73-
"""
74-
if group not in self.group_dict:
75-
group_keys = list(self.group_dict.keys())
76-
raise ValueError(
77-
"Invalid group parameter '{}'. Possible parameter input: {}".format(
78-
group, group_keys
79-
)
80-
)
81-
if order not in self.order_dict:
82-
order_keys = list(self.order_dict.keys())
83-
raise ValueError(
84-
"Invalid order parameter '{}'. Possible parameter input: {}".format(
85-
order, order_keys
86-
)
87-
)
88-
self.url = (
89-
self.BASE_URL.format(group=self.group_dict[group], v_page=self.v_page)
90-
+ "&"
91-
+ self.order_dict[order]
92-
)
93-
94-
soup = web_scrap(self.url)
95-
table = soup.find("table", class_="groups_table")
96-
rows = table.find_all("tr")
97-
table_header = [i.text.strip() for i in rows[0].find_all("th")][1:]
98-
frame = []
99-
rows = rows[1:]
100-
num_col_index = list(range(2, len(table_header)))
101-
for row in rows:
102-
cols = row.find_all("td")[1:]
103-
info_dict = {}
104-
for i, col in enumerate(cols):
105-
# check if the col is number
106-
if i not in num_col_index:
107-
info_dict[table_header[i]] = col.text
108-
else:
109-
info_dict[table_header[i]] = number_covert(col.text)
110-
111-
frame.append(info_dict)
112-
return pd.DataFrame(frame)

finvizfinance/group/performance.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
55
.. moduleauthor:: Tianning Li <[email protected]>
66
"""
7-
from finvizfinance.group.overview import Overview
7+
from finvizfinance.group.base import Base
88

99

10-
class Performance(Overview):
10+
class Performance(Base):
1111
"""Performance inherit from overview module.
1212
Getting information from the finviz group performance page.
1313
"""

0 commit comments

Comments
 (0)