From 0163ecdeef60cfb7284601ec6d525a22b27a98be Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Sat, 26 Oct 2024 16:25:22 +0200 Subject: [PATCH] update rules --- app/cron_info_text.py | 6 +++++ app/cron_statistics.py | 30 +++++++++++++++++++++++ app/restart_json.py | 55 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 app/cron_statistics.py diff --git a/app/cron_info_text.py b/app/cron_info_text.py index 02c0ca2..8a21a77 100644 --- a/app/cron_info_text.py +++ b/app/cron_info_text.py @@ -536,6 +536,12 @@ data = { "text": "Operating margin is the percentage of revenue left as operating income, after subtracting cost of revenue and all operating expenses from the revenue.", "equation": "Operating Margin = (Operating Income / Revenue) * 100%", }, + "sharesQoQ": { + "text": "The change in the number of shares outstanding, comparing the most recent quarter to the previous quarter.", + }, + "sharesYoY": { + "text": "The change in the number of shares outstanding, comparing the most recent quarter to the same quarter a year ago.", + }, } diff --git a/app/cron_statistics.py b/app/cron_statistics.py new file mode 100644 index 0000000..cabecc2 --- /dev/null +++ b/app/cron_statistics.py @@ -0,0 +1,30 @@ +from datetime import datetime, timedelta +import orjson +import time +import sqlite3 +import asyncio +import aiohttp +import random +from tqdm import tqdm +from dotenv import load_dotenv +import os + + +stock_screener_data_dict = {item['symbol']: item for item in stock_screener_data} + + + + +async def run(): + con = sqlite3.connect('stocks.db') + cursor = con.cursor() + cursor.execute("PRAGMA journal_mode = wal") + cursor.execute("SELECT DISTINCT symbol FROM stocks WHERE symbol NOT LIKE '%.%'") + total_symbols = [row[0] for row in cursor.fetchall()] + con.close() + + + +if __name__ == "__main__": + loop = asyncio.get_event_loop() + loop.run_until_complete(run()) \ No newline at end of file diff --git a/app/restart_json.py b/app/restart_json.py index 75f4c0a..29d1754 100755 --- a/app/restart_json.py +++ b/app/restart_json.py @@ -40,6 +40,16 @@ query_price = """ LIMIT 1 """ +query_shares = f""" + SELECT + historicalShares + FROM + stocks + WHERE + symbol = ? +""" + + time_frames = { 'change1W': (datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d'), 'change1M': (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d'), @@ -69,6 +79,50 @@ def calculate_price_changes(symbol, item, con): for name in time_frames.keys(): item[name] = None +def filter_data_quarterly(data): + # Generate a range of quarter-end dates from the start to the end date + start_date = data[0]['date'] + end_date = datetime.today().strftime('%Y-%m-%d') + quarter_ends = pd.date_range(start=start_date, end=end_date, freq='QE').strftime('%Y-%m-%d').tolist() + + # Filter data to keep only entries with dates matching quarter-end dates + filtered_data = [entry for entry in data if entry['date'] in quarter_ends] + + return filtered_data + +def calculate_share_changes(symbol, item, con): + item['sharesQoQ'] = None + item['sharesYoY'] = None + try: + # Execute query and load data + df = pd.read_sql_query(query_shares, con, params=(symbol,)) + shareholder_statistics = orjson.loads(df.to_dict()['historicalShares'][0]) + + # Keys to keep + keys_to_keep = ["date", "floatShares", "outstandingShares"] + + # Create new list with only the specified keys and convert floatShares and outstandingShares to integers + shareholder_statistics = [ + {key: int(d[key]) if key in ["floatShares", "outstandingShares"] else d[key] + for key in keys_to_keep} + for d in shareholder_statistics + ] + + shareholder_statistics = sorted(shareholder_statistics, key=lambda x: datetime.strptime(x['date'], '%Y-%m-%d'), reverse=False) + + historical_shares = filter_data_quarterly(shareholder_statistics) + + latest_data = historical_shares[-1]['outstandingShares'] + previous_quarter = historical_shares[-2]['outstandingShares'] + previous_year = historical_shares[-4]['outstandingShares'] + + item['sharesQoQ'] = round((latest_data/previous_quarter-1)*100,2) + item['sharesYoY'] = round((latest_data/previous_year-1)*100,2) + except: + item['sharesQoQ'] = None + item['sharesYoY'] = None + + # Replace NaN values with None in the resulting JSON object def replace_nan_inf_with_none(obj): if isinstance(obj, list): @@ -501,6 +555,7 @@ async def get_stock_screener(con): item['marketCap'] = None calculate_price_changes(symbol, item, con) + calculate_share_changes(symbol, item, con) try: