update rules
This commit is contained in:
parent
dca7d93f62
commit
0163ecdeef
@ -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.",
|
"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%",
|
"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.",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
30
app/cron_statistics.py
Normal file
30
app/cron_statistics.py
Normal file
@ -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())
|
||||||
@ -40,6 +40,16 @@ query_price = """
|
|||||||
LIMIT 1
|
LIMIT 1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
query_shares = f"""
|
||||||
|
SELECT
|
||||||
|
historicalShares
|
||||||
|
FROM
|
||||||
|
stocks
|
||||||
|
WHERE
|
||||||
|
symbol = ?
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
time_frames = {
|
time_frames = {
|
||||||
'change1W': (datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d'),
|
'change1W': (datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d'),
|
||||||
'change1M': (datetime.now() - timedelta(days=30)).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():
|
for name in time_frames.keys():
|
||||||
item[name] = None
|
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
|
# Replace NaN values with None in the resulting JSON object
|
||||||
def replace_nan_inf_with_none(obj):
|
def replace_nan_inf_with_none(obj):
|
||||||
if isinstance(obj, list):
|
if isinstance(obj, list):
|
||||||
@ -501,6 +555,7 @@ async def get_stock_screener(con):
|
|||||||
item['marketCap'] = None
|
item['marketCap'] = None
|
||||||
|
|
||||||
calculate_price_changes(symbol, item, con)
|
calculate_price_changes(symbol, item, con)
|
||||||
|
calculate_share_changes(symbol, item, con)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user