-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathshorts.py
More file actions
executable file
·106 lines (96 loc) · 3.62 KB
/
Copy pathshorts.py
File metadata and controls
executable file
·106 lines (96 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env python3
import json, re, sys
from lib.config import *
from lib import sharesight
from lib import webhook
from lib import util
from lib import yahoo
from lib import shortman
def lambda_handler(chat_id=config_telegramChatID, threshold=config_shorts_percent, specific_stock=None, service=None, interactive=False):
def prepare_shorts_payload(service, market_data):
payload = []
chart_rows = []
graph = False
emoji = "🩳"
for ticker in tickers:
try:
short_percent = float(market_data[ticker]['short_percent'])
except (KeyError, ValueError):
continue
if '.AX' in ticker:
url = 'https://www.shortman.com.au/stock?q=' + ticker.split('.')[0]
short_interest_link = util.link(url, ticker.split('.')[0], service)
else:
url = 'https://finance.yahoo.com/quote/' + ticker + '/key-statistics?p=' + ticker
short_interest_link = util.link(url, ticker.split('.')[0], service)
title = market_data[ticker]['profile_title']
if short_percent > threshold or specific_stock:
payload.append([emoji, title, f'({short_interest_link})', short_percent])
chart_rows.append((ticker.split('.')[0], short_percent))
def last_element(e):
return e[-1]
payload.sort(key=last_element)
for i, e in enumerate(payload):
e[-1] = str(round(e[-1])) + '%'
payload[i] = ' '.join(e)
if payload:
if not specific_stock:
message = f'Tracked stocks shorted over {threshold}%:'
caption_message = webhook.bold(message.rstrip(':'), service) # chart captions don't end in a colon
message = webhook.bold(message, service)
payload.insert(0, message)
if chart_rows and (interactive or service == 'telegram'): # Slack/Discord cron posts have no way to upload an image
chart_rows.sort(key=lambda row: row[1], reverse=True)
graph = util.column_chart(chart_rows, f"Shorted over {threshold}%", f"% of shares shorted; dashed line is the {threshold}% threshold",
lambda v: f"{round(v)}%", threshold=threshold, axis_fmt=lambda v: f"{v:g}%")
payload = [caption_message] # the chart replaces the list
else:
if interactive:
if specific_stock:
payload = [f"{emoji}No short interest found for {tickers[0]}"]
else:
payload = [f"{emoji}No stocks shorted over {threshold}%. Try specifying a number."]
return payload, graph
# MAIN #
if specific_stock:
ticker = util.transform_to_yahoo(specific_stock)
tickers = [ticker]
else:
tickers = util.get_holdings_and_watchlist()
market_data = yahoo.fetch(tickers)
for ticker in tickers:
if '.' not in ticker:
try:
market_data = market_data | yahoo.fetch_detail(ticker)
except TypeError:
pass
print("")
market_data = shortman.fetch(market_data)
# Prep and send payloads
if not webhooks:
print("Error: no services enabled in .env", file=sys.stderr)
sys.exit(1)
if interactive:
payload, graph = prepare_shorts_payload(service, market_data)
url = webhooks[service]
if service == "slack":
url = 'https://slack.com/api/chat.postMessage'
elif service == "telegram":
url = url + "sendMessage?chat_id=" + str(chat_id)
if graph:
webhook.sendPhoto(chat_id, graph, '\n'.join(payload), service)
else:
webhook.payload_wrapper(service, url, payload, chat_id)
else:
for service, url in webhooks.items():
payload, graph = prepare_shorts_payload(service, market_data)
if service == "telegram":
url = url + "sendMessage?chat_id=" + str(chat_id)
if graph:
webhook.sendPhoto(chat_id, graph, '\n'.join(payload), service)
continue
webhook.payload_wrapper(service, url, payload, chat_id)
# make google cloud happy
return True
if __name__ == "__main__":
webhook.guarded('shorts.py', lambda_handler)