|
import streamlit as st |
|
import os |
|
import getpass |
|
from langchain import PromptTemplate |
|
from langchain import hub |
|
from langchain.docstore.document import Document |
|
from langchain.document_loaders import WebBaseLoader |
|
from langchain.schema import StrOutputParser |
|
from langchain.schema.prompt_template import format_document |
|
from langchain.schema.runnable import RunnablePassthrough |
|
import google.generativeai as genai |
|
from langchain_google_genai import GoogleGenerativeAIEmbeddings |
|
from langchain_google_genai import ChatGoogleGenerativeAI |
|
from langchain.chains.llm import LLMChain |
|
from langchain.chains import StuffDocumentsChain |
|
from langchain_core.messages import HumanMessage |
|
import requests |
|
from tradingview_ta import TA_Handler, Interval |
|
import yfinance as yf |
|
from datetime import datetime, timedelta |
|
from newsapi import NewsApiClient |
|
import json |
|
import altair as alt |
|
|
|
st.set_page_config(layout="wide") |
|
|
|
GOOGLE_API_KEY=os.environ['GOOGLE_API_KEY'] |
|
|
|
st.title('Stock Market Insights') |
|
st.sidebar.image("https://myndroot.com/wp-content/uploads/2023/12/Gemini-Dext.jpg",width =100) |
|
st.sidebar.markdown("The App uses **Google Gemini API** for Text and Vision along with π¦οΈπ LangChain") |
|
st.sidebar.info("Know more about [NSE Tickers](https://www.google.com/search?q=nse+tickers+list&sca_esv=a6c39f4d03c5324c&sca_upv=1&rlz=1C1GCEB_enIN1011IN1011&sxsrf=ADLYWILQPbew-0SrvUUWpI8Y29_uOOgbvA%3A1716470016765&ei=AEFPZp-zLvzHp84P_ZWtuA0&oq=NSE+Tickers+&gs_lp=Egxnd3Mtd2l6LXNlcnAiDE5TRSBUaWNrZXJzICoCCAAyBRAAGIAEMggQABgWGAoYHjIGEAAYFhgeMgYQABgWGB4yBhAAGBYYHjIGEAAYFhgeMgYQABgWGB4yBhAAGBYYHjILEAAYgAQYhgMYigUyCxAAGIAEGIYDGIoFSIIbUL0PWL0PcAF4AZABAJgB8QKgAfECqgEDMy0xuAEByAEA-AEBmAICoAKKA8ICChAAGLADGNYEGEeYAwCIBgGQBgiSBwUxLjMtMaAHtQU&sclient=gws-wiz-serp)") |
|
|
|
st.sidebar.info("Know more about [Charts](https://chart-img.com/)") |
|
ticker_user = st.text_input("Enter Ticker for NSE Stocks","") |
|
gemini_embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") |
|
llm = ChatGoogleGenerativeAI(model="gemini-2.5-pro",google_api_key = GOOGLE_API_KEY) |
|
|
|
|
|
def get_tradingview_analysis(symbol, exchange, screener, interval): |
|
try: |
|
stock = TA_Handler( |
|
symbol=symbol, |
|
screener=screener, |
|
exchange=exchange, |
|
interval=interval, |
|
) |
|
analysis_summary = stock.get_analysis() |
|
return analysis_summary |
|
except Exception as e: |
|
return {"error": str(e)} |
|
|
|
|
|
if ticker_user!="": |
|
url1 = f"https://www.google.com/finance/quote/{ticker_user}:NSE?hl=en" |
|
url2 = f"https://in.tradingview.com/symbols/NSE-{ticker_user}/" |
|
url3 = f"https://in.tradingview.com/symbols/NSE-{ticker_user}/news/" |
|
url4 = f"https://in.tradingview.com/symbols/NSE-{ticker_user}/minds/" |
|
|
|
loader = WebBaseLoader([url1,url2,url3,url4]) |
|
docs = loader.load() |
|
|
|
|
|
st.divider() |
|
|
|
|
|
|
|
|
|
llm_prompt_template = """You are an expert Stock Market Trader specializing in stock market insights derived from fundamental analysis, analytical trends, profit-based evaluations, and detailed company financials. Using your expertise, please analyze the stock based on the provided context below. |
|
|
|
Context: |
|
{input_documents} |
|
|
|
Task: |
|
Summarize the stock based on its historical and current data. |
|
Evaluate the stock on the following parameters: |
|
1. Company Fundamentals: Assess the stock's intrinsic value, growth potential, and financial health. |
|
2. Current & Future Price Trends: Analyze historical price movements and current price trends. |
|
3. News and Sentiment: Review recent news articles, press releases, and social media sentiment. |
|
4. Red Flags: Identify any potential risks or warning signs. |
|
5. Provide a rating for the stock on a scale of 1 to 10. |
|
6. Advise if the stock is a good buy for the next 1,5, 10 weeks. |
|
7. Suggest at what price we need to buy and hold or sell the stock |
|
|
|
PROVIDE THE DETAILS based on just the FACTS present in the document |
|
PROVIDE THE DETAILS IN an JSON Object. Stick to the below JSON object |
|
{{ |
|
"stock_summary": {{ |
|
"company_name": "", |
|
"ticker": "", |
|
"exchange": "", |
|
"description": "", |
|
"current_price": "", |
|
"market_cap": "", |
|
"historical_performance": {{ |
|
"5_day": "", |
|
"1_month": "", |
|
"6_months": "", |
|
"1_year": "", |
|
"5_years": "" |
|
}} |
|
}}, |
|
"evaluation_parameters": {{ |
|
"company_fundamentals": {{ |
|
"assessment": "", |
|
"key_metrics": {{ |
|
"pe_ratio": "", |
|
"volume":"", |
|
"revenue_growth_yoy": "", |
|
"net_income_growth_yoy": "", |
|
"eps_growth_yoy": "", |
|
"dividend_yield": "", |
|
"balance_sheet": "", |
|
"return_on_capital": "" |
|
}} |
|
}}, |
|
"current_and_future_price_trends": {{ |
|
"assessment": "", |
|
"historical_trends": "", |
|
"current_trends": "", |
|
"technical_analysis_notes": "", |
|
"technical_indicators":"" |
|
}}, |
|
"news_and_sentiment": {{ |
|
"assessment": "", |
|
"positive_sentiment": [ |
|
"", |
|
"", |
|
"" |
|
], |
|
"negative_sentiment": [ |
|
"", |
|
"", |
|
"" |
|
] |
|
}}, |
|
"red_flags": [ |
|
{{ |
|
"flag": "", |
|
"details": "" |
|
}}, |
|
{{ |
|
"flag": "", |
|
"details": "" |
|
}}, |
|
{{ |
|
"flag": "", |
|
"details": "" |
|
}} |
|
] |
|
}}, |
|
"overall_rating": {{ |
|
"rating": "X/10", |
|
"justification": "" |
|
}}, |
|
"investment_advice": {{ |
|
"next_1_weeks_outlook": "", |
|
"next_5_weeks_outlook": "", |
|
"next_10_weeks_outlook": "", |
|
"price_action_suggestions": {{ |
|
"buy": "", |
|
"hold": "", |
|
"sell": "" |
|
}} |
|
}} |
|
}} |
|
""" |
|
|
|
|
|
|
|
|
|
interval = Interval.INTERVAL_1_DAY |
|
analysis_summary = get_tradingview_analysis( |
|
symbol=ticker_user, |
|
exchange="NSE", |
|
screener="india", |
|
interval=interval, |
|
) |
|
|
|
|
|
|
|
|
|
|
|
details = { |
|
"symbol": ticker_user, |
|
"exchange": "NSE", |
|
"screener": "india", |
|
"interval": interval, |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.title(f"π TradingView Analysis: {ticker_user} ({details['exchange']})") |
|
|
|
|
|
col1, col2 = st.columns([1, 3]) |
|
with col1: |
|
st.subheader("βΉοΈ Details") |
|
st.table(details) |
|
|
|
with col2: |
|
st.subheader("π Summary") |
|
|
|
chart = alt.Chart(analysis_summary.summary).mark_bar().encode( |
|
x=alt.X('RECOMMENDATION', sort=['BUY', 'NEUTRAL', 'SELL']), |
|
y='Count', |
|
color='RECOMMENDATION' |
|
).properties( |
|
width=400, |
|
height=300, |
|
title="Recommendation Counts" |
|
) |
|
|
|
st.altair_chart(chart, use_container_width=True) |
|
st.dataframe(analysis_summary.summary, use_container_width=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
url = "https://api.chart-img.com/v2/tradingview/advanced-chart" |
|
api_key = "l0iUFRSeqC9z7nDPTd1hnafPh2RrdcEy6rl6tNqV" |
|
headers = { |
|
"x-api-key": api_key, |
|
"content-type": "application/json" |
|
} |
|
data = { |
|
"height": 400, |
|
"theme": "light", |
|
"interval": "1D", |
|
"session": "extended", |
|
"symbol": f"NSE:{ticker_user}" |
|
} |
|
|
|
response = requests.post(url, headers=headers, json=data) |
|
|
|
if response.status_code == 200: |
|
with open("chart_t1.jpg", "wb") as f: |
|
f.write(response.content) |
|
|
|
st.image("chart_t1.jpg", caption='') |
|
|
|
llm_prompt = PromptTemplate.from_template(llm_prompt_template) |
|
|
|
llm_chain = LLMChain(llm=llm,prompt=llm_prompt) |
|
stuff_chain = StuffDocumentsChain(llm_chain=llm_chain,document_variable_name="input_documents") |
|
|
|
|
|
res = stuff_chain.invoke({"input_documents": docs}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data = json.loads(res["output_text"]) |
|
|
|
st.markdown(f"### {data['stock_summary']['company_name']} ({data['stock_summary']['ticker']}) | {data['stock_summary']['exchange']}") |
|
st.markdown(f"**Description**: {data['stock_summary']['description']}") |
|
|
|
|
|
row1 = st.columns(3) |
|
row1[0].metric("π° Current Price", data["stock_summary"]["current_price"]) |
|
row1[1].metric("π’ Market Cap", data["stock_summary"]["market_cap"]) |
|
row1[2].metric("β Rating", data["overall_rating"]["rating"]) |
|
|
|
|
|
st.subheader("π Historical Performance") |
|
perf_cols = st.columns(len(data["stock_summary"]["historical_performance"])) |
|
for i, (k, v) in enumerate(data["stock_summary"]["historical_performance"].items()): |
|
perf_cols[i].metric(k.replace("_", " ").title(), v) |
|
|
|
|
|
st.subheader("π Company Fundamentals") |
|
row3 = st.columns(4) |
|
metrics = data["evaluation_parameters"]["company_fundamentals"]["key_metrics"] |
|
row3[0].metric("P/E Ratio", metrics["pe_ratio"]) |
|
row3[1].metric("EPS YoY", metrics["eps_growth_yoy"]) |
|
row3[2].metric("Revenue YoY", metrics["revenue_growth_yoy"]) |
|
row3[3].metric("Dividend Yield", metrics["dividend_yield"]) |
|
|
|
row3b = st.columns(4) |
|
row3b[0].metric("Net Income YoY", metrics["net_income_growth_yoy"]) |
|
row3b[1].metric("Volume", metrics["volume"]) |
|
row3b[2].metric("Return on Capital", metrics["return_on_capital"]) |
|
row3b[3].metric("Balance Sheet", metrics["balance_sheet"]) |
|
|
|
st.info(data["evaluation_parameters"]["company_fundamentals"]["assessment"]) |
|
|
|
|
|
st.subheader("π Trends & Technical Analysis") |
|
row4 = st.columns(3) |
|
row4[0].markdown(f"**Historical Trends:** {data['evaluation_parameters']['current_and_future_price_trends']['historical_trends']}") |
|
row4[1].markdown(f"**Current Trends:** {data['evaluation_parameters']['current_and_future_price_trends']['current_trends']}") |
|
row4[2].markdown(f"**Technical Indicators:** {data['evaluation_parameters']['current_and_future_price_trends']['technical_indicators']}") |
|
|
|
st.success(data["evaluation_parameters"]["current_and_future_price_trends"]["assessment"]) |
|
st.caption(f"π Notes: {data['evaluation_parameters']['current_and_future_price_trends']['technical_analysis_notes']}") |
|
|
|
|
|
st.subheader("π° News & Sentiment") |
|
sentiment_cols = st.columns(2) |
|
with sentiment_cols[0]: |
|
st.success("π Positive Sentiment") |
|
for s in data["evaluation_parameters"]["news_and_sentiment"]["positive_sentiment"]: |
|
st.write(f"β
{s}") |
|
with sentiment_cols[1]: |
|
st.error("π Negative Sentiment") |
|
for s in data["evaluation_parameters"]["news_and_sentiment"]["negative_sentiment"]: |
|
st.write(f"β {s}") |
|
st.info(data["evaluation_parameters"]["news_and_sentiment"]["assessment"]) |
|
|
|
|
|
st.subheader("π© Red Flags") |
|
red_flag_cols = st.columns(3) |
|
for i, flag in enumerate(data["evaluation_parameters"]["red_flags"]): |
|
red_flag_cols[i].warning(f"**{flag['flag']}**\n{flag['details']}") |
|
|
|
|
|
st.subheader("π‘ Investment Advice") |
|
advice_cols = st.columns(3) |
|
advice = data["investment_advice"] |
|
advice_cols[0].markdown(f"**Next 1 Week**\n{advice['next_1_weeks_outlook']}") |
|
advice_cols[1].markdown(f"**Next 5 Weeks**\n{advice['next_5_weeks_outlook']}") |
|
advice_cols[2].markdown(f"**Next 10 Weeks**\n{advice['next_10_weeks_outlook']}") |
|
|
|
action_cols = st.columns(3) |
|
action_cols[0].success(f"**Buy:** {advice['price_action_suggestions']['buy']}") |
|
action_cols[1].info(f"**Hold:** {advice['price_action_suggestions']['hold']}") |
|
action_cols[2].error(f"**Sell:** {advice['price_action_suggestions']['sell']}") |
|
|
|
|
|
st.markdown("---") |
|
st.caption("Generated by AI-powered financial analysis dashboard.") |
|
else: |
|
st.warning(f"Failed to retrieve image. Status code: {response.status_code}") |
|
st.warning("Response:", response.text) |
|
|