ankur2402 commited on
Commit
d6702d1
1 Parent(s): de6984a

Upload 2 files

Browse files
Files changed (2) hide show
  1. requirements.txt +17 -0
  2. streamlit.py +423 -0
requirements.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ streamlit_chat
2
+ streamlit~=1.23.1
3
+ langchain~=0.0.225
4
+ sentence_transformers
5
+ utils~=1.0.1
6
+ cohere~=4.11.2
7
+ openai~=0.27.8
8
+ pypdf2~=3.0.1
9
+ tiktoken~=0.4.0
10
+ PyPDF2~=3.0.1
11
+ langchain~=0.0.231
12
+ chromadb~=0.3.27
13
+ yfinance~=0.2.25
14
+ yahooquery~=2.3.1
15
+ google-search-results~=2.4.2
16
+ fpdf~=1.7.2
17
+ pypdf~=3.12.1
streamlit.py ADDED
@@ -0,0 +1,423 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ # Import necessary libraries
4
+ import os
5
+ import requests
6
+ import json
7
+ import yfinance as yf
8
+ from yahooquery import Ticker
9
+ from fpdf import FPDF
10
+ from typing import List, Union
11
+ import re
12
+
13
+ # Import components from langchain and other libraries
14
+ from langchain.agents import load_tools, initialize_agent, create_csv_agent, AgentType, AgentExecutor, LLMSingleActionAgent, AgentOutputParser
15
+ from langchain.agents.agent_toolkits import create_vectorstore_agent, VectorStoreToolkit, VectorStoreInfo
16
+ from langchain.llms import OpenAI, Cohere
17
+ from langchain.document_loaders import PyPDFLoader, TextLoader, DirectoryLoader
18
+ from langchain.vectorstores import Chroma
19
+ from langchain.embeddings import CohereEmbeddings, OpenAIEmbeddings
20
+ from langchain.indexes import VectorstoreIndexCreator
21
+ from langchain.chains import RetrievalQA
22
+ from langchain.evaluation.qa import QAEvalChain
23
+ from langchain.prompts import StringPromptTemplate
24
+ from langchain.tools.python.tool import PythonREPLTool
25
+ from langchain.python import PythonREPL
26
+ from langchain import LLMMathChain, SerpAPIWrapper, LLMChain
27
+ from langchain.schema import AgentAction, AgentFinish, OutputParserException
28
+
29
+ # Set up Streamlit header and sidebar
30
+ st.header('FinAI')
31
+ mod = None
32
+ with st.sidebar:
33
+ with st.form('Cohere/OpenAI'):
34
+ # User selects the model (OpenAI/Cohere) and enters API keys
35
+ model = st.radio('Choose OpenAI/Cohere', ('OpenAI', 'Cohere'))
36
+ api_key = st.text_input('Enter API key', type="password")
37
+ serpAI_key = st.text_input('Enter SERPAIAPI key', type="password")
38
+ submitted = st.form_submit_button("Submit")
39
+
40
+ # Check if API key is provided and set up the language model accordingly
41
+ if api_key:
42
+ if model == 'OpenAI':
43
+ os.environ["OPENAI_API_KEY"] = api_key
44
+ llm = OpenAI(temperature=0.3)
45
+ mod = 'OpenAI'
46
+ os.environ["SERPAPI_API_KEY"] = serpAI_key
47
+ elif model == 'Cohere':
48
+ os.environ["Cohere_API_KEY"] = api_key
49
+ llm = Cohere(cohere_api_key=api_key)
50
+ mod = 'Cohere'
51
+ os.environ["SERPAPI_API_KEY"] = serpAI_key
52
+
53
+ # Helper function to get company news from SERP API
54
+ def get_company_news(company_name):
55
+ # Set the parameters for the SERP API request
56
+ params = {
57
+ "engine": "google",
58
+ "tbm": "nws",
59
+ "q": company_name,
60
+ "api_key": os.environ["SERPAPI_API_KEY"],
61
+ }
62
+
63
+ # Send the request and get the response data in JSON format
64
+ response = requests.get('https://serpapi.com/search', params=params)
65
+ data = response.json()
66
+
67
+ return data.get('news_results')
68
+
69
+ # Helper function to write news data to a file
70
+ def write_news_to_file(news, filename):
71
+ with open(filename, 'w') as file:
72
+ for news_item in news:
73
+ if news_item is not None:
74
+ title = news_item.get('title', 'No title')
75
+ link = news_item.get('link', 'No link')
76
+ date = news_item.get('date', 'No date')
77
+ file.write(f"Title: {title}\n")
78
+ file.write(f"Link: {link}\n")
79
+ file.write(f"Date: {date}\n\n")
80
+
81
+ # Helper function to get stock evolution data from Yahoo Finance API
82
+ def get_stock_evolution(company_name, period="1y"):
83
+ # Get the stock information using yfinance
84
+ stock = yf.Ticker(company_name)
85
+
86
+ # Get historical market data for the specified period
87
+ hist = stock.history(period=period)
88
+
89
+ # Convert the DataFrame to a string with a specific format
90
+ data_string = hist.to_string()
91
+
92
+ # Save the historical market data to a CSV file
93
+ hist.to_csv('stocks_data.csv')
94
+
95
+ # Get financials data
96
+ fin = stock.get_financials()
97
+ fin.to_csv('fin_data.csv')
98
+
99
+ # Append the string to the "investment.txt" file
100
+ with open("investment.txt", "a") as file:
101
+ file.write(f"\nStock Evolution for {company_name}:\n")
102
+ file.write(data_string)
103
+ file.write("\n")
104
+
105
+ # Helper function to get financial statements from Yahoo Finance API
106
+ def get_financial_statements(ticker):
107
+ # Create a Ticker object
108
+ company = Ticker(ticker)
109
+
110
+ # Get financial data for balance sheet, cash flow, income statement, and valuation measures
111
+ balance_sheet = company.balance_sheet().to_string()
112
+ cash_flow = company.cash_flow(trailing=False).to_string()
113
+ income_statement = company.income_statement().to_string()
114
+ valuation_measures = str(company.valuation_measures) # This one might already be a dictionary or string
115
+
116
+ # Write data to "investment.txt" file
117
+ with open("investment.txt", "a") as file:
118
+ file.write("\nBalance Sheet\n")
119
+ file.write(balance_sheet)
120
+ file.write("\nCash Flow\n")
121
+ file.write(cash_flow)
122
+ file.write("\nIncome Statement\n")
123
+ file.write(income_statement)
124
+ file.write("\nValuation Measures\n")
125
+ file.write(valuation_measures)
126
+
127
+ # Helper function to fetch data from different sources and store it in "investment.txt" file
128
+ def get_data(company_name, company_ticker, period="1y", filename="investment.txt"):
129
+ news = get_company_news(company_name)
130
+ if news:
131
+ write_news_to_file(news, filename)
132
+ else:
133
+ print("No news found.")
134
+
135
+ get_stock_evolution(company_ticker, period)
136
+
137
+ get_financial_statements(company_ticker)
138
+
139
+ # Helper function to call the language model for financial analysis based on user request
140
+ def financial_analyst(request):
141
+ # Print the request received from the user
142
+ print(f"Received request: {request}")
143
+
144
+ # Use OpenAI GPT-3.5 Turbo model to analyze the request and generate a response
145
+ response = openai.ChatCompletion.create(
146
+ model="gpt-3.5-turbo-16k",
147
+ messages=[{
148
+ "role": "user",
149
+ "content": f"Given the user request, what is the company name and the company stock ticker ?: {request}?"
150
+ }],
151
+ functions=[{
152
+ "name": "get_data",
153
+ "description": "Get financial data on a specific company for investment purposes",
154
+ "parameters": {
155
+ "type": "object",
156
+ "properties": {
157
+ "company_name": {
158
+ "type": "string",
159
+ "description": "The name of the company",
160
+ },
161
+ "company_ticker": {
162
+ "type": "string",
163
+ "description": "The ticker of the stock of the company"
164
+ },
165
+ "period": {
166
+ "type": "string",
167
+ "description": "The period of analysis"
168
+ },
169
+ "filename": {
170
+ "type": "string",
171
+ "description": "The filename to store data"
172
+ }
173
+ },
174
+ "required": ["company_name", "company_ticker"],
175
+ },
176
+ }],
177
+ function_call={"name": "get_data"},
178
+ )
179
+
180
+ # Extract the arguments and company information from the response
181
+ message = response["choices"][0]["message"]
182
+ if message.get("function_call"):
183
+ arguments = json.loads(message["function_call"]["arguments"])
184
+ company_name = arguments["company_name"]
185
+ company_ticker = arguments["company_ticker"]
186
+
187
+ # Call the function to fetch and store financial data
188
+ get_data(company_name, company_ticker)
189
+
190
+ # Read the contents of the "investment.txt" file for the response
191
+ with open("investment.txt", "r") as file:
192
+ content = file.read()[:14000]
193
+
194
+ # Use OpenAI GPT-3.5 Turbo model again to provide a detailed investment thesis
195
+ second_response = openai.ChatCompletion.create(
196
+ model="gpt-3.5-turbo-16k",
197
+ messages=[
198
+ {
199
+ "role": "user",
200
+ "content": request
201
+ },
202
+ message,
203
+ {
204
+ "role": "system",
205
+ "content": """write a detailed investment thesis to answer
206
+ the user request. Provide numbers to justify
207
+ your assertions, a lot ideally. Never mention
208
+ something like this:
209
+ However, it is essential to consider your own risk
210
+ tolerance, financial goals, and time horizon before
211
+ making any investment decisions. It is recommended
212
+ to consult with a financial advisor or do further
213
+ research to gain more insights into the company's
214
+ fundamentals and market trends. The user
215
+ already knows that"""
216
+ },
217
+ {
218
+ "role": "assistant",
219
+ "content": content,
220
+ },
221
+ ],
222
+ )
223
+
224
+ return second_response["choices"][0]["message"]["content"]
225
+
226
+ # Helper function to generate a PDF with text and images
227
+ def generate_pdf(text, image_paths):
228
+ # Create a FPDF object
229
+ pdf = FPDF()
230
+
231
+ # Add a page
232
+ pdf.add_page()
233
+
234
+ # Set style and size of font for the PDF
235
+ pdf.set_font("Arial", size=12)
236
+
237
+ # Set left and right margins
238
+ pdf.set_left_margin(20)
239
+ pdf.set_right_margin(20)
240
+
241
+ # Add multi-cell with line break for the text
242
+ pdf.multi_cell(0, 10, text)
243
+
244
+ # Move to the next line after the text
245
+ pdf.ln()
246
+
247
+ # Add a new page for the images
248
+ pdf.add_page()
249
+
250
+ # Add the first image to the PDF
251
+ pdf.image(image_paths[0], x=20, y=pdf.get_y(), w=175)
252
+
253
+ # Calculate the y-coordinate for the second image
254
+ second_image_y = pdf.get_y() + 150
255
+
256
+ # Add the second image to the PDF
257
+ pdf.image(image_paths[1], x=20, y=second_image_y, w=175)
258
+
259
+ # Save the PDF with the given file name
260
+ pdf.output("output.pdf")
261
+
262
+ # Helper function to generate graphs using langchain and save as images
263
+ def graphs(path, prompt):
264
+ agent = create_csv_agent(
265
+ OpenAI(temperature=0),
266
+ path,
267
+ verbose=True,
268
+ agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
269
+ )
270
+ agent.run(prompt)
271
+
272
+
273
+ # Category 1: Revenue and Sales
274
+ revenue_sales_questions = [
275
+ "What was the total revenue generated by the company during the fiscal year?",
276
+ "How does the revenue of the current year compare to the previous year?",
277
+ "Which product/service contributed the most to the company's revenue?",
278
+ "Did the company experience any significant changes in sales volume or pricing?",
279
+ "Are there any notable trends or patterns in the revenue growth of the company over the past few years?",
280
+ "What were the geographical regions or markets where the company generated the highest revenue?",
281
+ "Has the company introduced any new revenue streams or business lines?",
282
+ "Were there any extraordinary events or factors that affected the company's revenue performance?",
283
+ "How does the revenue composition of the company compare to its competitors in the industry?",
284
+ "Are there any forecasts or projections for future revenue growth provided in the report?"
285
+ ]
286
+
287
+ # Category 2: Expenses and Costs
288
+ expenses_costs_questions = [
289
+ "What were the major expense categories for the company during the fiscal year?",
290
+ "How do the expenses of the current year compare to the previous year?",
291
+ "Did the company implement any cost-saving measures or efficiency improvements?",
292
+ "Were there any significant changes in the cost of raw materials or production inputs?",
293
+ "How does the company's expense ratio compare to industry benchmarks?",
294
+ "Did the company incur any one-time or non-recurring expenses during the year?",
295
+ "Are there any trends or patterns in the company's cost structure over the past few years?",
296
+ "Has the company invested in research and development (R&D) or capital expenditures?",
297
+ "What were the employee-related costs and benefits provided by the company?",
298
+ "Are there any forecasts or projections for future cost management initiatives provided in the report?"
299
+ ]
300
+
301
+ # Category 3: Profitability and Financial Ratios
302
+ profitability_ratios_questions = [
303
+ "What was the net profit or net income generated by the company during the fiscal year?",
304
+ "How does the profitability of the current year compare to the previous year?",
305
+ "What is the company's gross profit margin and how has it changed over time?",
306
+ "Did the company experience any changes in operating profit or operating margin?",
307
+ "What is the return on assets (ROA) and return on equity (ROE) for the company?",
308
+ "Has the company improved its profitability compared to its competitors in the industry?",
309
+ "Are there any trends or patterns in the company's profitability ratios over the past few years?",
310
+ "Did the company face any challenges or risks that impacted its profitability?",
311
+ "How does the company's profitability ratios compare to industry benchmarks?",
312
+ "Are there any forecasts or projections for future profitability provided in the report?"
313
+ ]
314
+
315
+ # Category 4: Cash Flow and Liquidity
316
+ cash_flow_liquidity_questions = [
317
+ "What was the operating cash flow generated by the company during the fiscal year?",
318
+ "How does the cash flow from operations of the current year compare to the previous year?",
319
+ "Did the company experience any significant changes in its working capital management?",
320
+ "What were the major sources and uses of cash for the company during the year?",
321
+ "Has the company made any significant investments or divestments during the year?",
322
+ "How does the company's cash conversion cycle compare to industry benchmarks?",
323
+ "Are there any trends or patterns in the company's cash flow statement over the past few years?",
324
+ "What is the company's current ratio and quick ratio for assessing liquidity?",
325
+ "Did the company undertake any debt financing or equity financing activities?",
326
+ "Are there any forecasts or projections for future cash flow or liquidity provided in the report?"
327
+ ]
328
+ # Define the options for the dropdown menu
329
+ categories = [
330
+ "Revenue and Sales",
331
+ "Expenses and Costs",
332
+ "Profitability and Financial Ratios",
333
+ "Cash Flow and Liquidity"
334
+ ]
335
+ # Create a textbox to enter company's name
336
+ company_name = st.text_input("Enter the company's name:")
337
+
338
+ uploaded_file = st.file_uploader(f"Upload an Annual Report of {company_name} if available (PDF).", type=['pdf'])
339
+ toolkit = None
340
+ if uploaded_file is not None:
341
+ st.write("File uploaded successfully!")
342
+ file_contents = uploaded_file.read()
343
+ save_path = uploaded_file.name
344
+ with open(save_path, "wb") as f:
345
+ f.write(file_contents)
346
+ print(save_path)
347
+ loader = PyPDFLoader(save_path) #Step 1.1
348
+ documents = loader.load()
349
+ #1.2
350
+ text_splitter = CharacterTextSplitter(chunk_size=2000, chunk_overlap=0) #Splitting the text and creating chunks
351
+ docs = text_splitter.split_documents(documents)
352
+ if(mod=="OpenAI"):
353
+ embeddings = OpenAIEmbeddings()
354
+ if(mod=="Cohere"):
355
+ embeddings = CohereEmbeddings(cohere_api_key=api_key)
356
+ store = Chroma.from_documents(docs,embeddings)
357
+ vectorstore_info = VectorStoreInfo(
358
+ name="starbucks",
359
+ description="Starbucks financials",
360
+ vectorstore=store,
361
+ )
362
+ # llm = OpenAI(temperature=0.3)
363
+ toolkit = VectorStoreToolkit(llm=llm,vectorstore_info=vectorstore_info)
364
+
365
+
366
+ # Create a dropdown using the `selectbox` function
367
+ selected_category = st.selectbox("Select a category:", categories)
368
+
369
+ if(selected_category=="Revenue and Sales"):
370
+ selected_ques= st.selectbox("Select a category:", revenue_sales_questions)
371
+ if(selected_category=="Expenses and Costs"):
372
+ selected_ques= st.selectbox("Select a category:", expenses_costs_questions)
373
+ if(selected_category=="Profitability and Financial Ratios"):
374
+ selected_ques= st.selectbox("Select a category:", profitability_ratios_questions)
375
+ if(selected_category=="Cash Flow and Liquidity"):
376
+ selected_ques= st.selectbox("Select a category:", cash_flow_liquidity_questions)
377
+
378
+ # st.write(selected_ques)
379
+
380
+ ans=[]
381
+ if (st.button("Submit")):
382
+ output_res=[]
383
+
384
+ st.write("Company Name: " + company_name)
385
+
386
+ # llm = OpenAI(temperature=0.3)
387
+ tools = load_tools(["serpapi", "llm-math"], llm=llm)
388
+ agent = initialize_agent(llm = llm,
389
+ toolkit = toolkit,
390
+ agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
391
+ tools = tools,
392
+ verbose=True)
393
+ if(mod=='OpenAI'):
394
+ ans = financial_analyst(company_name)
395
+ st.write("Question asked by the user is " + selected_ques)
396
+ response = agent.run(selected_ques+f" Consider {ans}")
397
+ st.write(response)
398
+ st.write("Report")
399
+ st.write(ans)
400
+ 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'"
401
+ 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'"
402
+ graphs('stocks_data.csv',prompt1)
403
+ graphs('fin_data.csv',prompt2)
404
+ image_path = ['img1.png','img2.png']
405
+ generate_pdf(ans,image_path)
406
+ st.write("PDF generated successfully! Click below to download.")
407
+ # Download link
408
+ with open("output.pdf", "rb") as f:
409
+ st.download_button("Download PDF", f.read(), file_name="output.pdf", mime="application/pdf")
410
+ else:
411
+ try:
412
+ st.write("Question asked by the user is " + selected_ques)
413
+ response = agent.run(f"As a financial data analyst, your task is to thoroughly analyze \
414
+ the annual financial report of a company and provide accurate answers based solely on the data presented \
415
+ in the document. It is important to strictly adhere to the information provided in the report and \
416
+ refrain from making any assumptions or speculations. \
417
+ If necessary, you may utilize appropriate tools and formulas to derive the required answers.\
418
+ prompt = {selected_ques}")
419
+ print(response)
420
+ # response = agent.run(selected_ques)
421
+ st.write(response)
422
+ except:
423
+ st.write("Cohere Key Cannot give out the desired outputs. Pls provide OpenAI key for better results or try again!")