mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 12:40:35 +00:00
Add Insider Activity over time command from Business Insider
This commit is contained in:
@@ -201,3 +201,116 @@ def estimates(l_args, s_ticker):
|
||||
except:
|
||||
print("")
|
||||
return
|
||||
|
||||
|
||||
# ----------------------------------------------- INSIDER_ACTIVITY -----------------------------------------------
|
||||
def insider_activity(l_args, df_stock, s_ticker, s_start, s_interval):
|
||||
parser = argparse.ArgumentParser(prog='insider_activity',
|
||||
description="""Insider activity over time [Source: Business Insider API]""")
|
||||
parser.add_argument('-n', "--num", action="store", dest="n_num", type=check_positive, default=10, help='Number of latest insider activity')
|
||||
|
||||
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
|
||||
|
||||
url_market_business_insider = f"https://markets.businessinsider.com/stocks/{s_ticker.lower()}-stock"
|
||||
text_soup_market_business_insider = BeautifulSoup(requests.get(url_market_business_insider).text, "lxml")
|
||||
|
||||
d_insider = dict()
|
||||
l_insider_vals = list()
|
||||
for idx, insider_val in enumerate(text_soup_market_business_insider.findAll('td', {'class':"table__td text-center"})):
|
||||
#print(insider_val.text.strip())
|
||||
|
||||
l_insider_vals.append(insider_val.text.strip())
|
||||
|
||||
# Add value to dictionary
|
||||
if (idx+1)%6 == 0:
|
||||
# Check if we are still parsing insider trading activity
|
||||
if '/' not in l_insider_vals[0]:
|
||||
break
|
||||
d_insider[(idx+1)//6] = l_insider_vals
|
||||
l_insider_vals = list()
|
||||
|
||||
df_insider = pd.DataFrame.from_dict(d_insider, orient='index',
|
||||
columns = ['Date', 'Shares Traded', 'Shares Held', 'Price', 'Type', 'Option'])
|
||||
|
||||
df_insider['Date'] = pd.to_datetime(df_insider['Date'])
|
||||
df_insider = df_insider.set_index('Date')
|
||||
df_insider = df_insider.sort_index(ascending=True)
|
||||
|
||||
if s_start:
|
||||
df_insider = df_insider[s_start:]
|
||||
|
||||
pfig, ax = plt.subplots()
|
||||
|
||||
if s_interval == "1440min":
|
||||
plt.plot(df_stock.index, df_stock['5. adjusted close'].values, lw=3)
|
||||
else: # Intraday
|
||||
plt.plot(df_stock.index, df_stock['4. close'].values, lw=3)
|
||||
|
||||
plt.title(f"{s_ticker.upper()} (Time Series) and Price Target")
|
||||
|
||||
plt.xlabel('Time')
|
||||
plt.ylabel('Share Price ($)')
|
||||
|
||||
df_insider['Trade'] = df_insider.apply(lambda row: (1, -1)[row.Type == 'Sell'] * float(row['Shares Traded'].replace(',','')), axis=1)
|
||||
plt.xlim(df_insider.index[0], df_stock.index[-1])
|
||||
min_price, max_price = ax.get_ylim()
|
||||
|
||||
price_range = max_price - min_price
|
||||
shares_range = df_insider[df_insider['Type'] == 'Buy'].groupby(by=['Date']).sum()['Trade'].max() - df_insider[df_insider['Type'] == 'Sell'].groupby(by=['Date']).sum()['Trade'].min()
|
||||
n_proportion = price_range / shares_range
|
||||
|
||||
for ind in df_insider[df_insider['Type'] == 'Sell'].groupby(by=['Date']).sum().index:
|
||||
if ind in df_stock.index:
|
||||
ind_dt = ind
|
||||
else:
|
||||
ind_dt = get_next_stock_market_days(ind, 1)[0]
|
||||
|
||||
n_stock_price = 0
|
||||
if s_interval == "1440min":
|
||||
n_stock_price = df_stock['5. adjusted close'][ind_dt]
|
||||
else:
|
||||
n_stock_price = df_stock['4. close'][ind_dt]
|
||||
|
||||
plt.vlines(x=ind_dt,
|
||||
ymin= n_stock_price + n_proportion * float(df_insider[df_insider['Type'] == 'Sell'].groupby(by=['Date']).sum()['Trade'][ind]),
|
||||
ymax= n_stock_price,
|
||||
colors='red', ls='-', lw=5)
|
||||
|
||||
for ind in df_insider[df_insider['Type'] == 'Buy'].groupby(by=['Date']).sum().index:
|
||||
if ind in df_stock.index:
|
||||
ind_dt = ind
|
||||
else:
|
||||
ind_dt = get_next_stock_market_days(ind, 1)[0]
|
||||
|
||||
n_stock_price = 0
|
||||
if s_interval == "1440min":
|
||||
n_stock_price = df_stock['5. adjusted close'][ind_dt]
|
||||
else:
|
||||
n_stock_price = df_stock['4. close'][ind_dt]
|
||||
|
||||
plt.vlines(x=ind_dt,
|
||||
ymin=n_stock_price,
|
||||
ymax=n_stock_price + n_proportion * float(df_insider[df_insider['Type'] == 'Buy'].groupby(by=['Date']).sum()['Trade'][ind]),
|
||||
colors='green', ls='-', lw=5)
|
||||
|
||||
plt.grid(b=True, which='major', color='#666666', linestyle='-')
|
||||
plt.minorticks_on()
|
||||
plt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2)
|
||||
plt.show()
|
||||
|
||||
l_names = list()
|
||||
for s_name in text_soup_market_business_insider.findAll('a', {'onclick':"silentTrackPI()"}):
|
||||
l_names.append(s_name.text.strip())
|
||||
df_insider['Insider'] = l_names
|
||||
|
||||
print(df_insider.sort_index(ascending=False).head(n=ns_parser.n_num).to_string())
|
||||
print("")
|
||||
|
||||
except:
|
||||
print("")
|
||||
return
|
||||
|
||||
@@ -40,6 +40,7 @@ def print_due_diligence(s_ticker, s_start, s_interval):
|
||||
print(" rating rating of the company from strong sell to strong buy [FMP]")
|
||||
print(" pt price targets over time [Business Insider]")
|
||||
print(" est quarter and year analysts earnings estimates [Business Insider]")
|
||||
print(" ins insider activity over time [Business Insider]")
|
||||
print(" insider insider trading of the company [Finviz]")
|
||||
print(" sec SEC filings [Market Watch]")
|
||||
print(" short short interest [Quandl]")
|
||||
@@ -57,7 +58,7 @@ def dd_menu(df_stock, s_ticker, s_start, s_interval):
|
||||
'red', # Reddit
|
||||
'short', # Quandl
|
||||
'rating', # FMP
|
||||
'pt', 'est', # BI
|
||||
'pt', 'est', 'ins', # BI
|
||||
'insider', 'news', 'analyst', # Finviz
|
||||
'warnings', 'sec']) # MW
|
||||
|
||||
@@ -108,6 +109,9 @@ def dd_menu(df_stock, s_ticker, s_start, s_interval):
|
||||
elif ns_known_args.cmd == 'est':
|
||||
bi_api.estimates(l_args, s_ticker)
|
||||
|
||||
elif ns_known_args.cmd == 'ins':
|
||||
bi_api.insider_activity(l_args, df_stock, s_ticker, s_start, s_interval)
|
||||
|
||||
# FINANCIAL MODELING PREP API
|
||||
elif ns_known_args.cmd == 'rating':
|
||||
fmp_api.rating(l_args, s_ticker)
|
||||
|
||||
Reference in New Issue
Block a user