From 1172635016ac56d48f0975ca4b84a04c28601f41 Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Wed, 5 Mar 2025 12:41:27 +0100 Subject: [PATCH] bugfixing hedge fund --- app/create_etf_db.py | 20 ++++++++++++++++++-- app/create_institute_db.py | 10 ++-------- app/create_stock_db.py | 20 +++++++++++++++++--- app/cron_hedge_funds.py | 20 ++++---------------- 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/app/create_etf_db.py b/app/create_etf_db.py index 9c1d5b4..5f07f2a 100755 --- a/app/create_etf_db.py +++ b/app/create_etf_db.py @@ -25,6 +25,22 @@ warnings.filterwarnings("ignore", category=RuntimeWarning, message="invalid valu start_date = datetime(2015, 1, 1).strftime("%Y-%m-%d") end_date = datetime.today().strftime("%Y-%m-%d") +def get_last_completed_quarter(): + today = datetime.today() + year = today.year + month = today.month + # Calculate the current quarter (1 to 4) + current_quarter = (month - 1) // 3 + 1 + + # The previous quarter is the last completed quarter. + # If we're in Q1, the previous quarter is Q4 of last year. + if current_quarter == 1: + return 4, year - 1 + else: + return current_quarter - 1, year + +# Get last completed quarter and its year +quarter, year = get_last_completed_quarter() if os.path.exists("backup_db/etf.db"): @@ -188,7 +204,7 @@ class ETFDatabase: f"https://financialmodelingprep.com/api/v3/etf-country-weightings/{symbol}?apikey={api_key}", f"https://financialmodelingprep.com/api/v3/quote/{symbol}?apikey={api_key}", f"https://financialmodelingprep.com/stable/dividends?symbol={symbol}&apikey={api_key}", - f"https://financialmodelingprep.com/api/v4/institutional-ownership/institutional-holders/symbol-ownership-percent?date=2023-09-30&symbol={symbol}&page=0&apikey={api_key}", + f"https://financialmodelingprep.com/stable/institutional-ownership/symbol-positions-summary?symbol={symbol}&year={year}&quarter={quarter}&apikey={api_key}", ] fundamental_data = {} @@ -238,7 +254,7 @@ class ETFDatabase: elif "dividends" in url: fundamental_data['etf_dividend'] = ujson.dumps(parsed_data) - elif "institutional-ownership/institutional-holders" in url: + elif "institutional-ownership" in url: fundamental_data['shareholders'] = ujson.dumps(parsed_data) except: diff --git a/app/create_institute_db.py b/app/create_institute_db.py index a81450d..aaf84c9 100755 --- a/app/create_institute_db.py +++ b/app/create_institute_db.py @@ -49,20 +49,14 @@ etf_dict = {normalize_name(etf['name']): etf['symbol'] for etf in etf_data} etf_symbols = [item['symbol'] for item in etf_data] -crypto_cursor = crypto_con.cursor() -crypto_cursor.execute("PRAGMA journal_mode = wal") -crypto_cursor.execute("SELECT DISTINCT symbol FROM cryptos") -crypto_symbols = [row[0] for row in crypto_cursor.fetchall()] - -total_symbols = stock_symbols + etf_symbols + crypto_symbols +total_symbols = stock_symbols + etf_symbols con.close() etf_con.close() -crypto_con.close() load_dotenv() api_key = os.getenv('FMP_API_KEY') -quarter_date = '2024-09-30' +quarter_date = '2024-12-31' diff --git a/app/create_stock_db.py b/app/create_stock_db.py index 57a35fa..b3df0d8 100755 --- a/app/create_stock_db.py +++ b/app/create_stock_db.py @@ -27,8 +27,22 @@ warnings.filterwarnings("ignore", category=RuntimeWarning, message="invalid valu start_date = datetime(2015, 1, 1).strftime("%Y-%m-%d") end_date = datetime.today().strftime("%Y-%m-%d") -quarter_date = '2024-06-30' +def get_last_completed_quarter(): + today = datetime.today() + year = today.year + month = today.month + # Calculate the current quarter (1 to 4) + current_quarter = (month - 1) // 3 + 1 + # The previous quarter is the last completed quarter. + # If we're in Q1, the previous quarter is Q4 of last year. + if current_quarter == 1: + return 4, year - 1 + else: + return current_quarter - 1, year + +# Get last completed quarter and its year +quarter, year = get_last_completed_quarter() if os.path.exists("backup_db/stocks.db"): os.remove('backup_db/stocks.db') @@ -104,7 +118,7 @@ class StockDatabase: f"https://financialmodelingprep.com/api/v4/historical/employee_count?symbol={symbol}&apikey={api_key}", f"https://financialmodelingprep.com/api/v3/historical-price-full/stock_split/{symbol}?apikey={api_key}", f"https://financialmodelingprep.com/api/v4/stock_peers?symbol={symbol}&apikey={api_key}", - f"https://financialmodelingprep.com/api/v4/institutional-ownership/institutional-holders/symbol-ownership-percent?date={quarter_date}&symbol={symbol}&page=0&apikey={api_key}", + f"https://financialmodelingprep.com/stable/institutional-ownership/symbol-positions-summary?symbol={symbol}&year={year}&quarter={quarter}&apikey={api_key}", f"https://financialmodelingprep.com/api/v4/historical/shares_float?symbol={symbol}&apikey={api_key}", f"https://financialmodelingprep.com/api/v4/revenue-product-segmentation?symbol={symbol}&structure=flat&period=annual&apikey={api_key}", f"https://financialmodelingprep.com/api/v4/revenue-geographic-segmentation?symbol={symbol}&structure=flat&apikey={api_key}", @@ -165,7 +179,7 @@ class StockDatabase: elif "stock_peers" in url: # Handle list response, save as JSON object fundamental_data['stock_peers'] = ujson.dumps([item for item in parsed_data[0]['peersList'] if item != ""]) - elif "institutional-ownership/institutional-holders" in url: + elif "institutional-ownership" in url: # Handle list response, save as JSON object fundamental_data['shareholders'] = ujson.dumps(parsed_data) elif "historical/shares_float" in url: diff --git a/app/cron_hedge_funds.py b/app/cron_hedge_funds.py index bbb4d22..7e30cfe 100644 --- a/app/cron_hedge_funds.py +++ b/app/cron_hedge_funds.py @@ -114,24 +114,11 @@ def get_data(cik, stock_sectors): 'marketValue': row[5], 'winRate': row[6], 'holdings': orjson.loads(row[7]), - } for row in cik_data] + } for row in cik_data][0] if not res: return None # Exit if no data is found - ''' - filtered_data = [] - for item in res: - try: - filtered_data+=item['holdings'] - except: - pass - filtered_data = [item for item in filtered_data if datetime.strptime(item['date'], "%Y-%m-%d") >= cutoff_date] - print(filtered_data) - ''' - - res = res[0] #latest data - filtered_holdings = [ {key: holding[key] for key in keys_to_keep} for holding in res['holdings'] @@ -162,9 +149,10 @@ def get_data(cik, stock_sectors): if quote_data: item['price'] = quote_data.get('price',None) item['changesPercentage'] = round(quote_data.get('changesPercentage'), 2) if quote_data.get('changesPercentage') is not None else None + item['name'] = quote_data.get('name') except: pass - #stock_screener_data_dict + res['holdings'] = filtered_holdings for rank, item in enumerate(res['holdings'], 1): item['rank'] = rank @@ -209,7 +197,7 @@ if __name__ == '__main__': cursor.execute("SELECT DISTINCT cik FROM institutes") cik_symbols = [row[0] for row in cursor.fetchall()] #Test mode - #cik_symbols = ['0001649339'] + cik_symbols = ['0001067983'] try: stock_cursor = stock_con.cursor() stock_cursor.execute("SELECT DISTINCT symbol, sector FROM stocks")