mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 04:31:13 +00:00
Add DD from Reddit to Fundamental Analysis
This commit is contained in:
@@ -14,6 +14,7 @@ from fundamental_analysis import alpha_vantage_api as av_api
|
||||
from fundamental_analysis import financial_modeling_prep_api as fmp_api
|
||||
from fundamental_analysis import finviz_api as fvz_api
|
||||
from fundamental_analysis import market_watch_api as mw_api
|
||||
from fundamental_analysis import reddit_api as r_api
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
@@ -33,6 +34,7 @@ def print_fundamental_analysis(s_ticker, s_start, s_interval):
|
||||
print(" q quit this menu, and shows back to main menu")
|
||||
print(" quit quit to abandon program")
|
||||
print("")
|
||||
print(" dd gets due diligence from another user's post [Reddit]")
|
||||
print(" warnings company warnings according to Sean Seah book [Market Watch]")
|
||||
print("\nFinviz API")
|
||||
print(" screener screen info about the company")
|
||||
@@ -113,7 +115,7 @@ def fa_menu(s_ticker, s_start, s_interval):
|
||||
|
||||
# Add list of arguments that the fundamental analysis parser accepts
|
||||
fa_parser = argparse.ArgumentParser(prog='fundamental_analysis', add_help=False)
|
||||
fa_parser.add_argument('cmd', choices=['info', 'warnings', 'help', 'q', 'quit', 'more',
|
||||
fa_parser.add_argument('cmd', choices=['info', 'help', 'q', 'quit', 'more', 'warnings', 'dd',
|
||||
'screener', 'insider', 'news', 'analyst', # Finviz
|
||||
'income', 'assets', 'liabilities', 'operating', 'investing', 'financing', 'sec']) # MW
|
||||
|
||||
@@ -146,6 +148,9 @@ def fa_menu(s_ticker, s_start, s_interval):
|
||||
# Abandon the program
|
||||
return True
|
||||
|
||||
elif ns_known_args.cmd == 'dd':
|
||||
r_api.due_diligence(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.cmd == 'warnings':
|
||||
mw_api.sean_seah_warnings(l_args, s_ticker)
|
||||
|
||||
|
||||
114
fundamental_analysis/reddit_api.py
Normal file
114
fundamental_analysis/reddit_api.py
Normal file
@@ -0,0 +1,114 @@
|
||||
import argparse
|
||||
from prettytable import PrettyTable
|
||||
from datetime import datetime, timedelta
|
||||
import pandas as pd
|
||||
from psaw import PushshiftAPI
|
||||
import praw
|
||||
from datetime import datetime
|
||||
from pytz import timezone
|
||||
from holidays import US as holidaysUS
|
||||
from stock_market_helper_funcs import *
|
||||
import re
|
||||
import finviz
|
||||
import config_bot as cfg
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def due_diligence(l_args, s_ticker):
|
||||
parser = argparse.ArgumentParser(prog='dd',
|
||||
description=""" Search for a stock's due diligence [Reddit] """)
|
||||
parser.add_argument('-l', "--limit", action="store", dest="n_limit", type=check_positive, default=5,
|
||||
help='Limit of posts with the watchlist word')
|
||||
parser.add_argument('-d', "--days", action="store", dest="n_days", type=check_positive, default=3,
|
||||
help="Look for a watchlist created on the past n days")
|
||||
parser.add_argument('-a', "--all", action="store_true", dest="b_all", default=False,
|
||||
help=""" Search through all flairs (apart from Yolo and Meme), otherwise we focus on the
|
||||
flairs: DD, technical analysis, Catalyst, News, Advice, Chart """)
|
||||
|
||||
try:
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
if l_unknown_args:
|
||||
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
|
||||
return
|
||||
|
||||
praw_api = praw.Reddit(client_id=cfg.API_REDDIT_CLIENT_ID,
|
||||
client_secret=cfg.API_REDDIT_CLIENT_SECRET,
|
||||
username=cfg.API_REDDIT_USERNAME,
|
||||
user_agent=cfg.API_REDDIT_USER_AGENT,
|
||||
password=cfg.API_REDDIT_PASSWORD)
|
||||
|
||||
psaw_api = PushshiftAPI()
|
||||
|
||||
n_ts_after = int((datetime.today() - timedelta(days=ns_parser.n_days)).timestamp())
|
||||
l_flair_text = ['DD', 'technical analysis', 'Catalyst', 'News', 'Advice', 'Chart']
|
||||
l_sub_reddits = ['pennystocks', 'RobinHoodPennyStocks', 'Daytrading', 'StockMarket', 'stocks', 'investing', 'wallstreetbets']
|
||||
|
||||
submissions = psaw_api.search_submissions(after=int(n_ts_after),
|
||||
subreddit=l_sub_reddits,
|
||||
q=s_ticker,
|
||||
filter=['id'])
|
||||
d_submission = {}
|
||||
n_flair_posts_found = 0
|
||||
while True:
|
||||
submission = next(submissions, None)
|
||||
if submission:
|
||||
# Get more information about post using PRAW api
|
||||
submission = praw_api.submission(id=submission.id)
|
||||
|
||||
# Ensure that the post hasn't been removed in the meanwhile
|
||||
if not submission.removed_by_category:
|
||||
|
||||
# Either just filter out Yolo, and Meme flairs, or focus on DD, based on b_DD flag
|
||||
if (submission.link_flair_text in l_flair_text,
|
||||
submission.link_flair_text not in ['Yolo', 'Meme'])[ns_parser.b_all]:
|
||||
|
||||
# Refactor data
|
||||
s_datetime = datetime.utcfromtimestamp(submission.created_utc).strftime("%d/%m/%Y %H:%M:%S")
|
||||
s_link = f"https://www.reddit.com{submission.permalink}"
|
||||
s_all_awards = ""
|
||||
for award in submission.all_awardings:
|
||||
s_all_awards += f"{award['count']} {award['name']}\n"
|
||||
s_all_awards = s_all_awards[:-2]
|
||||
|
||||
# Create dictionary with data to construct dataframe allows to save data
|
||||
d_submission[submission.id] = {
|
||||
'created_utc': s_datetime,
|
||||
'subreddit': submission.subreddit,
|
||||
'link_flair_text': submission.link_flair_text,
|
||||
'title':submission.title,
|
||||
'score': submission.score,
|
||||
'link': s_link,
|
||||
'num_comments': submission.num_comments,
|
||||
'upvote_ratio': submission.upvote_ratio,
|
||||
'awards': s_all_awards
|
||||
}
|
||||
|
||||
# Print post data collected so far
|
||||
print(f"{s_datetime} - {submission.title}")
|
||||
print(f"{s_link}")
|
||||
t_post = PrettyTable(['Subreddit', 'Flair', 'Score', '# Comments', 'Upvote %', "Awards"])
|
||||
t_post.add_row([submission.subreddit, submission.link_flair_text, submission.score,
|
||||
submission.num_comments,f"{round(100*submission.upvote_ratio)}%", s_all_awards])
|
||||
print(t_post)
|
||||
print("\n")
|
||||
|
||||
# If needed, submission.comments could give us the top comments
|
||||
|
||||
# Increment count of valid posts found
|
||||
n_flair_posts_found += 1
|
||||
|
||||
# Check if number of wanted posts found has been reached
|
||||
if n_flair_posts_found > ns_parser.n_limit-1:
|
||||
break
|
||||
|
||||
# Check if search_submissions didn't get anymore posts
|
||||
else:
|
||||
break
|
||||
|
||||
print(f"{('No more posts with specified requirements found.', '')[n_flair_posts_found > ns_parser.n_limit-1]}")
|
||||
# Create df with found data. Useful for saving all info in excel file.
|
||||
#df_submissions = pd.DataFrame.from_dict(d_submission, orient='index', columns=list(d_submission[next(iter(d_submission.keys()))].keys()))
|
||||
#df_submissions.sort_values(by=['created_utc'], inplace=True, ascending=True)
|
||||
|
||||
except:
|
||||
print("")
|
||||
Reference in New Issue
Block a user