vsa / vn-stock-analysis-app /templates /stock_analysis.html
danghungithp's picture
Upload 1398 files
bec48e1 verified
{% extends "base.html" %}
{% block title %}
Phân tích {{ symbol if symbol else 'Cổ phiếu' }} - Dữ liệu và Biểu đồ
{% endblock %}
{% block og_title %}Phân tích {{ symbol if symbol else 'Cổ phiếu' }} - Dữ liệu và Biểu đồ{% endblock %}
{% block twitter_title %}Phân tích {{ symbol if symbol else 'Cổ phiếu' }} - Dữ liệu và Biểu đồ{% endblock %}
{% block head %}
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
<style>
.stock-header {
background-color: #fff;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
text-align: center;
}
.stock-header form {
display: flex;
justify-content: center;
gap: 10px;
margin-top: 15px;
}
.stock-header input[type="text"] {
width: 300px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
.stock-header button {
padding: 10px 20px;
background-color: #003366;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.tabs {
display: flex;
border-bottom: 2px solid #dee2e6;
margin-bottom: 20px;
}
.tab-link {
padding: 10px 20px;
cursor: pointer;
border: none;
background: none;
font-size: 16px;
border-bottom: 2px solid transparent;
margin-bottom: -2px;
}
.tab-link.active {
border-color: #003366;
font-weight: bold;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
#stockChartContainer {
position: relative;
height: 60vh;
width: 100%;
background: #fff;
padding: 15px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}
.info-card {
background: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
margin-bottom: 20px;
}
.financial-tables .table-responsive {
max-height: 400px;
overflow-y: auto;
}
.ai-analysis {
margin-top: 20px;
padding: 15px;
background-color: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
}
.ai-analysis h4 {
margin-top: 0;
margin-bottom: 10px;
}
</style>
{% endblock %}
{% block header_title %}
Phân tích Cổ phiếu - {{ symbol if symbol else 'Nhập mã để bắt đầu' }}
{% endblock %}
{% block content %}
<div id="stock-symbol-data" data-symbol="{{ symbol or '' }}"></div>
<div class="stock-header">
<form method="get" action="{{ url_for('stock_analysis') }}">
<input type="text" name="symbol" placeholder="Nhập mã cổ phiếu (VD: FPT, ACB...)" value="{{ symbol or '' }}" required>
<button type="submit">Phân tích</button>
</form>
{% if error %}
<div class="alert alert-danger mt-3">{{ error }}</div>
{% endif %}
</div>
{% if symbol %}
<div class="tabs">
<button class="tab-link active" data-tab="tab-chart">Biểu đồ kỹ thuật</button>
<button class="tab-link" data-tab="tab-financials">Dữ liệu tài chính</button>
<button class="tab-link" data-tab="tab-valuation">Phân tích & Định giá</button>
</div>
<div id="tab-chart" class="tab-content active">
<div class="chart-container" style="height: 60vh;">
<canvas id="stockMainChart"></canvas>
</div>
<div class="chart-grid">
<div class="chart-item"><canvas id="priceChart"></canvas></div>
<div class="chart-item"><canvas id="volumeChart"></canvas></div>
<div class="chart-item"><canvas id="pvChart"></canvas>
<p><b>Price Volume (PV)</b>: Tích số giá và khối lượng. Đường ngang ở mức 0 là ngưỡng trung bình. PV trên 0 cho thấy dòng tiền vào, dưới 0 cho thấy dòng tiền ra.</p>
</div>
<div class="chart-item"><canvas id="mfiChart"></canvas>
<p><b>Money Flow Index (MFI)</b>: Chỉ số dòng tiền. Đường ngang ở mức 50 là ngưỡng trung bình. MFI trên 50 cho thấy áp lực mua, dưới 50 cho thấy áp lực bán.</p>
</div>
</div>
</div>
<div id="tab-financials" class="tab-content financial-tables">
<div class="info-card">
<h3>
Bảng dữ liệu tài chính
<button type="button" id="reload-financial-data-btn" class="btn btn-sm btn-primary" style="margin-left: 20px;">
Tải dữ liệu mới
<span id="financial-loading-spinner" class="spinner" style="display:none; margin-left: 5px;"></span>
</button>
</h3>
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item"><a class="nav-link active" data-bs-toggle="tab" href="#bs-data">Bảng CĐKT</a></li>
<li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#is-data">Kết quả KD</a></li>
<li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#cf-data">Lưu chuyển tiền tệ</a></li>
<li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#ratio-data">Chỉ số TC</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div id="bs-data" class="container tab-pane active"><br>
<h4>Bảng CĐKT (Năm)</h4>
<table id="bs_year_table" class="display" style="width:100%">{{ tables['bs_year']|safe }}</table>
<div class="ai-analysis">
<h4>Phân tích AI (Năm)</h4>
<p id="bs_year_ai_analysis">Phân tích AI sẽ hiển thị ở đây.</p>
<button class="btn btn-primary" onclick="getAiAnalysis('bs_year')">Phân tích</button>
</div>
<h4>Bảng CĐKT (Quý)</h4>
<table id="bs_quarter_table" class="display" style="width:100%">{{ tables['bs_quarter']|safe }}</table>
<div class="ai-analysis">
<h4>Phân tích AI (Quý)</h4>
<p id="bs_quarter_ai_analysis">Phân tích AI sẽ hiển thị ở đây.</p>
<button class="btn btn-primary" onclick="getAiAnalysis('bs_quarter')">Phân tích</button>
</div>
</div>
<div id="is-data" class="container tab-pane fade"><br>
<h4>Kết quả KD (Năm)</h4>
<table id="is_year_table" class="display" style="width:100%">{{ tables['is_year']|safe }}</table>
<div class="ai-analysis">
<h4>Phân tích AI (Năm)</h4>
<p id="is_year_ai_analysis">Phân tích AI sẽ hiển thị ở đây.</p>
<button class="btn btn-primary" onclick="getAiAnalysis('is_year')">Phân tích</button>
</div>
<h4>Kết quả KD (Quý)</h4>
<table id="is_quarter_table" class="display" style="width:100%">{{ tables['is_quarter']|safe }}</table>
<div class="ai-analysis">
<h4>Phân tích AI (Quý)</h4>
<p id="is_quarter_ai_analysis">Phân tích AI sẽ hiển thị ở đây.</p>
<button class="btn btn-primary" onclick="getAiAnalysis('is_quarter')">Phân tích</button>
</div>
</div>
<div id="cf-data" class="container tab-pane fade"><br>
<h4>Lưu chuyển tiền tệ (Năm)</h4>
<table id="cf_year_table" class="display" style="width:100%">{{ tables['cf_year']|safe }}</table>
<div class="ai-analysis">
<h4>Phân tích AI (Năm)</h4>
<p id="cf_year_ai_analysis">Phân tích AI sẽ hiển thị ở đây.</p>
<button class="btn btn-primary" onclick="getAiAnalysis('cf_year')">Phân tích</button>
</div>
</div>
<div id="ratio-data" class="container tab-pane fade"><br>
<h4>Chỉ số TC (Năm)</h4>
<table id="ratio_year_table" class="display" style="width:100%">{{ tables['ratio_year']|safe }}</table>
<div class="ai-analysis">
<h4>Phân tích AI (Năm)</h4>
<p id="ratio_year_ai_analysis">Phân tích AI sẽ hiển thị ở đây.</p>
<button class="btn btn-primary" onclick="getAiAnalysis('ratio_year')">Phân tích</button>
</div>
<h4>Chỉ số TC (Quý)</h4>
<table id="ratio_quarter_table" class="display" style="width:100%">{{ tables['ratio_quarter']|safe }}</table>
<div class="ai-analysis">
<h4>Phân tích AI (Quý)</h4>
<p id="ratio_quarter_ai_analysis">Phân tích AI sẽ hiển thị ở đây.</p>
<button class="btn btn-primary" onclick="getAiAnalysis('ratio_quarter')">Phân tích</button>
</div>
</div>
</div>
</div>
</div>
<div id="tab-valuation" class="tab-content">
<div class="info-card">
<h3>Phân tích tự động với Groq AI</h3>
<form id="groq-form">
<input type="hidden" name="symbol" value="{{ symbol }}">
<input type="text" name="question" placeholder="Nhập câu hỏi về dữ liệu tài chính (tùy chọn)" class="form-control mb-2">
<button type="submit" class="btn btn-info">Phân tích với AI <span class="spinner" style="display:none;"></span></button>
</form>
<div id="groq-result" class="alert alert-info mt-3" style="white-space: pre-wrap;">Kết quả phân tích sẽ hiển thị ở đây.</div>
</div>
</div>
{% else %}
<div class="info-card" style="text-align: center;">
<h4>Chào mừng đến với công cụ Phân tích Cổ phiếu</h4>
<p>Vui lòng nhập một mã cổ phiếu vào ô ở trên để bắt đầu xem biểu đồ, dữ liệu tài chính và các phân tích chuyên sâu.</p>
</div>
{% endif %}
{% endblock %}
{% block scripts %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-chart-financial"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation"></script>
<script type="module" src="{{ url_for('static', filename='js/stock_analysis.js') }}"></script>
<script>
$(document).ready( function () {
$('a[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) {
if (e.target.getAttribute('href') == '#bs-data') {
$('#bs_year_table').DataTable();
$('#bs_quarter_table').DataTable();
}
if (e.target.getAttribute('href') == '#is-data') {
$('#is_year_table').DataTable();
$('#is_quarter_table').DataTable();
}
if (e.target.getAttribute('href') == '#cf-data') {
$('#cf_year_table').DataTable();
}
if (e.target.getAttribute('href') == '#ratio-data') {
$('#ratio_year_table').DataTable();
$('#ratio_quarter_table').DataTable();
}
});
} );
function getAiAnalysis(tableId) {
var symbol = $('#stock-symbol-data').data('symbol');
$.ajax({
url: '/api/stock_valuation_groq?symbol=' + symbol,
type: 'GET',
success: function(response) {
if (response.groq_valuation) {
$('#' + tableId + '_ai_analysis').text(response.groq_valuation);
} else if (response.error) {
$('#' + tableId + '_ai_analysis').text('Error: ' + response.error);
} else {
$('#' + tableId + '_ai_analysis').text('No analysis available.');
}
},
error: function(error) {
$('#' + tableId + '_ai_analysis').text('Error fetching analysis.');
}
});
}
</script>
{% endblock %}