Spaces:
Runtime error
Runtime error
from flask import Blueprint, render_template, request | |
import os | |
import pandas as pd | |
from datetime import datetime | |
from modules.utils import plot_candlestick_with_fibo_patterns, detect_candlestick_patterns, calculate_fibonacci_levels, calculate_money_flow, find_double_top_bottom, detect_w_double_bottom, detect_m_double_top, detect_cup_and_handle, get_financial_valuation, DATA_DIR | |
from vnstock import Vnstock | |
def load_financial_table(csv_path, symbol, period=None): | |
header_row = 1 if 'ratio' in csv_path.lower() else 0 | |
if not os.path.exists(csv_path): | |
return None | |
try: | |
df = pd.read_csv(csv_path, header=header_row) | |
df.columns = [str(col).strip().lower().replace(' ', '').replace('_', '') for col in df.columns] | |
symbol_col = None | |
for col in ['ticker', 'cp', 'mã', 'stock']: | |
if col in df.columns: | |
symbol_col = col | |
break | |
year_col = None | |
for col in ['yearreport', 'năm', 'year', 'nam']: | |
if col in df.columns: | |
year_col = col | |
break | |
if symbol_col is None or year_col is None: | |
return None | |
df[symbol_col] = df[symbol_col].astype(str).str.upper().str.strip() | |
df = df[df[symbol_col] == symbol.upper()] | |
if df.empty: | |
return None | |
return df | |
except Exception: | |
return None | |
def df_to_html(df, max_cols=12): | |
if df is None or (hasattr(df, 'empty') and df.empty): | |
return '<span style="color:#888">Chưa có dữ liệu tài chính. Hãy bấm <b>Tải dữ liệu mới</b> để lấy dữ liệu!</span>' | |
if len(df) == 1 and df.isnull().all(axis=None): | |
return '<span style="color:#888">Chưa có dữ liệu tài chính. Hãy bấm <b>Tải dữ liệu mới</b> để lấy dữ liệu!</span>' | |
if len(df.columns) > max_cols: | |
df = df.iloc[:, :max_cols] | |
return df.to_html(classes='table table-sm table-bordered', index=False, border=0, justify='center') | |
vsa_bp = Blueprint('vsa', __name__) | |
def vsa_index(): | |
symbol = request.args.get('symbol', 'VNINDEX').strip().upper() | |
start = request.args.get('start', '2024-01-01') | |
end = request.args.get('end', datetime.now().strftime('%Y-%m-%d')) | |
try: | |
stock = Vnstock().stock(symbol=symbol) | |
df = stock.quote.history(start=start, end=end, interval='1D') | |
if df is None or df.empty: | |
return render_template('vsa.html', symbol=symbol, error="Không có dữ liệu cho mã cổ phiếu hoặc khoảng thời gian đã chọn.", chart_path_vsa=None, tables={ | |
'bs_year': '', 'bs_quarter': '', 'is_year': '', 'is_quarter': '', 'cf_year': '', 'ratio_year': '', 'ratio_quarter': '' | |
}) | |
except Exception as e: | |
return render_template('vsa.html', symbol=symbol, error=f"Lỗi khi lấy dữ liệu: {e}", chart_path_vsa=None, tables={ | |
'bs_year': '', 'bs_quarter': '', 'is_year': '', 'is_quarter': '', 'cf_year': '', 'ratio_year': '', 'ratio_quarter': '' | |
}) | |
# Data cleaning | |
for col in ['open', 'high', 'low', 'close', 'volume']: | |
df[col] = pd.to_numeric(df[col], errors='coerce') | |
df.dropna(subset=['open', 'high', 'low', 'close', 'volume'], inplace=True) | |
candlestick_patterns = detect_candlestick_patterns(df) | |
fibonacci_levels = calculate_fibonacci_levels(df) | |
df = calculate_money_flow(df) | |
double_tops, double_bottoms = find_double_top_bottom(df) | |
w_double_bottoms = detect_w_double_bottom(df) | |
m_double_tops = detect_m_double_top(df) | |
CHART_PATH_VSA = "static/images/vnindex_vsa.png" | |
os.makedirs(os.path.dirname(CHART_PATH_VSA), exist_ok=True) | |
plot_candlestick_with_fibo_patterns( | |
df, fibonacci_levels, candlestick_patterns, symbol, chart_path=CHART_PATH_VSA, | |
double_tops=double_tops, double_bottoms=double_bottoms, | |
cup_handle_patterns=None, w_double_bottoms=w_double_bottoms, m_double_tops=m_double_tops | |
) | |
# Bổ sung bảng tài chính | |
bs_year = load_financial_table('DFbalance_sheet_year.csv', symbol, period='year') | |
bs_quarter = load_financial_table('DFbalance_sheet_quarter.csv', symbol, period='quarter') | |
is_year = load_financial_table('DFincome_statement_year.csv', symbol, period='year') | |
is_quarter = load_financial_table('dfincome_statement_quarter.csv', symbol, period='quarter') | |
cf_year = load_financial_table('dfcash_flow_year.csv', symbol, period='year') | |
ratio_year = load_financial_table('dfratio_year.csv', symbol, period='year') | |
ratio_quarter = load_financial_table('dfratio_quarter.csv', symbol, period='quarter') | |
tables = { | |
'bs_year': df_to_html(bs_year), | |
'bs_quarter': df_to_html(bs_quarter), | |
'is_year': df_to_html(is_year), | |
'is_quarter': df_to_html(is_quarter), | |
'cf_year': df_to_html(cf_year), | |
'ratio_year': df_to_html(ratio_year), | |
'ratio_quarter': df_to_html(ratio_quarter), | |
} | |
financial_valuation = get_financial_valuation(stock) | |
return render_template('vsa.html', symbol=symbol, chart_path_vsa=CHART_PATH_VSA, error=None, tables=tables, financial_valuation=financial_valuation) | |