Nazhar commited on
Commit
fdc6557
·
verified ·
1 Parent(s): 44e6e5d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -345
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import streamlit as st
2
  import pandas as pd
3
  import plotly.express as px
@@ -7,10 +8,14 @@ import numpy as np
7
  import ast
8
  from pagination import paginator
9
  import style as cs
10
- # from ragfile2 import result
11
  import random
12
  import time
13
-
 
 
 
 
 
14
 
15
 
16
  # Utils Functions
@@ -66,65 +71,67 @@ def convert_str_to_list(string):
66
  # If the string cannot be converted to a list, return it as is
67
  return string
68
 
69
- title_container = st.container(border=False)
70
- # main_container.write(f"Date: {date}")
71
-
72
- col1, col2 = title_container.columns([0.2, 0.8], gap='medium')
73
- col1.image("logo.png")
74
- # st.image("logo.png", width=150)
75
- col2.title("AI Equity Advisor")
 
76
  c1, c2 = col2.columns([0.5, 0.5], gap="large")
77
  c1.markdown("Powered by GenInstigators")
78
- # Display disclaimer text using markdown
79
- # title_container.markdown("""
80
- # <div style='background-color:#b43c42; color:#ffffff; padding:8px; border-radius:3px; font-size:12px''>
81
- # <strong>Disclaimer:</strong> For demo purpose, the tool is currently populated with 10 months (Nov 2020 - Aug 2021) news and historical data of oil sector (OGDC) from PSX.
82
- # This data is intended to illustrate the tool's functionality and is not intended for actual investment decisions.
83
- # </div>
84
- # """, unsafe_allow_html=True)
85
- # Load data
86
  data_file_path = r"technicalRecommendation.csv" # Update this with your file path
87
  data = pd.read_csv(data_file_path)
88
 
89
  # Convert 'Date' column to datetime format
90
  data['Date'] = pd.to_datetime(data['Date'])
91
- # print(data.shape, data.columns)
92
 
93
- default_start_date = data['Date'].min() # Set default start date for the start date picker
94
- date_limit = pd.to_datetime(data['Date'].max()) # Set date limit for end date picker
 
 
95
  current_date = pd.to_datetime('2021-08-12')
96
 
97
  # Create Tabs
98
- market_analysis, news_analysis, final_recs, chat, chat2 = st.tabs(["Market Analysis", "News Analysis", "GenAI Recommendations",
99
- "Ask AI Advisor", "Ask AI Advisor 2"])
100
 
101
  with market_analysis:
102
  st.header("Market Analysis", help = "This module provides market analysis for the following day based on the current date.")
103
  # st.write("This module provides market analysis for the following day based on the current date.")
104
- date_container = st.container(border=False)
105
- # main_container.write(f"Date: {date}")
106
-
107
  col1, col2 = date_container.columns([0.5, 0.5], gap='medium')
108
  # start_date = col1.date_input('Start Date', value=default_start_date, min_value=data['Date'].min(), max_value=date_limit)
109
  end_date = col1.date_input("Current Date", value=current_date, min_value=data['Date'].min(), max_value=date_limit)
110
- start_date = data['Date'].min()
111
- start_date = pd.to_datetime(start_date)
 
112
  end_date = pd.to_datetime(end_date)
113
  data2 = data[data['Date'].between(start_date, end_date)]
114
 
115
  # Dropdown for selecting the indicator
116
  selected_indicator = st.selectbox("Select an Indicator", ['EMA 9', 'EMA 55', 'MACD', 'RSI'])
 
117
  # Dropdown for selecting the Number of Signal Days
118
  num_signals = st.selectbox("Signals to Show", ['None', 'All', 'Last 5 Days', 'Last 15 Days', 'Last 20 Days'])
 
 
119
  data2.rename(columns={'Close_price': 'Close Price', 'EMA_9': 'EMA 9', 'EMA_55': 'EMA 55'}, inplace=True)
120
-
 
121
  if selected_indicator == 'EMA 9':
122
  # Plot close price and EMA 9
123
  fig = px.line(data2, x='Date', y=['Close Price', 'EMA 9'], title='Close Price vs EMA 9',
124
  labels={'Date': 'Date', 'value': 'Price in Rs.', 'variable': 'Type'})
125
  fig.update_traces(selector=dict(type='scatter'))
126
- # Plot ‘strong buy’ signals
 
127
  if num_signals != 'None':
 
128
  strong_buy_dates, strong_sell_dates, strong_hold_dates = signals_to_plot(
129
  selected_indicator=selected_indicator,
130
  num_signals=num_signals,
@@ -371,32 +378,21 @@ with news_analysis:
371
  news = events[events['Date'].between(start_date, end_date, inclusive='both')]
372
  news = news[['Date', 'Raw_Headline', 'Bold_KW', 'Feature', 'Raw_News', 'Sources', 'Urls']]
373
 
374
- # pos_news = plot_sub_pos[['Date', 'Raw_Headline', 'Bold_KW', 'Feature', 'Raw_News', 'Sources', 'Urls']]
375
- # neg_news = plot_sub_neg[['Date', 'Raw_Headline', 'Bold_KW', 'Feature', 'Raw_News', 'Sources', 'Urls']]
376
 
377
-
378
- # pos_news[col] = pos_news[col].apply(convert_str_to_list)
379
- # neg_news[col] = neg_news[col].apply(convert_str_to_list)
380
  # Extract only the date part
381
  news['Date'] = news['Date'].dt.date
382
- # neg_news['Date'] = neg_news['Date'].dt.date
383
- # pos_news['Date'] = pos_news['Date'].dt.date
384
  # Sort DataFrame based on the 'Date' column in descending order
385
  news = news.sort_values(by='Date', ascending=False)
386
- # neg_news = neg_news.sort_values(by='Date', ascending=False)
387
- # pos_news = pos_news.sort_values(by='Date', ascending=False)
388
 
389
  # Reset index to reflect the new order
390
  news.reset_index(drop=True, inplace=True)
391
- # pos_news.reset_index(drop=True, inplace=True)
392
- # neg_news.reset_index(drop=True, inplace=True)
393
  st.subheader("News Events")
394
- # st.dataframe(news, hide_index=True)
395
- # st.table(news)
396
  dates = list(news['Date'].unique())
397
- # dates_neg = list(neg_news['Date'].unique())
398
- # dates_pos = list(pos_news['Date'].unique())
399
- # dates = dates_pos + dates_neg
400
  dates = np.sort(dates)
401
  # Reverse the array to have the latest date at index 0
402
  dates = dates[::-1]
@@ -431,206 +427,14 @@ with news_analysis:
431
  # st.divider()
432
  with st.expander("Oil Sector Features"):
433
  st.write(set(features))
434
- # if date in dates_pos:
435
- # filtered_news = pos_news[pos_news['Date'] == date]
436
- # print(filtered_news.shape)
437
- # features = filtered_news['Feature'].sum()
438
- # headlines = filtered_news['Raw_Headline'].sum()
439
- # news_list = filtered_news['Raw_News'].sum()
440
- # sources = filtered_news['Sources'].sum()
441
- # urls = filtered_news['Urls'].sum()
442
-
443
- # main_container = st.container(height = 250, border=True)
444
- # # main_container.write(f"Date: {date}")
445
-
446
- # col1, col2 = main_container.columns([0.7, 0.3], gap='medium')
447
-
448
- # # Merge lists of headlines into a single list
449
- # for index, headline in enumerate(headlines):
450
- # col1.page_link(urls[index], label=f"**:blue[{headline}]**")
451
- # # col1.write(f"<span style='font-size: large;'><b><u>{headline}</u></b></span>", unsafe_allow_html=True)
452
- # col1.write(f"<span style='font-size: small;'>By {sources[index]}</span><br>", unsafe_allow_html=True)
453
- # with col1:
454
- # with st.expander("Show Full Article"):
455
- # st.write(news_list[index])
456
-
457
- # with col2:
458
- # # st.divider()
459
- # with st.expander("Oil Sector Features"):
460
- # st.write(set(features))
461
-
462
- # if date in dates_neg:
463
- # filtered_news = neg_news[neg_news['Date'] == date]
464
- # print(filtered_news.shape)
465
- # features = filtered_news['Feature'].sum()
466
- # headlines = filtered_news['Raw_Headline'].sum()
467
- # news_list = filtered_news['Raw_News'].sum()
468
- # sources = filtered_news['Sources'].sum()
469
- # urls = filtered_news['Urls'].sum()
470
-
471
- # main_container = st.container(height = 250, border=True)
472
- # # main_container.write(f"Date: {date}")
473
-
474
- # col1, col2 = main_container.columns([0.7, 0.3], gap='medium')
475
-
476
- # # Merge lists of headlines into a single list
477
- # for index, headline in enumerate(headlines):
478
- # col1.page_link(urls[index], label=f"**:blue[{headline}]**")
479
- # # col1.write(f"<span style='font-size: large;'><b><u>{headline}</u></b></span>", unsafe_allow_html=True)
480
- # col1.write(f"<span style='font-size: small;'>By {sources[index]}</span><br>", unsafe_allow_html=True)
481
- # with col1:
482
- # with st.expander("Show Full Article"):
483
- # st.write(news_list[index])
484
-
485
- # with col2:
486
- # # st.divider()
487
- # with st.expander("Oil Sector Features"):
488
- # st.write(set(features))
489
 
490
  st.markdown("""
491
  <div style='background-color:#b43c42; color:#ffffff; padding:8px; border-radius:3px; font-size:12px''>
492
  <strong>Disclaimer:</strong> For demo purpose, the tool is currently populated with 10 months (Nov 2020 - Aug 2021) news and historical data of oil sector from PSX.
493
  This data is intended to illustrate the tool's functionality and is not intended for actual investment decisions.
494
  </div>
495
- """, unsafe_allow_html=True)
496
- # with trade_recs:
497
- # st.header("Trading Recommendations")
498
-
499
- # # Create the line trace for stock prices
500
- # # Dropdown for selecting the indicator
501
- # selected_indicator = st.selectbox("Indicator to Show", ['EMA 9', 'EMA 55', 'MACD', 'RSI'])
502
- # if selected_indicator == 'EMA 9':
503
- # column = 'EMA9_Signal'
504
- # hover_text = '%{x}<br>Close: %{y}<br> EMA9_Signal: %{customdata}<br>'
505
- # elif selected_indicator == 'EMA 55':
506
- # column = 'EMA55_Signal'
507
- # hover_text = '%{x}<br>Close: %{y}<br> EMA55_Signal: %{customdata}<br>'
508
- # elif selected_indicator == 'MACD':
509
- # column = 'MACD_Signals'
510
- # hover_text = '%{x}<br>Close: %{y}<br> MACD_Signal: %{customdata}<br>'
511
- # elif selected_indicator == 'RSI':
512
- # column = 'RSI_Signals'
513
- # hover_text = '%{x}<br>Close: %{y}<br> RSI_Signal: %{customdata}<br>'
514
- # line_stock = go.Scatter(x=events['Date'], y=events['Price'], mode='lines', name='OGDCL Close Price',
515
- # line=dict(dash='solid',color=cs.close_line_color, width=2), # color='royalblue'
516
- # text=[column],
517
- # # hovertext=events['FeatureSentiment'],
518
- # customdata=events[column],
519
- # hovertemplate=hover_text,
520
- # # hoverlabel=dict(font=dict(color=events
521
- # # ['FeatureSentiment'].apply(lambda x: 'red' if x == 'Negative' else 'blue' if x == 'Neutral' else 'green'))), # Customize the line style, color, and width
522
- # )
523
- # # Create dummy traces for the legend
524
- # dummy_positive = go.Scatter(x=[None], y=[None], mode='lines', name='Positive Impacts',
525
- # marker=dict(color=cs.pos_impacts_color, size=15), showlegend=True,
526
- # # visible='legendonly'
527
- # )
528
- # dummy_negative = go.Scatter(x=[None], y=[None], mode='lines', name='Negative Impacts',
529
- # marker=dict(color=cs.neg_impacts_color, size=15), showlegend=True,
530
- # # visible='legendonly'
531
- # )
532
-
533
- # fontsize = 12
534
- # annotations = []
535
- # # Create annotations for the Positive points
536
- # for index, row in plot_sub_pos.iterrows():
537
- # annotation1 = dict(x=row['Date'], y=row['Price'], text = row['Positive_Impacts'],
538
- # showarrow=True, arrowhead=0, # arrowcolor='black',
539
- # ax=10, ay=-20, # Dynamic offset
540
- # font=dict(size=fontsize, color=cs.pos_impacts_color),
541
- # )
542
- # annotations.append(annotation1)
543
-
544
- # # Create annotations for the Negative points
545
- # for index, row in plot_sub_neg.iterrows():
546
- # annotation2 = dict(x=row['Date'], y=row['Price'], text = row['Negative_Impacts'],
547
- # showarrow=True, arrowhead=0, arrowcolor=cs.close_line_color,
548
- # ax=10, ay=-20, # Dynamic offset
549
- # font=dict(size=fontsize, color=cs.neg_impacts_color),
550
- # )
551
- # annotations.append(annotation2)
552
-
553
- # # Create the layout
554
- # title = 'OGDCL Close Price w.r.t. News Impacts'
555
- # layout = go.Layout(
556
- # title=title,
557
- # xaxis=dict(
558
- # title='Date',
559
- # tickformat='%b %d, %Y',
560
- # # gridcolor='lightgray',
561
- # range=[start_date, end_date],
562
- # # tickvals=list(range(dateA, dateB, 3)),
563
- # ),
564
- # yaxis=dict(
565
- # title='OGDCL Close Price',
566
- # # gridcolor='lightgray',
567
- # range=[90, 120],
568
- # tickvals=list(range(90, 120, 5)),
569
- # ),
570
- # # plot_bgcolor='rgba(245, 245, 245, 0.8)',
571
- # # paper_bgcolor='white',
572
- # # hoverlabel=dict(
573
- # # bgcolor='white',
574
- # # font=dict(color='black'),
575
- # # ),
576
- # annotations=annotations,
577
- # )
578
-
579
- # # Add all traces to the figure
580
- # figure = go.Figure(data=[line_stock, dummy_negative, dummy_positive], layout=layout)
581
- # # figure.update_traces(mode="markers+lines")
582
- # figure.update_layout(
583
- # title={
584
- # 'text': title,
585
- # 'x': 0.5,
586
- # 'y': 0.95,
587
- # 'xanchor': 'center',
588
- # 'yanchor': 'top',
589
- # 'font': dict(size=12),
590
- # },
591
- # hovermode='closest',
592
- # margin=dict(l=40, r=40, t=80, b=40),
593
- # )
594
- # figure.update_xaxes(
595
- # rangeslider_visible=True,
596
- # rangeselector=dict(
597
- # buttons=list([
598
- # dict(count=1, label="1m", step="month", stepmode="backward"),
599
- # dict(count=6, label="6m", step="month", stepmode="backward"),
600
- # dict(count=1, label="YTD", step="year", stepmode="todate"),
601
- # dict(count=1, label="1y", step="year", stepmode="backward"),
602
- # dict(step="all")
603
- # ])
604
- # )
605
- # )
606
- # st.plotly_chart(figure)
607
- # if 'Trading_Recommendations\r' in events.columns:
608
- # events.rename(columns={'Trading_Recommendations\r': 'Trading_Recommendations'}, inplace=True)
609
-
610
- # print(events.columns)
611
- # trade_recs = events[['Date', 'Trading_Recommendations']]
612
- # # Extract date component from the datetime column
613
- # trade_recs['Date'] = trade_recs['Date'].dt.date
614
- # # Convert back to Dictionaries from strings
615
- # trade_recs['Trading_Recommendations'] = trade_recs['Trading_Recommendations'].apply(convert_str_to_list)
616
- # dates = list(trade_recs['Date'].unique())
617
- # dates = np.sort(dates)
618
- # # Reverse the array to have the latest date at index 0
619
- # dates = dates[::-1]
620
- # num_dates = len(dates)
621
- # items_per_page = min(num_dates, 5)
622
- # for i, date in paginator("Select Page Number", dates, items_per_page=items_per_page, on_sidebar=False, ukey='trade_pages'):
623
- # st.write(f'<span style="font-size: large;"><b>Date:</b> <u>{date}</u></span>', unsafe_allow_html=True)
624
-
625
- # filtered_trades = trade_recs[trade_recs['Date'] == date]
626
- # filtered_trades.reset_index(inplace=True)
627
- # rec = filtered_trades['Trading_Recommendations'][0]
628
- # print(type(rec), rec)
629
- # trade_container = st.container(border=False)
630
- # trade_container.write(rec)
631
-
632
- # # st.write(trade_recs)
633
-
634
 
635
 
636
  with final_recs:
@@ -775,104 +579,9 @@ with final_recs:
775
  </div>
776
  """, unsafe_allow_html=True)
777
 
 
778
  with chat:
779
- st.header("Chat with AI Stock Advisor")
780
 
781
- from langchain.indexes import VectorstoreIndexCreator
782
- from langchain.chains import RetrievalQA
783
- from langchain.llms import OpenAI
784
- from langchain_community.document_loaders import CSVLoader
785
- from langchain_text_splitters import RecursiveCharacterTextSplitter
786
- # from langchain_community.text_splitter import RecursiveCharacterTextSplitter
787
- from langchain_community.embeddings import HuggingFaceInstructEmbeddings
788
- from langchain_community.vectorstores import FAISS
789
- from langchain_community.llms import HuggingFaceHub
790
- from langchain_core.prompts import PromptTemplate
791
-
792
- def get_answer(text):
793
- text = response['result']
794
- helpful_answer_index = text.find('Helpful Answer:')
795
- if helpful_answer_index != -1:
796
- helpful_answer = text[helpful_answer_index + len('Helpful Answer:'):].strip()
797
- print(helpful_answer)
798
- else:
799
- print("No helpful answer found.")
800
- return helpful_answer
801
-
802
- # Streamed response emulator
803
- def response_generator(answer):
804
- response = answer
805
- for word in response.split():
806
- yield word + " "
807
- time.sleep(0.05)
808
-
809
- print("Libraries imported")
810
-
811
- loader = CSVLoader("Events_SameDay.csv",encoding='iso-8859-1')
812
- print("CSV imported")
813
-
814
- # Create an index using the loaded documents
815
- try:
816
- index_creator = VectorstoreIndexCreator()
817
- print("index_creator Created")
818
-
819
- docsearch = index_creator.from_loaders([loader])
820
- print("DB Created")
821
-
822
- repo_id = "mistralai/Mistral-7B-Instruct-v0.1"
823
- llm = HuggingFaceHub(repo_id=repo_id, model_kwargs={"temperature": 0.1, "max_new_tokens": 1024})
824
- print("MistralAi Loaded")
825
-
826
- prompt_temp="As a financial expert for stock market, if user is asking for trading recommendation, then you need to generate trading signal recommendations utilizing insights from two approaches. One is the technical indicators signals EMA55, RSI, EMA9, and MACD (all ranging from -3 to 3, where –3 is strong sell, -2 is moderate sell, -1 is weak sell, 0 is for hold, 1 is for weak buy, 2 is for moderate buy and 3 is for strong buy) from the respective signal while other insight is from news impacts (either positive or negative between -5 to 5). Provide your recommendation with balanced approach if news impact is too much positive or negative, technical indicator can be ignored and buy or sell suggestion based on news impact can be given. On the contrary, if technical indicators are opposite to news impact, a hold position is a reasonable suggestion. If technical indicators are all positive along news impact, strong buy signal can be generated. If technical indicators and news impact are all negative a strong sell signal can be generated. If news impact is too low, then generate recommendation based on technical indicator specially with more weightage to ema 55 in all the technical indicators. Your response should cover all technical aspects including the analysis of technical indicators as well as covering the news sentiments. Also cover some logical financial rational as well as the explanations."
827
- # Create a question-answering chain using the index
828
- chain = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=docsearch.vectorstore.as_retriever(), input_key="question")
829
- print("Chain Created")
830
-
831
- # Initialize chat history
832
- if "messages" not in st.session_state:
833
- st.session_state.messages = []
834
-
835
- # Display chat messages from history on app rerun
836
- for message in st.session_state.messages:
837
- with st.chat_message(message["role"]):
838
- st.markdown(message["content"])
839
-
840
- # Accept user input
841
- if prompt := st.chat_input("Enter your query here."):
842
- # Add user message to chat history
843
- st.session_state.messages.append({"role": "user", "content": prompt})
844
- # Display user message in chat message container
845
- with st.chat_message("user"):
846
- st.markdown(prompt)
847
-
848
- # question = query
849
- print(f"User Question: {prompt}")
850
- response = chain({"question": prompt})
851
- print("Answer generated")
852
- result = get_answer(response['result'])
853
- print("helpful answer extracted")
854
-
855
- # Display assistant response in chat message container
856
- with st.chat_message("assistant"):
857
- response = st.write_stream(response_generator(result))
858
- # Add assistant response to chat history
859
- st.session_state.messages.append({"role": "assistant", "content": response})
860
- except Exception as e:
861
- print(f"error type: {type(e)}")
862
- if hasattr(e, 'message') and 'You exceeded your current quota' in e.message:
863
- st.markdown(':red[Insufficient Quota]')
864
- st.write(f'You exceeded your current quota, please check your plan and billing details. For more information on this error, read the docs: https://platform.openai.com/docs/guides/error-codes/api-errors.')
865
-
866
- else:
867
- st.markdown(f"An Error Occured: \n {e}")
868
-
869
- with chat2:
870
- from langchain_community.document_loaders import CSVLoader
871
- from langchain_community.embeddings import HuggingFaceInstructEmbeddings
872
- from langchain_community.vectorstores import FAISS
873
- from langchain_community.llms import HuggingFaceHub
874
- from langchain_core.prompts import PromptTemplate
875
- from langchain.chains import RetrievalQA
876
 
877
  st.header("Chat with AI Stock Advisor")
878
 
@@ -916,21 +625,23 @@ with chat2:
916
  input_key="question",
917
  chain_type_kwargs={"prompt": sys_prompt})
918
 
919
- # Initialize chat history
920
- if "messages" not in st.session_state:
921
- st.session_state.messages = []
922
-
923
- # Display chat messages from history on app rerun
924
- for message in st.session_state.messages:
925
- with st.chat_message(message["role"]):
926
- st.markdown(message["content"])
 
 
927
 
928
  # Accept user input
929
  if prompt := st.chat_input("Enter your query here.", key='input2'):
930
  # Add user message to chat history
931
  st.session_state.messages.append({"role": "user", "content": prompt})
932
  # Display user message in chat message container
933
- with st.chat_message("user"):
934
  st.markdown(prompt)
935
 
936
  # question = query
@@ -941,7 +652,7 @@ with chat2:
941
  print("helpful answer extracted")
942
 
943
  # Display assistant response in chat message container
944
- with st.chat_message("assistant"):
945
  response = st.write_stream(response_generator(result))
946
  # Add assistant response to chat history
947
  st.session_state.messages.append({"role": "assistant", "content": response})
 
1
+ # Import Necessary Libraries
2
  import streamlit as st
3
  import pandas as pd
4
  import plotly.express as px
 
8
  import ast
9
  from pagination import paginator
10
  import style as cs
 
11
  import random
12
  import time
13
+ from langchain_community.document_loaders import CSVLoader
14
+ from langchain_community.embeddings import HuggingFaceInstructEmbeddings
15
+ from langchain_community.vectorstores import FAISS
16
+ from langchain_community.llms import HuggingFaceHub
17
+ from langchain_core.prompts import PromptTemplate
18
+ from langchain.chains import RetrievalQA
19
 
20
 
21
  # Utils Functions
 
71
  # If the string cannot be converted to a list, return it as is
72
  return string
73
 
74
+
75
+ # Add Title and Logo
76
+ title_container = st.container(border=False) # Create a container to hold the tile and logo
77
+ col1, col2 = title_container.columns([0.2, 0.8], gap='medium') # Create columns to display logo and title side-by-side
78
+ col1.image("logo.png") # Add logo to the 1st column
79
+ col2.title("AI Equity Advisor") # Add title to the 2nd column
80
+
81
+ # Add credits below the title
82
  c1, c2 = col2.columns([0.5, 0.5], gap="large")
83
  c1.markdown("Powered by GenInstigators")
84
+
85
+ # Load Technical Data
 
 
 
 
 
 
86
  data_file_path = r"technicalRecommendation.csv" # Update this with your file path
87
  data = pd.read_csv(data_file_path)
88
 
89
  # Convert 'Date' column to datetime format
90
  data['Date'] = pd.to_datetime(data['Date'])
 
91
 
92
+ # Set date limit for end date picker
93
+ date_limit = pd.to_datetime(data['Date'].max())
94
+
95
+ # Set default current date
96
  current_date = pd.to_datetime('2021-08-12')
97
 
98
  # Create Tabs
99
+ market_analysis, news_analysis, final_recs, chat = st.tabs(["Market Analysis", "News Analysis", "GenAI Recommendations", "Ask AI Advisor"])
 
100
 
101
  with market_analysis:
102
  st.header("Market Analysis", help = "This module provides market analysis for the following day based on the current date.")
103
  # st.write("This module provides market analysis for the following day based on the current date.")
104
+
105
+ # Add date picker
106
+ date_container = st.container(border=False)
107
  col1, col2 = date_container.columns([0.5, 0.5], gap='medium')
108
  # start_date = col1.date_input('Start Date', value=default_start_date, min_value=data['Date'].min(), max_value=date_limit)
109
  end_date = col1.date_input("Current Date", value=current_date, min_value=data['Date'].min(), max_value=date_limit)
110
+
111
+ # Filter data based on the date selected by the user
112
+ start_date = pd.to_datetime(data['Date'].min())
113
  end_date = pd.to_datetime(end_date)
114
  data2 = data[data['Date'].between(start_date, end_date)]
115
 
116
  # Dropdown for selecting the indicator
117
  selected_indicator = st.selectbox("Select an Indicator", ['EMA 9', 'EMA 55', 'MACD', 'RSI'])
118
+
119
  # Dropdown for selecting the Number of Signal Days
120
  num_signals = st.selectbox("Signals to Show", ['None', 'All', 'Last 5 Days', 'Last 15 Days', 'Last 20 Days'])
121
+
122
+ # Rename columns to maintain naming convention
123
  data2.rename(columns={'Close_price': 'Close Price', 'EMA_9': 'EMA 9', 'EMA_55': 'EMA 55'}, inplace=True)
124
+
125
+ # Plot Close Price vs the indicator selected by the user
126
  if selected_indicator == 'EMA 9':
127
  # Plot close price and EMA 9
128
  fig = px.line(data2, x='Date', y=['Close Price', 'EMA 9'], title='Close Price vs EMA 9',
129
  labels={'Date': 'Date', 'value': 'Price in Rs.', 'variable': 'Type'})
130
  fig.update_traces(selector=dict(type='scatter'))
131
+
132
+ # Plot buy/sell signals
133
  if num_signals != 'None':
134
+ # get signal values using the signals_to_plot function
135
  strong_buy_dates, strong_sell_dates, strong_hold_dates = signals_to_plot(
136
  selected_indicator=selected_indicator,
137
  num_signals=num_signals,
 
378
  news = events[events['Date'].between(start_date, end_date, inclusive='both')]
379
  news = news[['Date', 'Raw_Headline', 'Bold_KW', 'Feature', 'Raw_News', 'Sources', 'Urls']]
380
 
 
 
381
 
 
 
 
382
  # Extract only the date part
383
  news['Date'] = news['Date'].dt.date
384
+
 
385
  # Sort DataFrame based on the 'Date' column in descending order
386
  news = news.sort_values(by='Date', ascending=False)
387
+
 
388
 
389
  # Reset index to reflect the new order
390
  news.reset_index(drop=True, inplace=True)
391
+
 
392
  st.subheader("News Events")
393
+
 
394
  dates = list(news['Date'].unique())
395
+
 
 
396
  dates = np.sort(dates)
397
  # Reverse the array to have the latest date at index 0
398
  dates = dates[::-1]
 
427
  # st.divider()
428
  with st.expander("Oil Sector Features"):
429
  st.write(set(features))
430
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
 
432
  st.markdown("""
433
  <div style='background-color:#b43c42; color:#ffffff; padding:8px; border-radius:3px; font-size:12px''>
434
  <strong>Disclaimer:</strong> For demo purpose, the tool is currently populated with 10 months (Nov 2020 - Aug 2021) news and historical data of oil sector from PSX.
435
  This data is intended to illustrate the tool's functionality and is not intended for actual investment decisions.
436
  </div>
437
+ """, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
 
439
 
440
  with final_recs:
 
579
  </div>
580
  """, unsafe_allow_html=True)
581
 
582
+
583
  with chat:
 
584
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
585
 
586
  st.header("Chat with AI Stock Advisor")
587
 
 
625
  input_key="question",
626
  chain_type_kwargs={"prompt": sys_prompt})
627
 
628
+ chat_container = st.container(height = 300, border=False)
629
+ with chat_container:
630
+ # Initialize chat history
631
+ if "messages" not in st.session_state:
632
+ st.session_state.messages = []
633
+
634
+ # Display chat messages from history on app rerun
635
+ for message in st.session_state.messages:
636
+ with st.chat_message(message["role"]):
637
+ st.markdown(message["content"])
638
 
639
  # Accept user input
640
  if prompt := st.chat_input("Enter your query here.", key='input2'):
641
  # Add user message to chat history
642
  st.session_state.messages.append({"role": "user", "content": prompt})
643
  # Display user message in chat message container
644
+ with chat_container.chat_message("user"):
645
  st.markdown(prompt)
646
 
647
  # question = query
 
652
  print("helpful answer extracted")
653
 
654
  # Display assistant response in chat message container
655
+ with chat_container.chat_message("assistant"):
656
  response = st.write_stream(response_generator(result))
657
  # Add assistant response to chat history
658
  st.session_state.messages.append({"role": "assistant", "content": response})