This commit is contained in:
aaron 2025-09-19 08:53:03 +08:00
parent 5513d22655
commit 9236b54c87
7 changed files with 91 additions and 38 deletions

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
"""
启动A股量化交易系统Web界面
启动AI 智能选股大师Web界面
"""
import sys
@ -11,7 +11,7 @@ import time
def main():
"""启动Web服务"""
print("🌐 A股量化交易系统")
print("🌐 AI 智能选股大师")
print("=" * 50)
# 检查web目录

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
"""
A股量化交易系统 Web 展示界面
AI 智能选股大师 Web 展示界面
使用Flask框架展示策略筛选结果
"""

View File

@ -1,4 +1,4 @@
/* A股量化交易系统 - 简洁清爽浅色调设计 */
/* AI 智能选股大师 - 简洁清爽浅色调设计 */
/* ========== 全局样式 ========== */
:root {
@ -177,12 +177,12 @@ body {
.table {
margin-bottom: 0;
font-size: 0.875rem;
border-collapse: collapse;
}
.table thead th {
background: linear-gradient(135deg, var(--bg-tertiary) 0%, var(--bg-secondary) 100%);
border-bottom: 2px solid var(--border-color);
border-top: none;
border: none !important;
font-weight: 600;
font-size: 0.75rem;
text-transform: uppercase;
@ -192,23 +192,29 @@ body {
}
.table tbody tr {
border-bottom: 1px solid var(--border-light);
border: none !important;
transition: all 0.2s ease;
}
.table tbody td {
border: none !important;
padding: 0.875rem 0.75rem;
vertical-align: middle;
color: var(--text-primary);
}
.table th,
.table td {
border-top: none !important;
border-bottom: none !important;
border-left: none !important;
border-right: none !important;
}
.table tbody tr:hover {
background-color: var(--bg-secondary);
}
.table tbody tr:last-child {
border-bottom: none;
}
.table tbody td {
padding: 0.875rem 0.75rem;
vertical-align: middle;
color: var(--text-primary);
}
.table-active {
background-color: var(--primary-lighter) !important;
@ -517,6 +523,49 @@ footer .text-muted {
transform: translateY(-2px);
}
/* ========== 股票信息样式 ========== */
.stock-code-link {
text-decoration: none;
transition: all 0.2s ease;
}
.stock-code-link:hover {
transform: translateY(-1px);
filter: drop-shadow(0 2px 4px rgba(37, 99, 235, 0.2));
}
.stock-code-badge {
font-size: 0.75rem;
font-weight: 600;
color: var(--primary-color);
background: linear-gradient(135deg, var(--primary-lighter) 0%, rgba(37, 99, 235, 0.1) 100%);
padding: 0.25rem 0.5rem;
border-radius: var(--radius-sm);
border: 1px solid rgba(37, 99, 235, 0.2);
display: inline-block;
letter-spacing: 0.02em;
font-family: 'JetBrains Mono', 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', monospace;
cursor: pointer;
transition: all 0.2s ease;
}
.stock-code-link:hover .stock-code-badge {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-light) 100%);
color: white;
border-color: var(--primary-color);
}
.stock-name {
font-size: 0.8rem;
font-weight: 400;
line-height: 1.2;
max-width: 100px;
color: var(--text-secondary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* ========== 滚动条美化 ========== */
::-webkit-scrollbar {
width: 6px;

View File

@ -1,5 +1,5 @@
/**
* A股量化交易系统 主要JavaScript功能
* AI 智能选股大师 主要JavaScript功能
*/
$(document).ready(function() {

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}A股量化交易系统{% endblock %}</title>
<title>{% block title %}AI 智能选股大师{% endblock %}</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
@ -19,7 +19,7 @@
<nav class="navbar navbar-expand-lg">
<div class="container">
<a class="navbar-brand" href="{{ url_for('signals') }}">
<i class="fas fa-chart-line me-2"></i>A股量化交易系统
<i class="fas fa-robot me-2"></i>AI 智能选股大师
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
@ -56,7 +56,7 @@
<footer class="mt-5 py-4">
<div class="container text-center">
<p class="text-muted mb-0">
<i class="fas fa-robot me-1"></i>A股量化交易系统 |
<i class="fas fa-robot me-1"></i>AI 智能选股大师 |
<i class="fas fa-code me-1"></i>基于Python + Flask + SQLite
</p>
</div>

View File

@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block title %}回踩监控 - A股量化交易系统{% endblock %}
{% block title %}回踩监控 - AI 智能选股大师{% endblock %}
{% block content %}
<!-- 页面标题和筛选 -->
@ -89,13 +89,15 @@
<tr>
<td>
<div class="d-flex align-items-center">
<span class="badge badge-light-primary me-2">{{ alert.stock_code }}</span>
<span class="fw-bold text-truncate" style="max-width: 80px;">{{ alert.stock_name or '未知' }}</span>
<a href="https://xueqiu.com/S/{% if alert.stock_code.endswith('.SZ') %}SZ{% elif alert.stock_code.endswith('.SH') %}SH{% elif alert.stock_code.startswith('0') or alert.stock_code.startswith('3') %}SZ{% else %}SH{% endif %}{{ alert.stock_code.split('.')[0] }}" target="_blank" class="stock-code-link me-2">
<div class="stock-code-badge">{{ alert.stock_code }}</div>
</a>
<div class="stock-name text-truncate">{{ alert.stock_name or '未知' }}</div>
</div>
</td>
<td>
<span class="badge bg-{% if alert.timeframe == 'daily' %}primary{% elif alert.timeframe == '1h' %}info{% else %}success{% endif %}">
{{ 'D' if alert.timeframe == 'daily' else ('1H' if alert.timeframe == '1h' else 'W') }}
{{ '日线' if alert.timeframe == 'daily' else ('1小时' if alert.timeframe == '1h' else '周线') }}
</span>
</td>
<td class="text-muted">{{ alert.original_signal_date | datetime_format('%Y-%m-%d') }}</td>

View File

@ -1,19 +1,12 @@
{% extends "base.html" %}
{% block title %}交易信号 - A股量化交易系统{% endblock %}
{% block title %}交易信号 - AI 智能选股大师{% endblock %}
{% block content %}
<!-- 页面标题和筛选 -->
<div class="row mb-4">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center">
<div>
<h1 class="h3 mb-1 text-primary fw-bold">
<i class="fas fa-signal me-2"></i>交易信号列表
</h1>
<p class="text-muted mb-0">详细的股票筛选信号数据</p>
</div>
<div class="d-flex justify-content-end align-items-center">
<!-- 筛选表单 -->
<form method="GET" class="d-flex gap-2 align-items-center">
<select name="strategy" class="form-select form-select-sm">
@ -23,7 +16,7 @@
<select name="timeframe" class="form-select form-select-sm">
<option value="">所有周期</option>
<option value="daily" {% if timeframe == 'daily' %}selected{% endif %}>日线</option>
<option value="daily" {% if timeframe == 'daily' or not timeframe %}selected{% endif %}>日线</option>
<option value="weekly" {% if timeframe == 'weekly' %}selected{% endif %}>周线</option>
<option value="1h" {% if timeframe == '1h' %}selected{% endif %}>1小时</option>
</select>
@ -64,7 +57,7 @@
<div class="table-container">
{% for scan_date, signals in signals_grouped.items() %}
<!-- 扫描日期分组标题 -->
<div class="scan-date-header bg-light px-3 py-2 border-bottom">
<div class="scan-date-header bg-light px-3 py-2">
<h6 class="mb-0 text-primary fw-bold">
<i class="fas fa-calendar-day me-2"></i>扫描日期: {{ scan_date }}
<span class="badge bg-primary ms-2">{{ signals|length }} 条信号</span>
@ -93,8 +86,10 @@
<tr>
<td>
<div class="d-flex align-items-center">
<span class="badge badge-light-primary me-2">{{ signal.stock_code }}</span>
<span class="fw-bold text-truncate" style="max-width: 80px;">{{ signal.stock_name or '未知' }}</span>
<a href="https://xueqiu.com/S/{% if signal.stock_code.endswith('.SZ') %}SZ{% elif signal.stock_code.endswith('.SH') %}SH{% elif signal.stock_code.startswith('0') or signal.stock_code.startswith('3') %}SZ{% else %}SH{% endif %}{{ signal.stock_code.split('.')[0] }}" target="_blank" class="stock-code-link me-2">
<div class="stock-code-badge">{{ signal.stock_code }}</div>
</a>
<div class="stock-name text-truncate">{{ signal.stock_name or '未知' }}</div>
</div>
</td>
<td>
@ -102,7 +97,7 @@
</td>
<td>
<span class="badge bg-{% if signal.timeframe == 'daily' %}primary{% elif signal.timeframe == '1h' %}info{% else %}success{% endif %}">
{{ 'D' if signal.timeframe == 'daily' else ('1H' if signal.timeframe == '1h' else 'W') }}
{{ '日线' if signal.timeframe == 'daily' else ('1小时' if signal.timeframe == '1h' else '周线') }}
</span>
</td>
<td class="text-muted">{{ signal.signal_date | datetime_format('%Y-%m-%d') }}</td>
@ -196,6 +191,13 @@
// 工具提示
$('[data-bs-toggle="tooltip"]').tooltip();
// 如果没有timeframe参数自动设置为daily并重新加载
const urlParams = new URLSearchParams(window.location.search);
if (!urlParams.has('timeframe')) {
urlParams.set('timeframe', 'daily');
window.location.search = urlParams.toString();
}
});
</script>
{% endblock %}