diff --git a/requirements.txt b/requirements.txt index 5ea8b91e..f2c66007 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +1,15 @@ yahoo-fin==0.8.9.1 -numpy==1.26.1 -yfinance==0.2.31 +numpy==1.26.3 +yfinance==0.2.36 pycoingecko==3.1.0 -pandas==2.1.3 +pandas==2.2.0 requests==2.31.0 -discord==2.3.1 PyYAML==6.0.1 tradingview-ta==3.3.0 aiohttp>=3.8.0 asyncpraw==7.7.1 -ccxt==4.1.76 -transformers==4.35.0 +ccxt==4.2.36 +transformers==4.37.2 matplotlib==3.8.2 scipy==1.11.4 brotli==1.1.0 diff --git a/src/cogs/loops/assets.py b/src/cogs/loops/assets.py index 47f11339..c5d13d0e 100644 --- a/src/cogs/loops/assets.py +++ b/src/cogs/loops/assets.py @@ -122,6 +122,7 @@ async def assets(self) -> None: async def update_prices_and_changes(self, new_df): # Filter DataFrame to only include rows where exchange is "Stock" + print("New_df in assets:") print(new_df) stock_df = new_df[new_df["exchange"] == "Stock"] @@ -137,7 +138,9 @@ async def get_price_change(row): results = await asyncio.gather( *(get_price_change(row) for _, row in stock_df.iterrows()) ) + print("Stock_df in assets:") print(stock_df) + print("Results in assets:") print(results) # Update the DataFrame with the results @@ -333,7 +336,7 @@ async def get_user(self, assets): id = assets["id"].values[0] disc_user = self.bot.get_user(id) - if disc_user == None: + if disc_user is None: try: disc_user = await get_user(self.bot, id) except Exception as e: diff --git a/src/cogs/loops/stocktwits.py b/src/cogs/loops/stocktwits.py index 73970a2a..4a4fcd45 100644 --- a/src/cogs/loops/stocktwits.py +++ b/src/cogs/loops/stocktwits.py @@ -62,8 +62,11 @@ async def get_data(self, e: discord.Embed, keyword: str) -> discord.Embed: full_df = pd.merge(stocks, table, on="stock_id") full_df.sort_values(by="val", ascending=False, inplace=True) - # Fill all NaN / None values with 0, in case the price is not known - full_df = full_df.fillna(0) + # Set types + full_df["price"] = full_df["price"].astype(float).fillna(0) + full_df["change"] = full_df["change"].astype(float).fillna(0) + full_df["symbol"] = full_df["symbol"].astype(str) + full_df["name"] = full_df["name"].astype(str) # Format % change full_df["change"] = full_df["change"].apply( diff --git a/src/main.py b/src/main.py index 4c9bc442..8140fd99 100644 --- a/src/main.py +++ b/src/main.py @@ -1,12 +1,6 @@ #!/usr/bin/env python3 # Python 3.8.11 -# Do this first -from dotenv import load_dotenv - -# Load the .env file -load_dotenv() - ##> Imports # > Standard library import os @@ -17,6 +11,10 @@ # Discord libraries import discord from discord.ext import commands +from dotenv import load_dotenv + +# Load the .env file +load_dotenv() # Import local dependencies from util.vars import config @@ -64,7 +62,7 @@ def load_folder(foldername: str) -> None: # Check the contents of the file in the folder if config[foldername.upper()][file]: # If the file type is not a boolean, check if it is enabled - if not type(config[foldername.upper()][file]) == bool: + if not isinstance(config[foldername.upper()][file], bool): # Check if the ENABLED key exists if "ENABLED" in config[foldername.upper()][file]: # Append if enabled == True @@ -125,16 +123,5 @@ def load_folder(foldername: str) -> None: sys.exit(1) # Main event loop - try: - bot.loop.run_until_complete(bot.run(TOKEN)) - except KeyboardInterrupt: - print("Caught interrupt signal.") - print("exiting...") - bot.loop.run_until_complete( - asyncio.wait( - [bot.change_presence(status=discord.Status.invisible), bot.logout()] - ) - ) - finally: - bot.loop.close() - sys.exit(0) + bot.run(TOKEN) + # If the bot randomly stops maybe put back old code diff --git a/src/util/cg_data.py b/src/util/cg_data.py index 967afa6a..844a6f41 100644 --- a/src/util/cg_data.py +++ b/src/util/cg_data.py @@ -75,7 +75,7 @@ def get_coin_exchanges(coin_dict: dict) -> tuple[str, list]: for info in coin_dict["tickers"]: if "base" in info.keys(): # Somtimes the base is a contract instead of ticker - if base == None: + if base is None: # > 7, because $KOMPETE if not (info["base"].startswith("0X") or len(info["base"]) > 7): base = info["base"] @@ -153,6 +153,7 @@ async def get_coin_info( coin_dict = None if ticker in util.vars.cg_db["symbol"].values: # Check coin by symbol, i.e. "BTC" + print("Cg_data ticker:") print(ticker) coin_dict, id = get_crypto_info( util.vars.cg_db[util.vars.cg_db["symbol"] == ticker]["id"] @@ -199,7 +200,7 @@ async def get_coin_info( exchanges = list(set(exchanges)) # Look into this! - if total_vol != 0 and base == None: + if total_vol != 0 and base is None: print("No base symbol found for:", ticker) base = ticker diff --git a/src/util/sentiment_analyis.py b/src/util/sentiment_analyis.py index b88d1851..40847dc1 100644 --- a/src/util/sentiment_analyis.py +++ b/src/util/sentiment_analyis.py @@ -1,6 +1,7 @@ ##> Imports # > Standard libaries from __future__ import annotations +import re # > Third party libraries import discord @@ -16,7 +17,9 @@ ) model.config.problem_type = "single_label_classification" tokenizer = AutoTokenizer.from_pretrained( - "StephanAkkerman/FinTwitBERT-sentiment", cache_dir="models/" + "StephanAkkerman/FinTwitBERT-sentiment", + cache_dir="models/", + add_special_tokens=True, ) model.eval() pipe = pipeline("text-classification", model=model, tokenizer=tokenizer) @@ -28,6 +31,16 @@ } +def preprocess_text(tweet: str) -> str: + # Replace URLs with URL token + tweet = re.sub(r"http\S+", "[URL]", tweet) + + # Replace @mentions with @USER token + tweet = re.sub(r"@\S+", "@USER", tweet) + + return tweet + + def classify_sentiment(text: str) -> tuple[str, str]: """ Uses the text of a tweet to classify the sentiment of the tweet. @@ -43,7 +56,7 @@ def classify_sentiment(text: str) -> tuple[str, str]: The probability of the tweet being bullish, neutral, or bearish. """ - label = pipe(text)[0].get("label") + label = pipe(preprocess_text(text))[0].get("label") emoji = label_to_emoji[label] label = f"{emoji} - {label.capitalize()}"