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

imported functions from telegram bot

This commit is contained in:
Anson 2020-06-10 22:24:31 -07:00
parent dbc24c0d88
commit 1a2cc312b2

View File

@ -1,38 +1,129 @@
import json import json
import os import os
import re import re
from datetime import datetime from datetime import datetime, timedelta
import requests import pandas as pd
import requests as r
IEX_TOKEN = os.environ["IEX"] from fuzzywuzzy import fuzz
import schedule
def getSymbols(text: str): class Symbol:
""" """
Takes a blob of text and returns a list of symbols without any repeats. Functions for finding stock market information about symbols.
""" """
SYMBOL_REGEX = "[$]([a-zA-Z]{1,4})" SYMBOL_REGEX = "[$]([a-zA-Z]{1,4})"
return list(set(re.findall(SYMBOL_REGEX, text))) searched_symbols = {}
help_text = """
Thanks for using this bot, consider supporting it by [buying me a beer.](https://www.buymeacoffee.com/Anson)
def symbolDataReply(symbols: list): Full documentation can be found [here.](https://simple-stock-bots.gitlab.io/site/telegram/)
**Commands**
- /dividend `$[symbol]` will return dividend information for the symbol.
- /news `$[symbol]` will return news about the symbol.
- /info `$[symbol]` will return general information about the symbol.
**Inline Features**
You can type @SimpleStockBot `[search]` in any chat or direct message to search for the stock bots full list of stock symbols and return the price of the ticker.
The bot also looks at every message in any chat it is in for stock symbols. Symbols start with a `$` followed by the stock symbol. For example: $tsla would return price information for Tesla Motors.
Market data is provided by [IEX Cloud](https://iexcloud.io)
""" """
Takes a list of symbols and returns a dictionary of strings with information about the symbol.
def __init__(self, IEX_TOKEN: str):
self.IEX_TOKEN = IEX_TOKEN
self.get_symbol_list()
schedule.every().day.do(self.get_symbol_list)
def get_symbol_list(self, return_df=False):
"""
Fetches a list of stock market symbols from FINRA
Returns:
pd.DataFrame -- [DataFrame with columns: Symbol | Issue_Name | Primary_Listing_Mkt
datetime -- The time when the list of symbols was fetched. The Symbol list is updated every open and close of every trading day.
"""
raw_symbols = r.get(
f"https://cloud.iexapis.com/stable/ref-data/symbols?token={self.IEX_TOKEN}"
).json()
symbols = pd.DataFrame(data=raw_symbols)
symbols["description"] = symbols["symbol"] + ": " + symbols["name"]
self.symbol_list = symbols
if return_df:
return symbols, datetime.now()
def search_symbols(self, search: str):
"""
Performs a fuzzy search to find stock symbols closest to a search term.
Arguments:
search {str} -- String used to search, could be a company name or something close to the companies stock ticker.
Returns:
List of Tuples -- A list tuples of every stock sorted in order of how well they match. Each tuple contains: (Symbol, Issue Name).
"""
schedule.run_pending()
search = search.lower()
try: # https://stackoverflow.com/a/3845776/8774114
return self.searched_symbols[search]
except KeyError:
pass
symbols = self.symbol_list
symbols["Match"] = symbols.apply(
lambda x: fuzz.ratio(search, f"{x['symbol']}".lower()), axis=1,
)
symbols.sort_values(by="Match", ascending=False, inplace=True)
if symbols["Match"].head().sum() < 300:
symbols["Match"] = symbols.apply(
lambda x: fuzz.partial_ratio(search, x["name"].lower()), axis=1,
)
symbols.sort_values(by="Match", ascending=False, inplace=True)
symbols = symbols.head(10)
symbol_list = list(zip(list(symbols["symbol"]), list(symbols["description"])))
self.searched_symbols[search] = symbol_list
return symbol_list
def find_symbols(self, text: str):
"""
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? -> ['tsla']
Arguments:
text {str} -- Blob of text that might contain tickers with the format: $TICKER
Returns:
list -- List of every found match without the dollar sign.
"""
return list(set(re.findall(self.SYMBOL_REGEX, text)))
def price_reply(self, symbols: list):
"""
Takes a list of symbols and replies with Markdown formatted text about the symbols price change for the day.
Arguments:
symbols {list} -- List of stock market symbols.
Returns:
dict -- Dictionary with keys of symbols and values of markdown formatted text example: {'tsla': 'The current stock price of Tesla Motors is $**420$$, the stock price is currently **up 42%**}
""" """
dataMessages = {} dataMessages = {}
for symbol in symbols: for symbol in symbols:
IEXurl = ( IEXurl = f"https://cloud.iexapis.com/stable/stock/{symbol}/quote?token={self.IEX_TOKEN}"
f"https://cloud.iexapis.com/stable/stock/{symbol}/quote?token={IEX_TOKEN}"
)
response = requests.get(IEXurl) response = r.get(IEXurl)
if response.status_code is 200: if response.status_code == 200:
IEXData = response.json() IEXData = response.json()
message = f"The current stock price of {IEXData['companyName']} is $**{IEXData['latestPrice']}**" message = f"The current stock price of {IEXData['companyName']} is $**{IEXData['latestPrice']}**"
# Determine wording of change text # Determine wording of change text
change = round(IEXData["changePercent"] * 100, 2) change = round(IEXData["changePercent"] * 100, 2)
if change > 0: if change > 0:
@ -48,14 +139,13 @@ def symbolDataReply(symbols: list):
return dataMessages return dataMessages
def dividend_reply(self, symbols: list):
def symbolDividend(symbols: list):
divMessages = {} divMessages = {}
for symbol in symbols: for symbol in symbols:
IEXurl = f"https://cloud.iexapis.com/stable/data-points/{symbol}/NEXTDIVIDENDDATE?token={IEX_TOKEN}" IEXurl = f"https://cloud.iexapis.com/stable/data-points/{symbol}/NEXTDIVIDENDDATE?token={self.IEX_TOKEN}"
response = requests.get(IEXurl) response = r.get(IEXurl)
if response.status_code is 200: if response.status_code == 200:
# extract date from json # extract date from json
date = response.json() date = response.json()
@ -77,18 +167,19 @@ def symbolDividend(symbols: list):
divMessages[symbol] = f"{symbol.upper()} is today." divMessages[symbol] = f"{symbol.upper()} is today."
else: else:
divMessages[symbol] = f"{symbol} either doesn't exist or pays no dividend." divMessages[
symbol
] = f"{symbol} either doesn't exist or pays no dividend."
return divMessages return divMessages
def news_reply(self, symbols: list):
def symbolNews(symbols: list):
newsMessages = {} newsMessages = {}
for symbol in symbols: for symbol in symbols:
IEXurl = f"https://cloud.iexapis.com/stable/stock/{symbol}/news/last/3?token={IEX_TOKEN}" IEXurl = f"https://cloud.iexapis.com/stable/stock/{symbol}/news/last/3?token={self.IEX_TOKEN}"
response = requests.get(IEXurl) response = r.get(IEXurl)
if response.status_code is 200: if response.status_code == 200:
data = response.json() data = response.json()
newsMessages[symbol] = f"News for **{symbol.upper()}**:\n" newsMessages[symbol] = f"News for **{symbol.upper()}**:\n"
for news in data: for news in data:
@ -101,17 +192,14 @@ def symbolNews(symbols: list):
return newsMessages return newsMessages
def info_reply(self, symbols: list):
def symbolInfo(symbols: list):
infoMessages = {} infoMessages = {}
for symbol in symbols: for symbol in symbols:
IEXurl = ( IEXurl = f"https://cloud.iexapis.com/stable/stock/{symbol}/company?token={self.IEX_TOKEN}"
f"https://cloud.iexapis.com/stable/stock/{symbol}/company?token={IEX_TOKEN}" response = r.get(IEXurl)
)
response = requests.get(IEXurl)
if response.status_code is 200: if response.status_code == 200:
data = response.json() data = response.json()
infoMessages[ infoMessages[
symbol symbol
@ -123,4 +211,3 @@ def symbolInfo(symbols: list):
] = f"No information found for: {symbol}\nEither today is boring or the symbol does not exist." ] = f"No information found for: {symbol}\nEither today is boring or the symbol does not exist."
return infoMessages return infoMessages