StockAnalysis / app.py
fpachisa's picture
Update app.py
a5ee854 verified
Raw History Blame Contribute Delete
4.04 kB
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()