import gradio as gr from urllib.request import urlopen import certifi import json import pandas as pd import os import warnings import re warnings.filterwarnings("ignore") from langchain_community.document_loaders import CSVLoader from langchain_community.vectorstores import Chroma from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.embeddings import HuggingFaceEmbeddings from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate from langchain_community.llms import HuggingFacePipeline from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline # Hugging Face API Key os.environ["HUGGINGFACEHUB_API_TOKEN"] = os.environ.get("HUGGINGFACEHUB_API_TOKEN") # Load Falcon LLM model_id = "tiiuae/Falcon3-3B-Instruct" tokenizer = AutoTokenizer.from_pretrained(model_id) model = AutoModelForCausalLM.from_pretrained(model_id) pipe = pipeline( "text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512, do_sample=True, temperature=0.1, top_k=50, top_p=0.95, eos_token_id=tokenizer.eos_token_id, ) llm = HuggingFacePipeline(pipeline=pipe) # Enhanced Prompt Template template = """ You are a Financial Market Expert. Analyze the provided market data and create a comprehensive financial report. Market Data: {context} Company: {question} Please provide a detailed analysis including: 1. Current stock performance metrics 2. Price movements and trends 3. Market capitalization details 4. Trading volume analysis 5. Key financial indicators Format the response as a clear, professional financial report with proper sections and bullet points. """ PROMPT = PromptTemplate(input_variables=["context", "question"], template=template) def format_currency(value): """Format currency values""" try: if isinstance(value, (int, float)): return f"${value:,.2f}" return str(value) except: return str(value) def format_percentage(value): """Format percentage values""" try: if isinstance(value, (int, float)): return f"{value:.2f}%" return str(value) except: return str(value) def create_html_report(data, llm_analysis): """Create a formatted HTML report""" if not data or len(data) == 0: return "
No data available for this ticker.
" # Get the first data point (assuming it's the most relevant) stock_data = data[0] if isinstance(data, list) else data # Extract key metrics symbol = stock_data.get('symbol', 'N/A') name = stock_data.get('name', 'N/A') price = stock_data.get('price', 0) change = stock_data.get('change', 0) change_percent = stock_data.get('changesPercentage', 0) market_cap = stock_data.get('marketCap', 0) volume = stock_data.get('volume', 0) avg_volume = stock_data.get('avgVolume', 0) pe_ratio = stock_data.get('pe', 'N/A') eps = stock_data.get('eps', 'N/A') # Determine trend color trend_color = "#22c55e" if change >= 0 else "#ef4444" trend_icon = "📈" if change >= 0 else "📉" html = f"""

{symbol} - Financial Report

{name}

📅 Generated on {pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')}
Current Price
{format_currency(price)}
Price Change {trend_icon}
{format_currency(change)} ({format_percentage(change_percent)})
Market Cap
{format_currency(market_cap) if market_cap else 'N/A'}
Volume
{f"{volume:,}" if volume else 'N/A'}

📊 Detailed Metrics

P/E Ratio {pe_ratio}
Earnings Per Share (EPS) {format_currency(eps) if eps != 'N/A' else 'N/A'}
Average Volume {f"{avg_volume:,}" if avg_volume else 'N/A'}
Exchange {stock_data.get('exchange', 'N/A')}

🤖 AI Analysis

{llm_analysis}

⚠️ This report is for informational purposes only and should not be considered as investment advice.

""" return html def generate_report(ticker: str, exchange: str): """Generate enhanced financial report""" api_key = "C1HRSweTniWdBuLmTTse9w8KpkoiouM5" if not ticker.strip(): return "
❌ Please enter a valid ticker symbol.
" try: # Show loading message loading_html = """
🔄 Generating Report...
Fetching data and running AI analysis
""" # Fetch Data ticker = ticker.upper().strip() if exchange == "NSE": url = f"https://financialmodelingprep.com/api/v3/search?query={ticker}&exchange=NSE&apikey={api_key}" else: url = f"https://financialmodelingprep.com/api/v3/quote/{ticker}?apikey={api_key}" response = urlopen(url, cafile=certifi.where()) data = json.loads(response.read().decode("utf-8")) if not data: return "
❌ No data found for ticker: " + ticker + "
" # Save to CSV for RAG processing df = pd.DataFrame(data) if 'timestamp' in df.columns: df['timestamp'] = pd.to_datetime(df['timestamp'], errors='coerce') if 'earningsAnnouncement' in df.columns: df['earningsAnnouncement'] = pd.to_datetime(df['earningsAnnouncement'], errors='coerce') df.to_csv("eco_ind.csv", index=False) # Create vector store and run LLM analysis loader = CSVLoader("eco_ind.csv") documents = loader.load() splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20) texts = splitter.split_documents(documents) embeddings = HuggingFaceEmbeddings() chroma = Chroma.from_documents( documents=texts, collection_name="economic_data", embedding=embeddings, persist_directory="docs/chroma_rag" ) retriever = chroma.as_retriever(search_kwargs={"k": 3}) qa = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", chain_type_kwargs={"prompt": PROMPT}, retriever=retriever, return_source_documents=False ) # Get LLM analysis query = f"Provide a comprehensive financial analysis for {ticker}" result = qa({"query": query}) llm_analysis = result["result"] # Create and return formatted HTML report return create_html_report(data, llm_analysis) except Exception as e: error_html = f"""

❌ Error Occurred

Details: {str(e)}
Please check your ticker symbol and try again. Make sure you have a stable internet connection.
""" return error_html # Custom CSS for better styling custom_css = """ #component-0 { max-width: 1200px !important; margin: 0 auto !important; } .gradio-container { background-color: black !important; min-height: 100vh !important; } #title { text-align: center !important; color: white !important; font-size: 2.5rem !important; font-weight: 700 !important; margin-bottom: 1rem !important; text-shadow: 0 2px 4px rgba(0,0,0,0.1) !important; } #description { text-align: center !important; color: white !important; font-size: 1.1rem !important; margin-bottom: 2rem !important; } .input-container { background: white !important; border-radius: 5px !important; padding: 3px !important; box-shadow: 0 10px 30px rgba(0,0,0,0.1) !important; margin-bottom: 20px !important; } .output-container { background: transparent !important; border-radius: 15px !important; padding: 10px; border: 2px white solid ; overflow: hidden !important; box-shadow: 0 10px 30px rgba(0,0,0,0.2) !important; } """ # Create the Gradio interface with sidebar for inputs with gr.Blocks(css=custom_css, title="📊 Financial Report Generator") as iface: gr.HTML('
📊 AI-Powered Financial Report Generator
') gr.HTML('
Enter a stock ticker and exchange to get a comprehensive AI-generated financial analysis
') # Sidebar for inputs with gr.Sidebar(): gr.Markdown("## 📥 Input Parameters") ticker_input = gr.Textbox( label="🎯 Stock Ticker Symbol", placeholder="e.g., MSFT, AAPL, GOOGL", info="Enter the stock symbol you want to analyze" ) exchange_input = gr.Radio( choices=["US", "NSE"], label="🏢 Exchange", value="US", info="Select the stock exchange" ) generate_btn = gr.Button( "🚀 Generate Report", variant="primary" ) clear_btn = gr.Button( "🔄 Clear", variant="secondary" ) # Output section with gr.Row(elem_classes=["output-container"]): output = gr.HTML(label="📊 Financial Report") # Event handlers generate_btn.click( fn=generate_report, inputs=[ticker_input, exchange_input], outputs=output ) clear_btn.click( lambda: ["", "US", ""], outputs=[ticker_input, exchange_input, output] ) ticker_input.submit( fn=generate_report, inputs=[ticker_input, exchange_input], outputs=output ) if __name__ == "__main__": iface.launch( share=True, show_error=True )