This commit is contained in:
MuslemRahimi 2024-09-17 13:56:33 +02:00
parent 4388739a17
commit d3efac141d
5 changed files with 173 additions and 22 deletions

View File

@ -255,12 +255,14 @@ class ETFDatabase:
for key in fundamental_data
}
'''
if len(json.loads(fundamental_data['holding'])) == 0:
self.cursor.execute("DELETE FROM etfs WHERE symbol = ?", (symbol,))
#self.cursor.execute("DELETE FROM symbol WHERE symbol = ?", (symbol,))
self.conn.commit()
print(f"Delete {symbol}")
return
'''
for column, (column_type, value) in column_definitions.items():
if column not in columns and column_type:
@ -392,5 +394,10 @@ async def fetch_tickers():
db = ETFDatabase('backup_db/etf.db')
loop = asyncio.get_event_loop()
all_tickers = loop.run_until_complete(fetch_tickers())
'''
for item in all_tickers:
if item['symbol'] == 'GLD':
print(item)
'''
loop.run_until_complete(db.save_etfs(all_tickers))
db.close_connection()

View File

@ -27,7 +27,6 @@ async def get_data(ticker, con):
analyst_estimates = ujson.loads(data['analyst_estimates'].iloc[0])
income = ujson.loads(data['income'].iloc[0])
combined_data = defaultdict(dict)
#Sum up quarter results
eps_sums = {}
revenue_sums = {}

View File

@ -5,8 +5,14 @@ import asyncio
import pandas as pd
from tqdm import tqdm
import orjson
from GetStartEndDate import GetStartEndDate
from collections import defaultdict
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv('FMP_API_KEY')
with open(f"json/stock-screener/data.json", 'rb') as file:
stock_screener_data = orjson.loads(file.read())
@ -14,20 +20,30 @@ with open(f"json/stock-screener/data.json", 'rb') as file:
stock_screener_data_dict = {item['symbol']: item for item in stock_screener_data}
def save_as_json(data):
with open(f"json/industry/overview.json", 'w') as file:
date, _ = GetStartEndDate().run()
date = date.strftime('%Y-%m-%d')
def save_as_json(data, filename):
with open(f"json/industry/{filename}.json", 'w') as file:
ujson.dump(data, file)
#async def get_data():
# Function to fetch data from the API
async def get_data(session, class_type='sector'):
if class_type == 'sector':
url = f"https://financialmodelingprep.com/api/v4/sector_price_earning_ratio?date={date}&exchange=NYSE&apikey={api_key}"
else:
url = f"https://financialmodelingprep.com/api/v4/industry_price_earning_ratio?date={date}&exchange=NYSE&apikey={api_key}"
async with session.get(url) as response:
data = await response.json()
return data
def run():
async def run():
# Initialize a dictionary to store stock count, market cap, and other totals for each industry
sector_industry_data = defaultdict(lambda: defaultdict(lambda: {
'numStocks': 0,
'totalMarketCap': 0.0,
'totalPE': 0.0,
'totalDividendYield': 0.0,
'totalNetIncome': 0.0,
'totalRevenue': 0.0,
@ -44,7 +60,6 @@ def run():
sector = stock.get('sector')
industry = stock.get('industry')
market_cap = stock.get('marketCap')
pe = stock.get('pe')
dividend_yield = stock.get('dividendYield')
net_income = stock.get('netIncome')
revenue = stock.get('revenue')
@ -57,11 +72,6 @@ def run():
sector_industry_data[sector][industry]['numStocks'] += 1
sector_industry_data[sector][industry]['totalMarketCap'] += float(market_cap)
# Accumulate PE ratio if available
if pe is not None:
sector_industry_data[sector][industry]['totalPE'] += float(pe)
sector_industry_data[sector][industry]['peCount'] += 1
# Accumulate dividend yield if available
if dividend_yield is not None:
sector_industry_data[sector][industry]['totalDividendYield'] += float(dividend_yield)
@ -83,19 +93,18 @@ def run():
sector_industry_data[sector][industry]['change1YCount'] += 1
# Prepare the final data in the requested format
result = {}
overview = {}
for sector, industries in sector_industry_data.items():
# Sort industries by stock count in descending order
sorted_industries = sorted(industries.items(), key=lambda x: x[1]['numStocks'], reverse=True)
# Add sorted industries with averages to the result for each sector
result[sector] = [
# Add sorted industries with averages to the overview for each sector
overview[sector] = [
{
'industry': industry,
'numStocks': data['numStocks'],
'totalMarketCap': data['totalMarketCap'],
'pe': round((data['totalMarketCap'] / data['totalNetIncome']),2) if data['totalNetIncome'] > 0 else None,
'avgDividendYield': round((data['totalDividendYield'] / data['dividendCount']),2) if data['dividendCount'] > 0 else None,
'profitMargin': round((data['totalNetIncome'] / data['totalRevenue'])*100,2) if data['totalRevenue'] > 0 else None,
'avgChange1M': round((data['totalChange1M'] / data['change1MCount']),2) if data['change1MCount'] > 0 else None,
@ -103,9 +112,87 @@ def run():
} for industry, data in sorted_industries
]
print(result)
# Assign the P/E values from pe_industry to the overview
async with aiohttp.ClientSession() as session:
pe_industry = await get_data(session, class_type='industry')
for sector, industries in overview.items():
for industry_data in industries:
industry_name = industry_data['industry']
save_as_json(result)
# Look for a matching industry in pe_industry to assign the P/E ratio
matching_pe = next((item['pe'] for item in pe_industry if item['industry'] == industry_name), None)
if matching_pe is not None:
industry_data['pe'] = round(float(matching_pe), 2)
save_as_json(overview, filename = 'overview')
industry_overview = []
for key in overview:
industry_overview.extend(overview[key])
industry_overview = sorted(industry_overview, key= lambda x: x['numStocks'], reverse=True)
save_as_json(industry_overview, filename='industry-overview')
run()
sector_overview = []
for sector, industries in sector_industry_data.items():
total_market_cap = 0
total_stocks = 0
total_dividend_yield = 0
total_net_income = 0
total_revenue = 0
total_change_1m = 0
total_change_1y = 0
dividend_count = 0
change_1m_count = 0
change_1y_count = 0
for industry, data in industries.items():
# Sum up values across industries for the sector summary
total_market_cap += data['totalMarketCap']
total_stocks += data['numStocks']
total_net_income += data['totalNetIncome']
total_revenue += data['totalRevenue']
total_change_1m += data['totalChange1M']
total_change_1y += data['totalChange1Y']
dividend_count += data['dividendCount']
change_1m_count += data['change1MCount']
change_1y_count += data['change1YCount']
total_dividend_yield += data['totalDividendYield']
# Calculate averages and profit margin for the sector
sector_overview.append({
'sector': sector,
'numStocks': total_stocks,
'totalMarketCap': total_market_cap,
'avgDividendYield': round((total_dividend_yield / dividend_count), 2) if dividend_count > 0 else None,
'profitMargin': round((total_net_income / total_revenue) * 100, 2) if total_revenue > 0 else None,
'avgChange1M': round((total_change_1m / change_1m_count), 2) if change_1m_count > 0 else None,
'avgChange1Y': round((total_change_1y / change_1y_count), 2) if change_1y_count > 0 else None
})
# Assign the P/E values from pe_industry to the overview
async with aiohttp.ClientSession() as session:
pe_sector = await get_data(session, class_type='sector')
# Loop through sector_overview to update P/E ratios from pe_sector
for sector_data in sector_overview:
sector_name = sector_data['sector']
# Find the matching sector in pe_sector and assign the P/E ratio
matching_pe = next((item['pe'] for item in pe_sector if item['sector'] == sector_name), None)
if matching_pe is not None:
sector_data['pe'] = round(float(matching_pe), 2)
sector_overview = sorted(sector_overview, key= lambda x: x['numStocks'], reverse=True)
save_as_json(sector_overview, filename='sector-overview')
loop = asyncio.get_event_loop()
sector_results = loop.run_until_complete(run())

View File

@ -82,11 +82,13 @@ async def get_data(ticker, con):
async def run():
con = sqlite3.connect('stocks.db')
etf_con = sqlite3.connect('etf.db')
cursor = con.cursor()
cursor.execute("PRAGMA journal_mode = wal")
cursor.execute("SELECT DISTINCT symbol FROM stocks")
stock_symbols = [row[0] for row in cursor.fetchall()]
counter = 0

View File

@ -3607,9 +3607,9 @@ async def get_economic_indicator(api_key: str = Security(get_api_key)):
headers={"Content-Encoding": "gzip"}
)
@app.get("/industry-overview")
@app.get("/sector-industry-overview")
async def get_industry_overview(api_key: str = Security(get_api_key)):
cache_key = f"industry_overview"
cache_key = f"sector-industry-overview"
cached_result = redis_client.get(cache_key)
if cached_result:
return StreamingResponse(
@ -3635,6 +3635,62 @@ async def get_industry_overview(api_key: str = Security(get_api_key)):
headers={"Content-Encoding": "gzip"}
)
@app.get("/sector-overview")
async def get_sector_overview(api_key: str = Security(get_api_key)):
cache_key = f"sector-overview"
cached_result = redis_client.get(cache_key)
if cached_result:
return StreamingResponse(
io.BytesIO(cached_result),
media_type="application/json",
headers={"Content-Encoding": "gzip"}
)
try:
with open(f"json/industry/sector-overview.json", 'rb') as file:
res = orjson.loads(file.read())
except:
res = []
data = orjson.dumps(res)
compressed_data = gzip.compress(data)
redis_client.set(cache_key, compressed_data)
redis_client.expire(cache_key,3600*3600)
return StreamingResponse(
io.BytesIO(compressed_data),
media_type="application/json",
headers={"Content-Encoding": "gzip"}
)
@app.get("/industry-overview")
async def get_industry_overview(api_key: str = Security(get_api_key)):
cache_key = f"industry-overview"
cached_result = redis_client.get(cache_key)
if cached_result:
return StreamingResponse(
io.BytesIO(cached_result),
media_type="application/json",
headers={"Content-Encoding": "gzip"}
)
try:
with open(f"json/industry/industry-overview.json", 'rb') as file:
res = orjson.loads(file.read())
except:
res = []
data = orjson.dumps(res)
compressed_data = gzip.compress(data)
redis_client.set(cache_key, compressed_data)
redis_client.expire(cache_key,3600*3600)
return StreamingResponse(
io.BytesIO(compressed_data),
media_type="application/json",
headers={"Content-Encoding": "gzip"}
)
@app.post("/next-earnings")
async def get_next_earnings(data:TickerData, api_key: str = Security(get_api_key)):
ticker = data.ticker