1
0
mirror of https://gitlab.com/simple-stock-bots/simple-stock-bot.git synced 2025-06-16 15:17:28 +00:00

Happy with current coverage close # 46

This commit is contained in:
Anson Biggs 2021-02-11 16:00:49 -07:00
parent a44008234a
commit 9b100f4926
2 changed files with 67 additions and 58 deletions

6
bot.py
View File

@ -182,11 +182,9 @@ def dividend(update: Update, context: CallbackContext):
if symbols: if symbols:
context.bot.send_chat_action(chat_id=chat_id, action=telegram.ChatAction.TYPING) context.bot.send_chat_action(chat_id=chat_id, action=telegram.ChatAction.TYPING)
for symbol in symbols:
for reply in s.dividend_reply(symbols).items():
update.message.reply_text( update.message.reply_text(
text=reply[1], parse_mode=telegram.ParseMode.MARKDOWN text=s.dividend_reply(symbol), parse_mode=telegram.ParseMode.MARKDOWN
) )

View File

@ -1,6 +1,6 @@
import re import re
from datetime import datetime from datetime import datetime
from typing import Optional from typing import Optional, List, Tuple, Dict
import pandas as pd import pandas as pd
import requests as r import requests as r
@ -130,16 +130,18 @@ _Donations can only be made in a chat directly with @simplestockbot_
usage = r.get( usage = r.get(
f"https://cloud.iexapis.com/stable/account/metadata?token={self.IEX_TOKEN}" f"https://cloud.iexapis.com/stable/account/metadata?token={self.IEX_TOKEN}"
).json() ).json()
try:
if ( if (
usage["messagesUsed"] >= usage["messageLimit"] - 10000 usage["messagesUsed"] >= usage["messageLimit"] - 10000
and not usage["payAsYouGoEnabled"] and not usage["payAsYouGoEnabled"]
): ):
return "Bot may be out of IEX Credits." return "Bot may be out of IEX Credits."
else: else:
return "Bot has available IEX Credits" return "Bot has available IEX Credits."
except KeyError:
return "**IEX API could not be reached.**"
def search_symbols(self, search: str) -> list[list[str, str]]: def search_symbols(self, search: str) -> List[Tuple[str, str]]:
"""Performs a fuzzy search to find stock symbols closest to a search term. """Performs a fuzzy search to find stock symbols closest to a search term.
Parameters Parameters
@ -149,7 +151,7 @@ _Donations can only be made in a chat directly with @simplestockbot_
Returns Returns
------- -------
list[tuple[str, str]] List[tuple[str, str]]
A list tuples of every stock sorted in order of how well they match. Each tuple contains: (Symbol, Issue Name). A list tuples of every stock sorted in order of how well they match. Each tuple contains: (Symbol, Issue Name).
""" """
@ -179,7 +181,7 @@ _Donations can only be made in a chat directly with @simplestockbot_
self.searched_symbols[search] = symbol_list self.searched_symbols[search] = symbol_list
return symbol_list return symbol_list
def find_symbols(self, text: str) -> list[str]: def find_symbols(self, text: str) -> List[str]:
"""Finds stock tickers starting with a dollar sign in a blob of text and returns them in a list. """Finds stock tickers starting with a dollar sign in a blob of text and returns them in a list.
Only returns each match once. Example: Whats the price of $tsla? Only returns each match once. Example: Whats the price of $tsla?
@ -190,13 +192,13 @@ _Donations can only be made in a chat directly with @simplestockbot_
Returns Returns
------- -------
list[str] List[str]
List of stock symbols as strings without dollar sign. List of stock symbols as strings without dollar sign.
""" """
return list(set(re.findall(self.SYMBOL_REGEX, text))) return list(set(re.findall(self.SYMBOL_REGEX, text)))
def price_reply(self, symbols: list) -> dict[str, str]: def price_reply(self, symbols: list) -> Dict[str, str]:
"""Returns current market price or after hours if its available for a given stock symbol. """Returns current market price or after hours if its available for a given stock symbol.
Parameters Parameters
@ -206,8 +208,9 @@ _Donations can only be made in a chat directly with @simplestockbot_
Returns Returns
------- -------
dict[str, str] Dict[str, str]
Each symbol passed in is a key with its value being a human readable markdown formatted string of the symbols price and movement. Each symbol passed in is a key with its value being a human readable
markdown formatted string of the symbols price and movement.
""" """
dataMessages = {} dataMessages = {}
for symbol in symbols: for symbol in symbols:
@ -216,6 +219,16 @@ _Donations can only be made in a chat directly with @simplestockbot_
response = r.get(IEXurl) response = r.get(IEXurl)
if response.status_code == 200: if response.status_code == 200:
IEXData = response.json() IEXData = response.json()
keys = (
"isUSMarketOpen",
"extendedChangePercent",
"extendedPrice",
"companyName",
"latestPrice",
"changePercent",
)
if set(keys).issubset(IEXData):
try: # Some symbols dont return if the market is open try: # Some symbols dont return if the market is open
IEXData["isUSMarketOpen"] IEXData["isUSMarketOpen"]
@ -243,6 +256,8 @@ _Donations can only be made in a chat directly with @simplestockbot_
message += f", the stock is currently **down {change}%**" message += f", the stock is currently **down {change}%**"
else: else:
message += ", the stock hasn't shown any movement today." message += ", the stock hasn't shown any movement today."
else:
message = f"The symbol: {symbol} encountered and error. This could be due to "
else: else:
message = f"The symbol: {symbol} was not found." message = f"The symbol: {symbol} was not found."
@ -251,7 +266,7 @@ _Donations can only be made in a chat directly with @simplestockbot_
return dataMessages return dataMessages
def dividend_reply(self, symbols: list) -> dict[str, str]: def dividend_reply(self, symbol: str) -> Dict[str, str]:
"""Returns the most recent, or next dividend date for a stock symbol. """Returns the most recent, or next dividend date for a stock symbol.
Parameters Parameters
@ -261,10 +276,9 @@ _Donations can only be made in a chat directly with @simplestockbot_
Returns Returns
------- -------
dict[str, str] Dict[str, str]
Each symbol passed in is a key with its value being a human readable formatted string of the symbols div dates. Each symbol passed in is a key with its value being a human readable formatted string of the symbols div dates.
""" """
divMessages = {}
IEXurl = f"https://cloud.iexapis.com/stable/stock/msft/dividends/next?token={self.IEX_TOKEN}" IEXurl = f"https://cloud.iexapis.com/stable/stock/msft/dividends/next?token={self.IEX_TOKEN}"
response = r.get(IEXurl) response = r.get(IEXurl)
@ -287,11 +301,8 @@ _Donations can only be made in a chat directly with @simplestockbot_
else: else:
price = f"{IEXData['amount']} {IEXData['currency']}" price = f"{IEXData['amount']} {IEXData['currency']}"
# extract date from json
date = response.json()
# Pattern IEX uses for dividend date. # Pattern IEX uses for dividend date.
pattern = "%Y-%m-%d" pattern = "%Y-%m-%d"
divDate = datetime.strptime(date, pattern)
declared = datetime.strptime(IEXData["declaredDate"], pattern).strftime( declared = datetime.strptime(IEXData["declaredDate"], pattern).strftime(
"%A, %B %w" "%A, %B %w"
@ -304,7 +315,7 @@ _Donations can only be made in a chat directly with @simplestockbot_
daysDelta = ( daysDelta = (
datetime.strptime(IEXData["paymentDate"], pattern) - datetime.now() datetime.strptime(IEXData["paymentDate"], pattern) - datetime.now()
).days ).days
print(self.symbol_list)
return ( return (
f"The next dividend for ${self.symbol_list[self.symbol_list['symbol']==symbol.upper()]['description'].item()}" f"The next dividend for ${self.symbol_list[self.symbol_list['symbol']==symbol.upper()]['description'].item()}"
+ f" is on {payment} which is in {daysDelta} days." + f" is on {payment} which is in {daysDelta} days."
@ -314,7 +325,7 @@ _Donations can only be made in a chat directly with @simplestockbot_
return f"{symbol} either doesn't exist or pays no dividend." return f"{symbol} either doesn't exist or pays no dividend."
def news_reply(self, symbols: list) -> dict[str, str]: def news_reply(self, symbols: list) -> Dict[str, str]:
"""Gets recent english news on stock symbols. """Gets recent english news on stock symbols.
Parameters Parameters
@ -351,17 +362,17 @@ _Donations can only be made in a chat directly with @simplestockbot_
return newsMessages return newsMessages
def info_reply(self, symbols: list[str]) -> dict[str, str]: def info_reply(self, symbols: List[str]) -> Dict[str, str]:
"""Gets information on stock symbols. """Gets information on stock symbols.
Parameters Parameters
---------- ----------
symbols : list[str] symbols : List[str]
List of stock symbols. List of stock symbols.
Returns Returns
------- -------
dict[str, str] Dict[str, str]
Each symbol passed in is a key with its value being a human readable formatted string of the symbols information. Each symbol passed in is a key with its value being a human readable formatted string of the symbols information.
""" """
infoMessages = {} infoMessages = {}
@ -449,17 +460,17 @@ _Donations can only be made in a chat directly with @simplestockbot_
return pd.DataFrame() return pd.DataFrame()
def stat_reply(self, symbols: list[str]) -> dict[str, str]: def stat_reply(self, symbols: List[str]) -> Dict[str, str]:
"""Gets key statistics for each symbol in the list """Gets key statistics for each symbol in the list
Parameters Parameters
---------- ----------
symbols : list[str] symbols : List[str]
List of stock symbols List of stock symbols
Returns Returns
------- -------
dict[str, str] Dict[str, str]
Each symbol passed in is a key with its value being a human readable formatted string of the symbols statistics. Each symbol passed in is a key with its value being a human readable formatted string of the symbols statistics.
""" """
infoMessages = {} infoMessages = {}