FinAI / app.py
ankur2402's picture
Update app.py
efd0302 verified
raw
history blame contribute delete
No virus
18.4 kB
import streamlit as st
# Import necessary libraries
import os
import requests
import json
import yfinance as yf
from yahooquery import Ticker
from fpdf import FPDF
from typing import List, Union
import re
# Import components from langchain and other libraries
from langchain.agents import load_tools, initialize_agent, AgentType, AgentExecutor, LLMSingleActionAgent, AgentOutputParser
# from langchain_experimental.agents.agent_toolkits import create_csv_agent
from langchain.agents.agent_toolkits import create_vectorstore_agent, VectorStoreToolkit, VectorStoreInfo
from langchain.llms import OpenAI, Cohere
from langchain.document_loaders import PyPDFLoader, TextLoader, DirectoryLoader
from langchain.vectorstores import Chroma
from langchain.embeddings import CohereEmbeddings, OpenAIEmbeddings
from langchain.indexes import VectorstoreIndexCreator
from langchain.chains import RetrievalQA
from langchain.evaluation.qa import QAEvalChain
from langchain.prompts import StringPromptTemplate
# from langchain.tools.python.tool import PythonREPLTool
from langchain.python import PythonREPL
from langchain import LLMMathChain, SerpAPIWrapper, LLMChain
from langchain.schema import AgentAction, AgentFinish, OutputParserException
# Set up Streamlit header and sidebar
st.header('FinAI')
mod = None
with st.sidebar:
with st.form('Cohere/OpenAI'):
# User selects the model (OpenAI/Cohere) and enters API keys
model = st.radio('Choose OpenAI/Cohere', ('OpenAI', 'Cohere'))
api_key = st.text_input('Enter API key', type="password")
serpAI_key = st.text_input('Enter SERPAIAPI key', type="password")
submitted = st.form_submit_button("Submit")
# Check if API key is provided and set up the language model accordingly
if api_key:
if model == 'OpenAI':
os.environ["OPENAI_API_KEY"] = api_key
llm = OpenAI(temperature=0.3)
mod = 'OpenAI'
os.environ["SERPAPI_API_KEY"] = serpAI_key
elif model == 'Cohere':
os.environ["Cohere_API_KEY"] = api_key
llm = Cohere(cohere_api_key=api_key)
mod = 'Cohere'
os.environ["SERPAPI_API_KEY"] = serpAI_key
# Helper function to get company news from SERP API
def get_company_news(company_name):
# Set the parameters for the SERP API request
params = {
"engine": "google",
"tbm": "nws",
"q": company_name,
"api_key": os.environ["SERPAPI_API_KEY"],
}
# Send the request and get the response data in JSON format
response = requests.get('https://serpapi.com/search', params=params)
data = response.json()
return data.get('news_results')
# Helper function to write news data to a file
def write_news_to_file(news, filename):
with open(filename, 'w') as file:
for news_item in news:
if news_item is not None:
title = news_item.get('title', 'No title')
link = news_item.get('link', 'No link')
date = news_item.get('date', 'No date')
file.write(f"Title: {title}\n")
file.write(f"Link: {link}\n")
file.write(f"Date: {date}\n\n")
# Helper function to get stock evolution data from Yahoo Finance API
def get_stock_evolution(company_name, period="1y"):
# Get the stock information using yfinance
stock = yf.Ticker(company_name)
# Get historical market data for the specified period
hist = stock.history(period=period)
# Convert the DataFrame to a string with a specific format
data_string = hist.to_string()
# Save the historical market data to a CSV file
hist.to_csv('stocks_data.csv')
# Get financials data
fin = stock.get_financials()
fin.to_csv('fin_data.csv')
# Append the string to the "investment.txt" file
with open("investment.txt", "a") as file:
file.write(f"\nStock Evolution for {company_name}:\n")
file.write(data_string)
file.write("\n")
# Helper function to get financial statements from Yahoo Finance API
def get_financial_statements(ticker):
# Create a Ticker object
company = Ticker(ticker)
# Get financial data for balance sheet, cash flow, income statement, and valuation measures
balance_sheet = company.balance_sheet().to_string()
cash_flow = company.cash_flow(trailing=False).to_string()
income_statement = company.income_statement().to_string()
valuation_measures = str(company.valuation_measures) # This one might already be a dictionary or string
# Write data to "investment.txt" file
with open("investment.txt", "a") as file:
file.write("\nBalance Sheet\n")
file.write(balance_sheet)
file.write("\nCash Flow\n")
file.write(cash_flow)
file.write("\nIncome Statement\n")
file.write(income_statement)
file.write("\nValuation Measures\n")
file.write(valuation_measures)
# Helper function to fetch data from different sources and store it in "investment.txt" file
def get_data(company_name, company_ticker, period="1y", filename="investment.txt"):
news = get_company_news(company_name)
if news:
write_news_to_file(news, filename)
else:
print("No news found.")
get_stock_evolution(company_ticker, period)
get_financial_statements(company_ticker)
# Helper function to call the language model for financial analysis based on user request
def financial_analyst(request):
# Print the request received from the user
print(f"Received request: {request}")
# Use OpenAI GPT-3.5 Turbo model to analyze the request and generate a response
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo-16k",
messages=[{
"role": "user",
"content": f"Given the user request, what is the company name and the company stock ticker ?: {request}?"
}],
functions=[{
"name": "get_data",
"description": "Get financial data on a specific company for investment purposes",
"parameters": {
"type": "object",
"properties": {
"company_name": {
"type": "string",
"description": "The name of the company",
},
"company_ticker": {
"type": "string",
"description": "The ticker of the stock of the company"
},
"period": {
"type": "string",
"description": "The period of analysis"
},
"filename": {
"type": "string",
"description": "The filename to store data"
}
},
"required": ["company_name", "company_ticker"],
},
}],
function_call={"name": "get_data"},
)
# Extract the arguments and company information from the response
message = response["choices"][0]["message"]
if message.get("function_call"):
arguments = json.loads(message["function_call"]["arguments"])
company_name = arguments["company_name"]
company_ticker = arguments["company_ticker"]
# Call the function to fetch and store financial data
get_data(company_name, company_ticker)
# Read the contents of the "investment.txt" file for the response
with open("investment.txt", "r") as file:
content = file.read()[:14000]
# Use OpenAI GPT-3.5 Turbo model again to provide a detailed investment thesis
second_response = openai.ChatCompletion.create(
model="gpt-3.5-turbo-16k",
messages=[
{
"role": "user",
"content": request
},
message,
{
"role": "system",
"content": """write a detailed investment thesis to answer
the user request. Provide numbers to justify
your assertions, a lot ideally. Never mention
something like this:
However, it is essential to consider your own risk
tolerance, financial goals, and time horizon before
making any investment decisions. It is recommended
to consult with a financial advisor or do further
research to gain more insights into the company's
fundamentals and market trends. The user
already knows that"""
},
{
"role": "assistant",
"content": content,
},
],
)
return second_response["choices"][0]["message"]["content"]
# Helper function to generate a PDF with text and images
def generate_pdf(text, image_paths):
# Create a FPDF object
pdf = FPDF()
# Add a page
pdf.add_page()
# Set style and size of font for the PDF
pdf.set_font("Arial", size=12)
# Set left and right margins
pdf.set_left_margin(20)
pdf.set_right_margin(20)
# Add multi-cell with line break for the text
pdf.multi_cell(0, 10, text)
# Move to the next line after the text
pdf.ln()
# Add a new page for the images
pdf.add_page()
# Add the first image to the PDF
pdf.image(image_paths[0], x=20, y=pdf.get_y(), w=175)
# Calculate the y-coordinate for the second image
second_image_y = pdf.get_y() + 150
# Add the second image to the PDF
pdf.image(image_paths[1], x=20, y=second_image_y, w=175)
# Save the PDF with the given file name
pdf.output("output.pdf")
# Helper function to generate graphs using langchain and save as images
def graphs(path, prompt):
agent = create_csv_agent(
OpenAI(temperature=0),
path,
verbose=True,
agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
)
agent.run(prompt)
# Category 1: Revenue and Sales
revenue_sales_questions = [
"What was the total revenue generated by the company during the fiscal year?",
"How does the revenue of the current year compare to the previous year?",
"Which product/service contributed the most to the company's revenue?",
"Did the company experience any significant changes in sales volume or pricing?",
"Are there any notable trends or patterns in the revenue growth of the company over the past few years?",
"What were the geographical regions or markets where the company generated the highest revenue?",
"Has the company introduced any new revenue streams or business lines?",
"Were there any extraordinary events or factors that affected the company's revenue performance?",
"How does the revenue composition of the company compare to its competitors in the industry?",
"Are there any forecasts or projections for future revenue growth provided in the report?"
]
# Category 2: Expenses and Costs
expenses_costs_questions = [
"What were the major expense categories for the company during the fiscal year?",
"How do the expenses of the current year compare to the previous year?",
"Did the company implement any cost-saving measures or efficiency improvements?",
"Were there any significant changes in the cost of raw materials or production inputs?",
"How does the company's expense ratio compare to industry benchmarks?",
"Did the company incur any one-time or non-recurring expenses during the year?",
"Are there any trends or patterns in the company's cost structure over the past few years?",
"Has the company invested in research and development (R&D) or capital expenditures?",
"What were the employee-related costs and benefits provided by the company?",
"Are there any forecasts or projections for future cost management initiatives provided in the report?"
]
# Category 3: Profitability and Financial Ratios
profitability_ratios_questions = [
"What was the net profit or net income generated by the company during the fiscal year?",
"How does the profitability of the current year compare to the previous year?",
"What is the company's gross profit margin and how has it changed over time?",
"Did the company experience any changes in operating profit or operating margin?",
"What is the return on assets (ROA) and return on equity (ROE) for the company?",
"Has the company improved its profitability compared to its competitors in the industry?",
"Are there any trends or patterns in the company's profitability ratios over the past few years?",
"Did the company face any challenges or risks that impacted its profitability?",
"How does the company's profitability ratios compare to industry benchmarks?",
"Are there any forecasts or projections for future profitability provided in the report?"
]
# Category 4: Cash Flow and Liquidity
cash_flow_liquidity_questions = [
"What was the operating cash flow generated by the company during the fiscal year?",
"How does the cash flow from operations of the current year compare to the previous year?",
"Did the company experience any significant changes in its working capital management?",
"What were the major sources and uses of cash for the company during the year?",
"Has the company made any significant investments or divestments during the year?",
"How does the company's cash conversion cycle compare to industry benchmarks?",
"Are there any trends or patterns in the company's cash flow statement over the past few years?",
"What is the company's current ratio and quick ratio for assessing liquidity?",
"Did the company undertake any debt financing or equity financing activities?",
"Are there any forecasts or projections for future cash flow or liquidity provided in the report?"
]
# Define the options for the dropdown menu
categories = [
"Revenue and Sales",
"Expenses and Costs",
"Profitability and Financial Ratios",
"Cash Flow and Liquidity"
]
# Create a textbox to enter company's name
company_name = st.text_input("Enter the company's name:")
uploaded_file = st.file_uploader(f"Upload an Annual Report of {company_name} if available (PDF).", type=['pdf'])
toolkit = None
if uploaded_file is not None:
st.write("File uploaded successfully!")
file_contents = uploaded_file.read()
save_path = uploaded_file.name
with open(save_path, "wb") as f:
f.write(file_contents)
print(save_path)
loader = PyPDFLoader(save_path) #Step 1.1
documents = loader.load()
#1.2
text_splitter = CharacterTextSplitter(chunk_size=2000, chunk_overlap=0) #Splitting the text and creating chunks
docs = text_splitter.split_documents(documents)
if(mod=="OpenAI"):
embeddings = OpenAIEmbeddings()
if(mod=="Cohere"):
embeddings = CohereEmbeddings(cohere_api_key=api_key)
store = Chroma.from_documents(docs,embeddings)
vectorstore_info = VectorStoreInfo(
name="starbucks",
description="Starbucks financials",
vectorstore=store,
)
# llm = OpenAI(temperature=0.3)
toolkit = VectorStoreToolkit(llm=llm,vectorstore_info=vectorstore_info)
# Create a dropdown using the `selectbox` function
selected_category = st.selectbox("Select a category:", categories)
if(selected_category=="Revenue and Sales"):
selected_ques= st.selectbox("Select a category:", revenue_sales_questions)
if(selected_category=="Expenses and Costs"):
selected_ques= st.selectbox("Select a category:", expenses_costs_questions)
if(selected_category=="Profitability and Financial Ratios"):
selected_ques= st.selectbox("Select a category:", profitability_ratios_questions)
if(selected_category=="Cash Flow and Liquidity"):
selected_ques= st.selectbox("Select a category:", cash_flow_liquidity_questions)
# st.write(selected_ques)
ans=[]
if (st.button("Submit")):
output_res=[]
st.write("Company Name: " + company_name)
# llm = OpenAI(temperature=0.3)
tools = load_tools(["serpapi", "llm-math"], llm=llm)
agent = initialize_agent(llm = llm,
toolkit = toolkit,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
tools = tools,
verbose=True)
if(mod=='OpenAI'):
ans = financial_analyst(company_name)
st.write("Question asked by the user is " + selected_ques)
response = agent.run(selected_ques+f" Consider {ans}")
st.write(response)
st.write("Report")
st.write(ans)
prompt2="Make a line graph with Date as the x label and Closing Value as the y label and save the graph as an image file name of file as 'img2.png'"
prompt1="Make a line graph, x axis lables should be rotation = 90, save the graph as an image file and name of file as 'img1.png'"
# graphs('stocks_data.csv',prompt1)
# graphs('fin_data.csv',prompt2)
image_path = ['img1.png','img2.png']
generate_pdf(ans,image_path)
st.write("PDF generated successfully! Click below to download.")
# Download link
with open("output.pdf", "rb") as f:
st.download_button("Download PDF", f.read(), file_name="output.pdf", mime="application/pdf")
else:
try:
st.write("Question asked by the user is " + selected_ques)
response = agent.run(f"As a financial data analyst, your task is to thoroughly analyze \
the annual financial report of a company and provide accurate answers based solely on the data presented \
in the document. It is important to strictly adhere to the information provided in the report and \
refrain from making any assumptions or speculations. \
If necessary, you may utilize appropriate tools and formulas to derive the required answers.\
prompt = {selected_ques}")
print(response)
# response = agent.run(selected_ques)
st.write(response)
except:
st.write("Cohere Key Cannot give out the desired outputs. Pls provide OpenAI key for better results or try again!")