stockvninsight / app.py
NguyNhu's picture
Update app.py
47e7e88 verified
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
import streamlit as st
import pandas as pd
import numpy as np
import plotly.graph_objs as go
from vnstock import Vnstock, Listing
st.set_page_config(page_title="Vietnam Stock Market Insight", layout="wide")
st.title("📈 Vietnam Stock Market Insight")
symbol = st.text_input("Nhập mã cổ phiếu (ví dụ: VNM, FPT, VCB):", value="GMD")
col1, col2 = st.columns(2)
with col1:
start_date = st.date_input("Ngày bắt đầu", pd.to_datetime("2025-01-01"))
with col2:
end_date = st.date_input("Ngày kết thúc", pd.to_datetime("2025-12-31"))
tab1, tab2, tab3 = st.tabs([
"📉 Phân tích kỹ thuật",
"📊 Phân tích cơ bản",
"🏢 Thông tin doanh nghiệp"
])
# TAB 1 - Phân tích kỹ thuật
with tab1:
if st.button("Phân tích kỹ thuật"):
with st.spinner("Đang tải dữ liệu..."):
try:
stock = Vnstock().stock(symbol=symbol, source='VCI')
df = stock.quote.history(
start=start_date.strftime("%Y-%m-%d"),
end=end_date.strftime("%Y-%m-%d"),
interval='1D'
)
df['date'] = pd.to_datetime(df['time'])
df.set_index('date', inplace=True)
df.sort_index(inplace=True)
df['EMA12'] = df['close'].ewm(span=12, adjust=False).mean()
df['EMA26'] = df['close'].ewm(span=26, adjust=False).mean()
df['MACD'] = df['EMA12'] - df['EMA26']
df['MACD_Signal'] = df['MACD'].ewm(span=9, adjust=False).mean()
df['BB_Middle'] = df['close'].rolling(window=20).mean()
df['BB_Std'] = df['close'].rolling(window=20).std()
df['BB_Upper'] = df['BB_Middle'] + (2 * df['BB_Std'])
df['BB_Lower'] = df['BB_Middle'] - (2 * df['BB_Std'])
delta = df['close'].diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.rolling(window=14).mean()
avg_loss = loss.rolling(window=14).mean()
rs = avg_gain / avg_loss
df['RSI'] = 100 - (100 / (1 + rs))
st.subheader("📊 Dữ liệu giá cổ phiếu")
st.dataframe(df[['open', 'high', 'low', 'close', 'volume']].dropna().tail(10))
st.subheader("📈 Bollinger Bands")
fig_bb = go.Figure()
fig_bb.add_trace(go.Scatter(x=df.index, y=df['close'], name='Close'))
fig_bb.add_trace(go.Scatter(x=df.index, y=df['BB_Upper'], name='Upper Band'))
fig_bb.add_trace(go.Scatter(x=df.index, y=df['BB_Lower'], name='Lower Band'))
st.plotly_chart(fig_bb, use_container_width=True)
st.subheader("📉 RSI")
fig_rsi = go.Figure()
fig_rsi.add_trace(go.Scatter(x=df.index, y=df['RSI'], name='RSI'))
fig_rsi.update_layout(yaxis=dict(range=[0, 100]))
st.plotly_chart(fig_rsi, use_container_width=True)
st.subheader("📉 MACD")
fig_macd = go.Figure()
fig_macd.add_trace(go.Scatter(x=df.index, y=df['MACD'], name='MACD'))
fig_macd.add_trace(go.Scatter(x=df.index, y=df['MACD_Signal'], name='Signal'))
st.plotly_chart(fig_macd, use_container_width=True)
except Exception as e:
st.error(f"❌ Lỗi kỹ thuật: {e}")
# TAB 2 - Phân tích cơ bản
with tab2:
if st.button("Phân tích cơ bản"):
with st.spinner("Đang tải báo cáo tài chính..."):
try:
stock = Vnstock().stock(symbol=symbol, source='VCI')
df_financial = stock.finance.income_statement(period='quarter', lang='vi', dropna=True)
st.subheader("📊 Báo cáo tài chính quý")
st.dataframe(df_financial)
except Exception as e:
st.error(f"❌ Lỗi dữ liệu tài chính: {e}")
# TAB 3 - Thông tin doanh nghiệp đầy đủ
with tab3:
try:
stock = Vnstock().stock(symbol=symbol, source='VCI')
st.subheader(f"🏢 Tổng quan công ty: {symbol}")
st.dataframe(stock.company.overview())
st.subheader("💰 Bảng cân đối kế toán")
st.dataframe(stock.finance.balance_sheet())
st.subheader("💸 Báo cáo lưu chuyển tiền tệ")
st.dataframe(stock.finance.cash_flow())
st.subheader("👥 Cổ đông lớn")
st.dataframe(stock.company.shareholders())
st.subheader("🧑‍💼 Ban lãnh đạo (đang làm việc)")
st.dataframe(stock.company.officers(filter_by="working"))
st.subheader("📎 Tài liệu công bố")
st.dataframe(stock.company.documents())
st.subheader("📋 Danh sách công ty niêm yết")
listing = Listing()
df_listing = listing.all_symbols()
st.dataframe(df_listing)
except Exception as e:
st.error(f"❌ Lỗi khi lấy thông tin doanh nghiệp: {e}")