160 lines
5.3 KiB
Python
Executable File
160 lines
5.3 KiB
Python
Executable File
import aiohttp
|
|
import aiofiles
|
|
import ujson
|
|
import sqlite3
|
|
import pandas as pd
|
|
import asyncio
|
|
import pytz
|
|
import time
|
|
import os
|
|
from dotenv import load_dotenv
|
|
from datetime import datetime, timedelta
|
|
|
|
date_format = "%a, %d %b %Y %H:%M:%S %z"
|
|
|
|
load_dotenv()
|
|
api_key = os.getenv('BENZINGA_API_KEY')
|
|
|
|
headers = {"accept": "application/json"}
|
|
|
|
query_template = """
|
|
SELECT
|
|
close
|
|
FROM
|
|
"{symbol}"
|
|
WHERE
|
|
date BETWEEN ? AND ?
|
|
"""
|
|
|
|
# List of holidays when the stock market is closed
|
|
holidays = [
|
|
"2024-01-01",
|
|
"2024-03-29",
|
|
"2024-12-25",
|
|
]
|
|
|
|
def is_holiday(date):
|
|
"""Check if the given date is a holiday"""
|
|
str_date = date.strftime("%Y-%m-%d")
|
|
return str_date in holidays
|
|
|
|
def correct_weekday(selected_date):
|
|
# Monday is 0 and Sunday is 6
|
|
if selected_date.weekday() == 0:
|
|
selected_date -= timedelta(3)
|
|
elif selected_date.weekday() <= 4:
|
|
selected_date -= timedelta(1)
|
|
elif selected_date.weekday() == 5:
|
|
selected_date -= timedelta(1)
|
|
elif selected_date.weekday() == 6:
|
|
selected_date -= timedelta(2)
|
|
|
|
# Check if the selected date is a holiday and adjust if necessary
|
|
while is_holiday(selected_date):
|
|
selected_date -= timedelta(1)
|
|
|
|
# Adjust again if the resulting date is a Saturday or Sunday
|
|
if selected_date.weekday() >= 5:
|
|
selected_date -= timedelta(selected_date.weekday() - 4)
|
|
|
|
return selected_date
|
|
|
|
async def get_endpoint(session, symbol, con):
|
|
url = "https://api.benzinga.com/api/v2/news"
|
|
querystring = {"token": api_key,"tickers": symbol, "channels":"WIIM","pageSize":"20","displayOutput":"full"}
|
|
async with session.get(url, params=querystring, headers=headers) as response:
|
|
res_list = []
|
|
res = ujson.loads(await response.text())
|
|
|
|
for item in res:
|
|
date_obj = datetime.strptime(item['created'], date_format)
|
|
date_obj_utc = date_obj.astimezone(pytz.utc)
|
|
|
|
new_date_obj_utc = date_obj_utc
|
|
|
|
start_date_obj_utc = correct_weekday(date_obj_utc)
|
|
|
|
start_date = start_date_obj_utc.strftime("%Y-%m-%d")
|
|
end_date = new_date_obj_utc.strftime("%Y-%m-%d")
|
|
|
|
new_date_str = new_date_obj_utc.strftime("%b %d, %Y")
|
|
query = query_template.format(symbol=symbol)
|
|
|
|
try:
|
|
df = pd.read_sql_query(query,con, params=(start_date, end_date))
|
|
if not df.empty:
|
|
change_percent = round((df['close'].iloc[1]/df['close'].iloc[0] -1)*100,2)
|
|
else:
|
|
change_percent = '-'
|
|
except Exception as e:
|
|
change_percent = '-'
|
|
|
|
res_list.append({'date': new_date_str, 'text': item['title'], 'changesPercentage': change_percent})
|
|
with open(f"json/wiim/company/{symbol}.json", 'w') as file:
|
|
ujson.dump(res_list, file)
|
|
|
|
'''
|
|
current_date = datetime.now(pytz.utc)
|
|
date_difference = current_date - new_date_obj_utc
|
|
if date_difference.days < 2:
|
|
new_date_str = new_date_obj_utc.strftime("%b %d, %Y")
|
|
formatted_data = {'wiim': res[0]['title'], 'updated': new_date_str}
|
|
|
|
with open(f"json/wiim/{symbol}.json", 'w') as file:
|
|
ujson.dump(formatted_data, file)
|
|
'''
|
|
|
|
|
|
async def get_latest_wiim(session, stock_symbols, etf_symbols):
|
|
url = "https://api.benzinga.com/api/v2/news"
|
|
querystring = {"token": api_key,"channels":"WIIM","pageSize":"20","displayOutput":"full"}
|
|
|
|
try:
|
|
async with session.get(url, params=querystring, headers=headers) as response:
|
|
res_list = []
|
|
res = ujson.loads(await response.text())
|
|
for item in res:
|
|
for el in item['stocks']:
|
|
# Update the 'name' key to 'ticker'
|
|
if 'name' in el:
|
|
el['ticker'] = el.pop('name')
|
|
if el['ticker'] in stock_symbols:
|
|
el['assetType'] = 'stock'
|
|
elif el['ticker'] in etf_symbols:
|
|
el['assetType'] = 'etf'
|
|
res_list.append({'date': item['created'], 'text': item['title'], 'stocks': item['stocks']})
|
|
with open(f"json/wiim/rss-feed/data.json", 'w') as file:
|
|
ujson.dump(res_list, file)
|
|
|
|
except Exception as e:
|
|
#pass
|
|
print(e)
|
|
|
|
async def run():
|
|
con = sqlite3.connect('stocks.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()]
|
|
|
|
etf_con = sqlite3.connect('etf.db')
|
|
|
|
etf_cursor = etf_con.cursor()
|
|
etf_cursor.execute("PRAGMA journal_mode = wal")
|
|
etf_cursor.execute("SELECT DISTINCT symbol FROM etfs")
|
|
etf_symbols = [row[0] for row in etf_cursor.fetchall()]
|
|
|
|
|
|
async with aiohttp.ClientSession() as session:
|
|
await get_latest_wiim(session, stock_symbols, etf_symbols)
|
|
await asyncio.gather(*(get_endpoint(session, symbol, con) for symbol in stock_symbols))
|
|
await asyncio.gather(*(get_endpoint(session, symbol, etf_con) for symbol in etf_symbols))
|
|
|
|
con.close()
|
|
etf_con.close()
|
|
try:
|
|
asyncio.run(run())
|
|
except Exception as e:
|
|
print(e)
|