DISC Cleanup (#1058)

* Get rid/cleanup of marketbeat functions

* Get rid of last unused disc function + fix related tests

* fix test
This commit is contained in:
jmaslek
2021-12-15 09:59:41 -05:00
committed by GitHub
parent 680e0cd278
commit aacbc911be
12 changed files with 9 additions and 364 deletions

View File

@@ -4,7 +4,6 @@ __docformat__ = "numpy"
import argparse
import difflib
from datetime import datetime
from typing import List
from matplotlib import pyplot as plt
@@ -16,7 +15,6 @@ from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
check_non_negative,
check_positive,
valid_date,
check_int_range,
try_except,
system_clear,
@@ -639,7 +637,7 @@ NASDAQ Data Link (Formerly Quandl):
)
parser.add_argument(
"-a",
"-ascend",
"--ascend",
dest="ascend",
help="Flag to sort in ascending order",
action="store_true",
@@ -772,15 +770,7 @@ NASDAQ Data Link (Formerly Quandl):
default=5,
help="number of articles being printed",
)
parser.add_argument(
"-d",
"--date",
action="store",
dest="s_date",
type=valid_date,
default=datetime.now().strftime("%Y-%m-%d"),
help="starting date of articles",
)
parser.add_argument(
"--export",
choices=["csv", "json", "xlsx"],
@@ -798,10 +788,8 @@ NASDAQ Data Link (Formerly Quandl):
return
seeking_alpha_view.news(
news_type="trending",
article_id=ns_parser.n_id,
num=ns_parser.n_num,
start_date=ns_parser.s_date,
export=ns_parser.export,
)

View File

@@ -1,93 +0,0 @@
""" MarketBeat Model """
__docformat__ = "numpy"
from typing import List
import requests
from bs4 import BeautifulSoup
from gamestonk_terminal.helper_funcs import get_user_agent
def get_ratings_html(url_ratings: str) -> str:
"""Wraps HTTP requests.get for testibility
Parameters
----------
url_ratings : str
Ratings URL
Returns
-------
str
HTML page of ratings
"""
ratings_html = requests.get(
url_ratings, headers={"User-Agent": get_user_agent()}
).text
return ratings_html
def get_ratings() -> List[dict]:
"""Returns a list of ratings
Parameters
----------
None
Returns
-------
list
Ratings list
"""
ratings = []
url_ratings = "https://www.marketbeat.com/ratings/"
text_soup_ratings = BeautifulSoup(
get_ratings_html(url_ratings),
"lxml",
)
for stock_rows in text_soup_ratings.findAll("tr"):
tds = stock_rows.findAll("td")
if len(tds) == 8:
rating = {}
# company
td = tds[0]
company = td.find("div", {"class": "title-area"}).text
ticker = td.find("div", {"class": "ticker-area"}).text
rating["company"] = company
rating["ticker"] = ticker
# action
td = tds[1]
action = td.text
rating["action"] = action
# brokerage
td = tds[2]
brokerage = td.find("a").text
rating["brokerage"] = brokerage
# current price
td = tds[3]
if td.find("span"):
td.span.extract()
analyst = td.text
rating["analyst"] = analyst
# target price
td = tds[4]
current_price = td.text
rating["current_price"] = current_price
# new rating
td = tds[5]
target_price = td.text
rating["target_price"] = target_price
# impact on price
td = tds[6]
if td.find("a"):
rate = td.find("a").text
else:
rate = td.text
rating["rate"] = rate
ratings.append(rating)
return ratings

View File

@@ -1,127 +0,0 @@
""" MarketBeat View """
__docformat__ = "numpy"
import argparse
from typing import List
import numpy as np
import pandas as pd
from gamestonk_terminal.helper_funcs import (
check_positive,
parse_known_args_and_warn,
)
from gamestonk_terminal.stocks.discovery import marketbeat_model
def ratings_view(other_args: List[str]):
"""Prints top ratings updates [Source: MarketBeat]
MarketBeat has changed the access to their data. Now, a user needs to have 'MarketBeat All Access'
to make the most out of this command.
Parameters
----------
other_args : List[str]
argparse other args - ["-t", "100"]
"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="ratings",
description="""Top ratings updates. MarketBeat has changed the access to their data.
Now, a user needs to have 'MarketBeat All Access' to make the most out of this command.
[Source: MarketBeat]""",
)
parser.add_argument(
"-t",
"--threshold",
action="store",
dest="n_threshold",
type=check_positive,
default=0, # Change to 0 because of the preview shown by MarketBeat
help="Minimum threshold in percentage change between current and target price to show ratings",
)
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-t")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
ratings = marketbeat_model.get_ratings()
df_ratings = pd.DataFrame(ratings)
df_ratings = df_ratings[df_ratings["target_price"] != ""]
df_ratings["old_target"] = (
df_ratings["target_price"]
.apply(lambda x: x.split(" ➝ ")[0].replace("$", "") if "➝" in x else "")
.astype(float)
)
df_ratings["new_target"] = (
df_ratings["target_price"]
.apply(lambda x: x.split(" ➝ ")[1].replace("$", "") if "➝" in x else x)
.astype(float)
)
df_ratings["clean_current_price"] = (
df_ratings["current_price"]
.apply(lambda x: x.replace("0.0%", "").replace("+", "").replace("$", ""))
.astype(float)
)
df_ratings.drop(columns=["analyst", "current_price", "target_price"], inplace=True)
df_ratings["pct_increase"] = round(
100
* (df_ratings["new_target"] - df_ratings["clean_current_price"])
/ df_ratings["clean_current_price"],
2,
)
df_ratings = df_ratings.sort_values(by=["pct_increase"], ascending=False)
df_ratings["pct_abs"] = np.abs(df_ratings["pct_increase"])
df_ratings_top = df_ratings[df_ratings["pct_abs"] > ns_parser.n_threshold][
[
"ticker",
"action",
"brokerage",
"rate",
"old_target",
"new_target",
"clean_current_price",
"pct_increase",
]
]
df_ratings_top["old_target"] = df_ratings_top["old_target"].apply(
lambda x: str(x) + " $"
)
df_ratings_top["new_target"] = df_ratings_top["new_target"].apply(
lambda x: str(x) + " $"
)
df_ratings_top["clean_current_price"] = df_ratings_top["clean_current_price"].apply(
lambda x: str(x) + " $"
)
df_ratings_top["pct_increase"] = df_ratings_top["pct_increase"].apply(
lambda x: str(x) + " %"
)
df_ratings_top = df_ratings_top.rename(
columns={
"old_target": "Old Target",
"new_target": "New Target",
"clean_current_price": "Current Price",
"pct_increase": "Increase",
}
)
print(df_ratings_top.to_string(index=False))
print("")

View File

@@ -2,7 +2,6 @@
__docformat__ = "numpy"
from typing import List, Dict
from datetime import datetime
import requests
from bs4 import BeautifulSoup
import pandas as pd
@@ -90,59 +89,6 @@ def get_articles_html(url_articles: str) -> str:
return articles_html
def get_article_list(start_date: datetime, num: int) -> List[dict]:
"""Returns a list of latest articles
Parameters
----------
start_date : datetime
Starting date
num : int
Number of articles
Returns
-------
list
Latest articles list
"""
articles: List[dict] = []
page = 1
url_articles = f"https://seekingalpha.com/market-news/{page}"
while len(articles) < num:
text_soup_articles = BeautifulSoup(
get_articles_html(url_articles),
"lxml",
)
for item_row in text_soup_articles.findAll("li", {"class": "item"}):
item = item_row.find("a", {"class": "add-source-assigned"})
if item is None:
continue
article_url = item["href"]
if not article_url.startswith("/news/"):
continue
article_id = article_url.split("/")[2].split("-")[0]
article_date = datetime.strptime(
item_row["data-last-date"], "%Y-%m-%d %H:%M:%S %z"
)
if start_date.date() < article_date.date():
continue
articles.append(
{
"title": item.text,
"publishedAt": article_date.strftime("%Y-%m-%d %H:%M:%S"),
"url": "https://seekingalpha.com" + article_url,
"id": article_id,
}
)
page += 1
url_articles = f"https://seekingalpha.com/market-news/{page}"
return articles
def get_trending_list(num: int) -> list:
"""Returns a list of trending articles

View File

@@ -3,7 +3,6 @@ __docformat__ = "numpy"
from typing import List
import os
from datetime import datetime
from tabulate import tabulate
import pandas as pd
from gamestonk_terminal.helper_funcs import export_data
@@ -78,30 +77,22 @@ def upcoming_earning_release_dates(num_pages: int, num_earnings: int, export: st
)
def news(news_type: str, article_id: int, num: int, start_date: datetime, export: str):
def news(article_id: int, num: int, export: str):
"""Prints the latest news article list. [Source: Seeking Alpha]
Parameters
----------
news_type: str
Select between 'latest' or 'trending'
article_id: int
Article ID. If -1, none is selected
num: int
Number of articles to display. Only used if article_id is -1.
start_date : datetime
Date from when to get articles dates. Only used if article_id is -1.
export : str
Export dataframe data to csv,json,xlsx file
"""
# User wants to see all latest news
if article_id == -1:
if news_type == "latest":
articles = seeking_alpha_model.get_article_list(start_date, num)
elif news_type == "trending":
articles = seeking_alpha_model.get_trending_list(num)
else:
print("Wrong type of news selected", "\n")
articles = seeking_alpha_model.get_trending_list(num)
if export:
df_articles = pd.DataFrame(articles)
@@ -122,12 +113,7 @@ def news(news_type: str, article_id: int, num: int, start_date: datetime, export
# User wants to access specific article
else:
if news_type == "latest":
article = seeking_alpha_model.get_article_data(article_id)
elif news_type == "trending":
article = seeking_alpha_model.get_article_data(article_id)
else:
print("Wrong type of news selected", "\n")
article = seeking_alpha_model.get_article_data(article_id)
if export:
df_articles = pd.DataFrame(article)
@@ -147,7 +133,7 @@ def news(news_type: str, article_id: int, num: int, start_date: datetime, export
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
news_type,
"trending",
df_articles,
)

View File

@@ -1,6 +1,5 @@
# IMPORTATION STANDARD
import os
from datetime import datetime
# IMPORTATION THIRDPARTY
import pytest
@@ -248,14 +247,11 @@ def test_call_quit():
[
"--id=123",
"--num=5",
"--date=2020-12-02",
"--export=csv",
],
{
"news_type": "trending",
"article_id": 123,
"num": 5,
"start_date": datetime.strptime("2020-12-02", "%Y-%m-%d"),
"export": "csv",
},
),

View File

@@ -1,21 +0,0 @@
# IMPORTATION STANDARD
# IMPORTATION THIRDPARTY
import pytest
# IMPORTATION INTERNAL
from gamestonk_terminal.stocks.discovery import marketbeat_model
@pytest.fixture(scope="module")
def vcr_config():
return {
"filter_headers": [("User-Agent", None)],
}
@pytest.mark.vcr
def test_get_ratings(recorder):
ratings = marketbeat_model.get_ratings()
recorder.capture(ratings)

View File

@@ -1,21 +0,0 @@
# IMPORTATION STANDARD
# IMPORTATION THIRDPARTY
import pytest
# IMPORTATION INTERNAL
from gamestonk_terminal.stocks.discovery import marketbeat_view
@pytest.fixture(scope="module")
def vcr_config():
return {
"filter_headers": [("User-Agent", None)],
}
@pytest.mark.skip("Broken + unused ?")
@pytest.mark.vcr
@pytest.mark.record_stdout
def test_ratings_view():
marketbeat_view.ratings_view(other_args=[])

View File

@@ -1,5 +1,4 @@
# IMPORTATION STANDARD
from datetime import datetime
# IMPORTATION THIRDPARTY
import pytest
@@ -21,13 +20,6 @@ def test_get_next_earnings(recorder):
recorder.capture(df_earnings)
@pytest.mark.skip("Broken ?")
@pytest.mark.vcr
def test_get_article_list():
start_date = datetime.strptime("2020-12-10", "%Y-%m-%d")
seeking_alpha_model.get_article_list(start_date=start_date, num=2)
@pytest.mark.vcr
def test_get_trending_list(recorder):
trending_list = seeking_alpha_model.get_trending_list(num=2)

View File

@@ -1,5 +1,4 @@
# IMPORTATION STANDARD
from datetime import datetime
# IMPORTATION THIRDPARTY
import pytest
@@ -29,10 +28,8 @@ def test_upcoming_earning_release_dates():
@pytest.mark.record_stdout
def test_news():
seeking_alpha_view.news(
news_type="trending",
article_id=-1,
num=2,
start_date=datetime.strptime("2020-12-10", "%Y-%m-%d"),
export="",
)