import os import requests import json from datetime import datetime, timedelta import pandas as pd import talib import yfinance as yf import plotly.express as px import gradio as gr from dotenv import load_dotenv, find_dotenv _ = load_dotenv(find_dotenv()) # read local .env file #openai.api_key = os.environ['OPENAI_API_KEY'] news_api_key = os.environ['NEWS_API_KEY'] def fetch_recent_news(api_key,query): # Calculate the date 2 days ago two_days_ago = datetime.now() - timedelta(days=10) formatted_date = two_days_ago.strftime('%Y-%m-%d') # Current date and time current_datetime = datetime.now().strftime('%Y-%m-%dT%H:%M:%S') # Endpoint URL #top_headlines_url = 'https://newsapi.org/v2/top-headlines?country=us' everything_url = 'https://newsapi.org/v2/everything?language=en&sortyBy=relevancy' # Parameters params = { 'apiKey': api_key, # Replace with your NewsAPI key 'q': query, 'from':formatted_date, } # Make the GET request news_response = requests.get(everything_url, params=params) # Check if the request was successful if news_response.status_code == 200: data = news_response.json()['articles'] # Select only the relevant columns selected_data = [ { 'title': article['title'], 'description': article['description'], 'content': article['content'], 'publishedAt': article['publishedAt'] } for article in data ] return selected_data else: print("Failed to fetch news") return [] # Use a pipeline as a high-level helper pipe = pipeline("text-classification", model="ProsusAI/finbert") def get_mean_sentiment_score(ticker): news_articles = fetch_recent_news(news_api_key,ticker) df = pd.DataFrame(news_articles) df['finbert_sentiment'] = df['content'].apply(pipe) df['Sentiment'] = df['content'].apply(lambda x: pipe(x)[0]['label']) df['Sentiment Score'] = df['content'].apply(lambda x: pipe(x)[0]['score']) df['finbert_sentiment_score'] = df['finbert_sentiment'].apply(lambda x: {x[0]['label']=='negative': -1, x[0]['label']=='positive': 1}.get(True, 0) * x[0]['score']) return df['finbert_sentiment_score'].mean() def get_buy_sell_signal(ticker,sentiment_score): period = "6mo" historical_prices = yf.Ticker(ticker).history(period=period) series1 = talib.EMA(historical_prices['Close'], 9) series2 = talib.EMA(historical_prices['Close'], 26) historical_prices['ema-9'] = series1 historical_prices['ema-26'] = series2 signal = "" if (series1[-2] < series2[-2] and series1[-1] > series2[-1]): signal = "BUY" elif (series2[-2] < series1[-2] and series2[-1] > series1[-1]): signal = "SELL" else: signal = "DO NOTHING" ema_chart = px.line(historical_prices, y=['ema-9','ema-26'], title=ticker + " ("+ "{:.2f}".format(sentiment_score)+") - "+signal, ) #return ema_chart # Show the plot #ema_chart.show() return signal, ema_chart def generate_gr_dashboard(ticker): # Creating an empty DataFrame dashboard_df = pd.DataFrame(columns=['TICKER', 'SENTIMENT SCORE', 'SIGNAL']) sentiment_score = get_mean_sentiment_score(ticker) #get_buy_sell_signal(ticker, sentiment_score) signal, ema_charts = get_buy_sell_signal(ticker, sentiment_score) new_row = pd.DataFrame({'TICKER': [ticker], 'SENTIMENT SCORE': [round(sentiment_score,2)], 'SIGNAL': [signal]}) dashboard_df = pd.concat([dashboard_df, new_row], ignore_index=True) return ema_charts, dashboard_df gr.close_all() with gr.Blocks() as demo: stock_code = gr.Textbox(label="Stock Ticker") output = [gr.Plot(label="Ema Chart"), gr.Dataframe(label="Table")] generate_button = gr.Button("Generate Chart") generate_button.click(fn=generate_gr_dashboard, inputs=stock_code, outputs=output) demo.launch()