From a4befde8ce1452237476b066ae0dac9f11f627a4 Mon Sep 17 00:00:00 2001 From: Anson Biggs Date: Sun, 28 Mar 2021 22:37:09 -0700 Subject: [PATCH] search now works with crypto --- IEX_Symbol.py | 5 ++++- bot.py | 17 ++++++++++------- cg_Crypto.py | 6 +++++- symbol_router.py | 30 +++++++++++++++++++++++++++--- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/IEX_Symbol.py b/IEX_Symbol.py index b29c6f3..232d190 100644 --- a/IEX_Symbol.py +++ b/IEX_Symbol.py @@ -58,7 +58,10 @@ class IEX_Symbol: ).json() symbols = pd.DataFrame(data=raw_symbols) - symbols["description"] = symbols["symbol"] + ": " + symbols["name"] + symbols["description"] = "$" + symbols["symbol"] + ": " + symbols["name"] + symbols["id"] = symbols["symbol"] + + symbols = symbols[["id", "symbol", "name", "description"]] self.symbol_list = symbols if return_df: return symbols, datetime.now() diff --git a/bot.py b/bot.py index 3267f40..dcb1871 100644 --- a/bot.py +++ b/bot.py @@ -229,9 +229,9 @@ def search(update: Update, context: CallbackContext): return context.bot.send_chat_action(chat_id=chat_id, action=telegram.ChatAction.TYPING) - queries = s.search_symbols(message)[:6] + queries = s.search_symbols(message)[:10] if queries: - reply = "*Search Results:*\n`$ticker: Company Name`\n" + reply = "*Search Results:*\n`$ticker: Company Name`\n`" + ("-" * 21) + "`\n" for query in queries: reply += "`" + query[1] + "`\n" update.message.reply_text(text=reply, parse_mode=telegram.ParseMode.MARKDOWN) @@ -373,10 +373,13 @@ def inline_query(update: Update, context: CallbackContext): matches = s.search_symbols(update.inline_query.query) + symbols = " ".join([match[1].split(":")[0] for match in matches]) + prices = s.price_reply(s.find_symbols(symbols)) + results = [] - for match in matches: + for match, price in zip(matches, prices): + print(match) try: - price = s.price_reply([match[0]])[0] results.append( InlineQueryResultArticle( match[0], @@ -390,7 +393,7 @@ def inline_query(update: Update, context: CallbackContext): logging.warning(str(match)) pass - if len(results) == 5: + if len(results) == 10: update.inline_query.answer(results) return @@ -423,8 +426,8 @@ def error(update: Update, context: CallbackContext): ) # Finally, send the message - update.message.reply_text(text=message, parse_mode=telegram.ParseMode.HTML) - update.message.reply_text(text="Please inform the bot admin of this issue.") + # update.message.reply_text(text=message, parse_mode=telegram.ParseMode.HTML) + # update.message.reply_text(text="Please inform the bot admin of this issue.") def main(): diff --git a/cg_Crypto.py b/cg_Crypto.py index 6323188..6ba1686 100644 --- a/cg_Crypto.py +++ b/cg_Crypto.py @@ -47,7 +47,9 @@ class cg_Crypto: raw_symbols = r.get("https://api.coingecko.com/api/v3/coins/list").json() symbols = pd.DataFrame(data=raw_symbols) - symbols["description"] = symbols["symbol"] + ": " + symbols["name"] + symbols["description"] = "$$" + symbols["symbol"] + ": " + symbols["name"] + symbols = symbols[["id", "symbol", "name", "description"]] + self.symbol_list = symbols if return_df: return symbols, datetime.now() @@ -131,6 +133,8 @@ class cg_Crypto: name = data["name"] price = data["market_data"]["current_price"][self.vs_currency] change = data["market_data"]["price_change_percentage_24h"] + if change is None: + change = 0 except KeyError: return f"{symbol} returned an error." diff --git a/symbol_router.py b/symbol_router.py index d143061..de12731 100644 --- a/symbol_router.py +++ b/symbol_router.py @@ -5,6 +5,7 @@ import re import pandas as pd import random import datetime +from fuzzywuzzy import fuzz from typing import List, Tuple @@ -17,6 +18,7 @@ from Symbol import Symbol, Stock, Coin class Router: STOCK_REGEX = "(?:^|[^\\$])\\$([a-zA-Z]{1,6})" CRYPTO_REGEX = "[$]{2}([a-zA-Z]{1,20})" + searched_symbols = {} def __init__(self): self.stock = IEX_Symbol() @@ -87,10 +89,31 @@ class Router: List[tuple[str, str]] A list tuples of every stock sorted in order of how well they match. Each tuple contains: (Symbol, Issue Name). """ - # TODO add support for crypto - return self.stock.search_symbols(search) - def price_reply(self, symbols: list) -> List[str]: + df = pd.concat([self.stock.symbol_list, self.crypto.symbol_list]) + + search = search.lower() + + df["Match"] = df.apply( + lambda x: fuzz.ratio(search, f"{x['symbol']}".lower()), + axis=1, + ) + + df.sort_values(by="Match", ascending=False, inplace=True) + if df["Match"].head().sum() < 300: + df["Match"] = df.apply( + lambda x: fuzz.partial_ratio(search, x["name"].lower()), + axis=1, + ) + + df.sort_values(by="Match", ascending=False, inplace=True) + + symbols = df.head(10) + symbol_list = list(zip(list(symbols["symbol"]), list(symbols["description"]))) + self.searched_symbols[search] = symbol_list + return symbol_list + + def price_reply(self, symbols: list[Symbol]) -> List[str]: """Returns current market price or after hours if its available for a given stock symbol. Parameters @@ -107,6 +130,7 @@ class Router: replies = [] for symbol in symbols: + print(symbol) if isinstance(symbol, Stock): replies.append(self.stock.price_reply(symbol)) elif isinstance(symbol, Coin):