Karthikeyen92
commited on
Commit
•
dd16aed
1
Parent(s):
4bfd700
Update app.py
Browse files
app.py
CHANGED
@@ -106,7 +106,7 @@ class StockAdviserUI:
|
|
106 |
|
107 |
def _setup_header(self):
|
108 |
st.markdown("<h1 class='main-header'>Stock Analysis with Generative AI</h1>", unsafe_allow_html=True)
|
109 |
-
st.markdown("<h3 class='main-header'>using RAG</h3>", unsafe_allow_html=True)
|
110 |
with st.expander("Available Historical Demo Companies"):
|
111 |
st.markdown("""
|
112 |
For Demo purpose, historical data is available only for the below companies:
|
@@ -219,6 +219,91 @@ class StockAdviser:
|
|
219 |
self.config.models.embedding_model = embedding_model
|
220 |
return self.config.models
|
221 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
def get_symbol(self, user_question):
|
223 |
qna_system_message = """
|
224 |
You are an assistant to a financial services firm who finds the 'nse company symbol' (assigned to the company in the provided stock market)) of the company in the question provided.
|
@@ -258,8 +343,7 @@ class StockAdviser:
|
|
258 |
return cmp_tkr
|
259 |
|
260 |
|
261 |
-
def process_historical_data(self,
|
262 |
-
cmp_tr = self.get_symbol(user_question)
|
263 |
|
264 |
# Initialize ChromaDB Database
|
265 |
chroma_db = DBStorage(hugg)
|
@@ -274,8 +358,7 @@ class StockAdviser:
|
|
274 |
|
275 |
return cmp_tr
|
276 |
|
277 |
-
def display_charts(self,cmp_tr,sentiment_response):
|
278 |
-
sentiment = self._extract_between(sentiment_response, "Overall Sentiment:", "Overall Justification:").strip()
|
279 |
|
280 |
days = 365
|
281 |
|
@@ -318,18 +401,21 @@ class StockAdviser:
|
|
318 |
# Display volume chart
|
319 |
st.plotly_chart(self.visualizer.create_volume_chart(df, cmp_tr))
|
320 |
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
|
|
|
|
|
|
333 |
|
334 |
def get_nse_stock_data(self,symbol, days):
|
335 |
"""
|
@@ -623,6 +709,34 @@ class StockAdviser:
|
|
623 |
|
624 |
return base_prompt + example_analysis + response_format + common_format + citation_format + instr + instr2, dcument
|
625 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
626 |
|
627 |
def main(hugg):
|
628 |
adviser = StockAdviser()
|
@@ -635,62 +749,62 @@ def main(hugg):
|
|
635 |
)
|
636 |
|
637 |
with st.sidebar:
|
638 |
-
|
639 |
st.markdown("""
|
640 |
<div style="background-color: #2d2d2d; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(255, 255, 255, 0.1);">
|
641 |
-
<h2 style="color: #e6e6e6; text-align:
|
642 |
-
<p style="font-size: 16px; color: #
|
643 |
-
This application provides investment managers with daily insights into
|
644 |
-
|
645 |
-
<
|
646 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
647 |
</p>
|
648 |
-
<p style="font-size: 16px; color: #
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
sentiment-driven market.
|
653 |
</p>
|
654 |
</div>
|
655 |
-
|
656 |
""", unsafe_allow_html=True)
|
|
|
657 |
# Sidebar Footer (Floating Footer)
|
658 |
st.sidebar.markdown("""
|
659 |
-
<div style="position: fixed; bottom:
|
660 |
-
<p style="color: #cccccc; font-size: 14px;">
|
661 |
Developed by: <a href="https://www.linkedin.com/in/karthikeyen92/" target="_blank" style="color: #4DA8DA; text-decoration: none;">Karthikeyen Packirisamy</a>
|
662 |
</p>
|
663 |
</div>
|
664 |
""", unsafe_allow_html=True)
|
665 |
-
|
666 |
|
667 |
|
668 |
# Main content
|
669 |
cmp_tr = "NOTICKER"
|
670 |
st.header("Ask a question")
|
671 |
-
user_question = st.text_input("
|
672 |
-
|
673 |
-
col1, col2 = st.columns(2)
|
674 |
-
|
675 |
-
with col1:
|
676 |
-
if user_question:
|
677 |
-
st.markdown("<h3 class='little-header'>Historical Analysis</h3>", unsafe_allow_html=True)
|
678 |
-
with st.container():
|
679 |
-
cmp_tr = adviser.process_historical_data(user_question, hugg)
|
680 |
-
|
681 |
-
with col2:
|
682 |
-
if user_question:
|
683 |
-
st.markdown("<h3 class='little-header'>Real-Time Analysis</h3>", unsafe_allow_html=True)
|
684 |
-
with st.container():
|
685 |
-
sentiment_response = adviser.process_realtime_data(cmp_tr, hugg)
|
686 |
-
|
687 |
-
if (str(cmp_tr) != "NOTICKER"):
|
688 |
-
with st.container():
|
689 |
-
if user_question:
|
690 |
-
adviser.display_charts(cmp_tr,sentiment_response)
|
691 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
692 |
st.markdown("---")
|
693 |
-
st.markdown("<p style='text-align: center; color: #666;'>© 2024
|
694 |
|
695 |
if __name__ == "__main__":
|
696 |
hugg = os.getenv("IS_HUGG") == "True"
|
|
|
106 |
|
107 |
def _setup_header(self):
|
108 |
st.markdown("<h1 class='main-header'>Stock Analysis with Generative AI</h1>", unsafe_allow_html=True)
|
109 |
+
st.markdown("<h3 class='main-header'>using Agents and RAG</h3>", unsafe_allow_html=True)
|
110 |
with st.expander("Available Historical Demo Companies"):
|
111 |
st.markdown("""
|
112 |
For Demo purpose, historical data is available only for the below companies:
|
|
|
219 |
self.config.models.embedding_model = embedding_model
|
220 |
return self.config.models
|
221 |
|
222 |
+
def stock_agent(self, user_question):
|
223 |
+
functions=[
|
224 |
+
{
|
225 |
+
"name":"get_advise",
|
226 |
+
"description":"Get only advise on a NSE stock",
|
227 |
+
"parameters":{
|
228 |
+
"type":"object",
|
229 |
+
"properties":{
|
230 |
+
"company":{
|
231 |
+
"type":"string",
|
232 |
+
"description":"Please find the 'nse company symbol' of the company in the question provided. In case of an invalid company, return 'NOTICKER'.",
|
233 |
+
},
|
234 |
+
|
235 |
+
},
|
236 |
+
"required":["company"]
|
237 |
+
},
|
238 |
+
},
|
239 |
+
{
|
240 |
+
"name":"get_stats",
|
241 |
+
"description":"Get only statistics/status on a NSE stock",
|
242 |
+
"parameters":{
|
243 |
+
"type":"object",
|
244 |
+
"properties":{
|
245 |
+
"company":{
|
246 |
+
"type":"string",
|
247 |
+
"description":"Please find the 'nse company symbol' of the company in the question provided. In case of an invalid company, return 'NOTICKER'.",
|
248 |
+
},
|
249 |
+
|
250 |
+
},
|
251 |
+
"required":["company"]
|
252 |
+
},
|
253 |
+
},
|
254 |
+
{
|
255 |
+
"name":"get_adv_stats",
|
256 |
+
"description":"Get both advise and statistics/status on a NSE stock",
|
257 |
+
"parameters":{
|
258 |
+
"type":"object",
|
259 |
+
"properties":{
|
260 |
+
"company":{
|
261 |
+
"type":"string",
|
262 |
+
"description":"Please find the 'nse company symbol' of the company in the question provided. In case of an invalid company, return 'NOTICKER'.",
|
263 |
+
},
|
264 |
+
|
265 |
+
},
|
266 |
+
"required":["company"]
|
267 |
+
},
|
268 |
+
},
|
269 |
+
{
|
270 |
+
"name":"get_none",
|
271 |
+
"description":"Get details other than advise or statistics/status on a NSE stock",
|
272 |
+
"parameters":{
|
273 |
+
"type":"object",
|
274 |
+
"properties":{
|
275 |
+
"company":{
|
276 |
+
"type":"string",
|
277 |
+
"description":"""
|
278 |
+
For any queries other than advise or statistics/status on a NSE stock, only return "NOTICKER".
|
279 |
+
""",
|
280 |
+
},
|
281 |
+
|
282 |
+
},
|
283 |
+
"required":["company"]
|
284 |
+
},
|
285 |
+
}
|
286 |
+
]
|
287 |
+
|
288 |
+
|
289 |
+
initial_response = self.client.chat.completions.create(
|
290 |
+
model=self.config.azure_config["model_deployment"],
|
291 |
+
messages=[
|
292 |
+
{"role": "system", "content": "You are a helpful assistant to understand the context of input query on NSE stock advise and statistics."},
|
293 |
+
{"role": "user", "content": user_question}
|
294 |
+
],
|
295 |
+
functions=functions
|
296 |
+
)
|
297 |
+
|
298 |
+
print (initial_response)
|
299 |
+
function_name = initial_response.choices[0].message.function_call.name
|
300 |
+
function_argument = json.loads(initial_response.choices[0].message.function_call.arguments)
|
301 |
+
company= function_argument['company']
|
302 |
+
print(function_name)
|
303 |
+
print(company)
|
304 |
+
return function_name
|
305 |
+
|
306 |
+
|
307 |
def get_symbol(self, user_question):
|
308 |
qna_system_message = """
|
309 |
You are an assistant to a financial services firm who finds the 'nse company symbol' (assigned to the company in the provided stock market)) of the company in the question provided.
|
|
|
343 |
return cmp_tkr
|
344 |
|
345 |
|
346 |
+
def process_historical_data(self, cmp_tr, hugg = False):
|
|
|
347 |
|
348 |
# Initialize ChromaDB Database
|
349 |
chroma_db = DBStorage(hugg)
|
|
|
358 |
|
359 |
return cmp_tr
|
360 |
|
361 |
+
def display_charts(self,cmp_tr,sentiment_response="none"):
|
|
|
362 |
|
363 |
days = 365
|
364 |
|
|
|
401 |
# Display volume chart
|
402 |
st.plotly_chart(self.visualizer.create_volume_chart(df, cmp_tr))
|
403 |
|
404 |
+
if sentiment_response != "none":
|
405 |
+
sentiment = self._extract_between(sentiment_response, "Overall Sentiment:", "Overall Justification:").strip()
|
406 |
+
|
407 |
+
# Display sentiment gauge (simulate sentiment score)
|
408 |
+
# Generating random score for Demo purpose
|
409 |
+
if sentiment == "Negative":
|
410 |
+
sentiment_score = np.random.uniform(-1, -0.75)
|
411 |
+
elif sentiment == "Neutral":
|
412 |
+
sentiment_score = np.random.uniform(-0.75, 0.25)
|
413 |
+
elif sentiment == "Positive":
|
414 |
+
sentiment_score = np.random.uniform(0.25, 1)
|
415 |
+
else:
|
416 |
+
sentiment_score = 0
|
417 |
+
|
418 |
+
st.plotly_chart(self.visualizer.create_sentiment_gauge(sentiment_score))
|
419 |
|
420 |
def get_nse_stock_data(self,symbol, days):
|
421 |
"""
|
|
|
709 |
|
710 |
return base_prompt + example_analysis + response_format + common_format + citation_format + instr + instr2, dcument
|
711 |
|
712 |
+
def get_advise(user_question,adviser,cmp_tr,sentiment_response,hugg):
|
713 |
+
col1, col2 = st.columns(2)
|
714 |
+
with col1:
|
715 |
+
if user_question:
|
716 |
+
st.markdown("<h3 class='little-header'>Historical Analysis</h3>", unsafe_allow_html=True)
|
717 |
+
with st.container():
|
718 |
+
adviser.process_historical_data(cmp_tr, hugg)
|
719 |
+
|
720 |
+
with col2:
|
721 |
+
if user_question:
|
722 |
+
st.markdown("<h3 class='little-header'>Real-Time Analysis</h3>", unsafe_allow_html=True)
|
723 |
+
with st.container():
|
724 |
+
sentiment_response = adviser.process_realtime_data(cmp_tr, hugg)
|
725 |
+
|
726 |
+
return sentiment_response
|
727 |
+
|
728 |
+
def get_stats(user_question,adviser,cmp_tr,sentiment_response,hugg):
|
729 |
+
if (str(cmp_tr) != "NOTICKER"):
|
730 |
+
with st.container():
|
731 |
+
if user_question:
|
732 |
+
adviser.display_charts(cmp_tr,sentiment_response)
|
733 |
+
|
734 |
+
def get_adv_stats(user_question,adviser,cmp_tr,sentiment_response,hugg):
|
735 |
+
sentiment_response = get_advise(user_question,adviser,cmp_tr,sentiment_response,hugg)
|
736 |
+
get_stats(user_question,adviser,cmp_tr,sentiment_response,hugg)
|
737 |
+
|
738 |
+
def get_none(user_question,adviser,cmp_tr,sentiment_response,hugg):
|
739 |
+
st.write("Please enter a valid NSE stock enquiry.")
|
740 |
|
741 |
def main(hugg):
|
742 |
adviser = StockAdviser()
|
|
|
749 |
)
|
750 |
|
751 |
with st.sidebar:
|
752 |
+
# About the Application (Main Area)
|
753 |
st.markdown("""
|
754 |
<div style="background-color: #2d2d2d; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(255, 255, 255, 0.1);">
|
755 |
+
<h2 style="color: #e6e6e6; text-align: center;">About the Application</h2>
|
756 |
+
<p style="font-size: 16px; color: #d9d9d9; line-height: 1.6; text-align: justify;">
|
757 |
+
This application provides <span style="color: #80b1c1;"><strong>investment managers</strong></span> with daily insights into
|
758 |
+
<span style="color: #d3b673;"><strong>social media</strong></span> and <span style="color: #d3b673;"><strong>news sentiment</strong></span> surrounding
|
759 |
+
specific <span style="color: #80b1c1;"><strong>stocks and companies</strong></span>. By analyzing posts and articles across major platforms
|
760 |
+
such as <strong style="color: #b0b0b0;">Reddit</strong>, <strong style="color: #b0b0b0;">YouTube</strong>, <strong style="color: #b0b0b0;">Tumblr</strong>,
|
761 |
+
<strong style="color: #b0b0b0;">Google News</strong>, <strong style="color: #b0b0b0;">Financial Times</strong>, <strong style="color: #b0b0b0;">Bloomberg</strong>,
|
762 |
+
<strong style="color: #b0b0b0;">Reuters</strong>, and <strong style="color: #b0b0b0;">Wall Street Journal</strong> (WSJ), it detects shifts in public
|
763 |
+
and media opinion that may impact stock performance.
|
764 |
+
</p>
|
765 |
+
<p style="font-size: 16px; color: #d9d9d9; line-height: 1.6; text-align: justify;">
|
766 |
+
Additionally, sources like <span style="color: #80b1c1;"><strong>Serper</strong></span> provide data from
|
767 |
+
<span style="color: #d3b673;"><strong>StockNews</strong></span>, <span style="color: #d3b673;"><strong>Yahoo Finance</strong></span>,
|
768 |
+
<span style="color: #d3b673;"><strong>Insider Monkey</strong></span>, <span style="color: #d3b673;"><strong>Investor's Business Daily</strong></span>,
|
769 |
+
and others. Using advanced <span style="color: #80b1c1;"><strong>AI techniques</strong></span>, the application generates a
|
770 |
+
<span style="color: #d3b673;"><strong>sentiment report</strong></span> that serves as a leading indicator, helping managers make informed,
|
771 |
+
timely adjustments to their positions. With daily updates and <span style="color: #d3b673;"><strong>historical trend analysis</strong></span>,
|
772 |
+
it empowers users to stay ahead in a fast-paced, sentiment-driven market.
|
773 |
</p>
|
774 |
+
<p style="font-size: 16px; color: #d9d9d9; line-height: 1.6; text-align: justify;">
|
775 |
+
The application also utilizes <span style="color: #80b1c1;"><strong>intelligent agent functions</strong></span> to determine the type of query input
|
776 |
+
by the user. It assesses whether the query seeks <span style="color: #d3b673;"><strong>stock statistics</strong></span>,
|
777 |
+
<span style="color: #d3b673;"><strong>sentiment-analyzed advice</strong></span>, both, or is unrelated, providing the most relevant response accordingly.
|
|
|
778 |
</p>
|
779 |
</div>
|
|
|
780 |
""", unsafe_allow_html=True)
|
781 |
+
|
782 |
# Sidebar Footer (Floating Footer)
|
783 |
st.sidebar.markdown("""
|
784 |
+
<div style="position: fixed; bottom: 25px; background-color: #1f1f1f; padding: 1px; border-radius: 15px; text-align: center;">
|
785 |
+
<p style="color: #cccccc; font-size: 14px; text-align: center; margin: 0;">
|
786 |
Developed by: <a href="https://www.linkedin.com/in/karthikeyen92/" target="_blank" style="color: #4DA8DA; text-decoration: none;">Karthikeyen Packirisamy</a>
|
787 |
</p>
|
788 |
</div>
|
789 |
""", unsafe_allow_html=True)
|
790 |
+
|
791 |
|
792 |
|
793 |
# Main content
|
794 |
cmp_tr = "NOTICKER"
|
795 |
st.header("Ask a question")
|
796 |
+
user_question = st.text_input("Please ask statistical or advice or both related questions on a NSE stock.", key="user_question")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
797 |
|
798 |
+
if user_question.strip():
|
799 |
+
cmp_tr = adviser.get_symbol(user_question)
|
800 |
+
sentiment_response = "none"
|
801 |
+
|
802 |
+
agent_function = adviser.stock_agent(user_question)
|
803 |
+
getattr(sys.modules[__name__], agent_function)(user_question,adviser,cmp_tr,sentiment_response,hugg)
|
804 |
+
|
805 |
+
# get_adv_stats(user_question,adviser,cmp_tr,sentiment_response,hugg)
|
806 |
st.markdown("---")
|
807 |
+
st.markdown("<p style='text-align: center; color: #666;'>© 2024 Karthikeyen</p>", unsafe_allow_html=True)
|
808 |
|
809 |
if __name__ == "__main__":
|
810 |
hugg = os.getenv("IS_HUGG") == "True"
|