trading.ai/web/templates/index.html
2025-09-23 16:12:18 +08:00

284 lines
15 KiB
HTML

{% extends "base.html" %}
{% block title %}首页 - A股量化交易系统{% 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-chart-line me-2"></i>交易信号概览
</h1>
<p class="text-muted mb-0">实时监控量化策略筛选结果</p>
</div>
<div class="text-end">
<div class="text-muted small">
<i class="fas fa-clock me-1"></i>最后更新
</div>
<div class="fw-bold text-primary">{{ current_time }}</div>
</div>
</div>
</div>
</div>
<!-- 统计卡片 -->
<div class="row mb-2">
{% for stat in strategy_stats %}
<div class="col-lg-3 col-md-6 mb-1">
<div class="stats-card hover-lift fade-in">
<div class="d-flex justify-content-between align-items-start">
<div>
<div class="stats-label text-uppercase mb-1">{{ stat.strategy_name }}</div>
<div class="stats-value">{{ stat.total_signals or 0 }}</div>
<div class="stats-sublabel">
<i class="fas fa-building me-1"></i>{{ stat.unique_stocks or 0 }} 只股票
</div>
</div>
<div class="text-primary" style="opacity: 0.3;">
<i class="fas fa-signal fa-lg"></i>
</div>
</div>
</div>
</div>
{% endfor %}
<!-- 如果没有统计数据,显示默认卡片 -->
{% if not strategy_stats %}
<div class="col-lg-3 col-md-6 mb-1">
<div class="stats-card hover-lift">
<div class="d-flex justify-content-between align-items-start">
<div>
<div class="stats-label text-uppercase mb-1">K线形态策略</div>
<div class="stats-value">0</div>
<div class="stats-sublabel">
<i class="fas fa-building me-1"></i>0 只股票
</div>
</div>
<div class="text-primary" style="opacity: 0.3;">
<i class="fas fa-signal fa-lg"></i>
</div>
</div>
</div>
</div>
{% endif %}
</div>
<!-- 最新信号表格 -->
<div class="row">
<div class="col-12">
<div class="card fade-in">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0 text-primary fw-bold">
<i class="fas fa-list-ul me-2"></i>最新交易信号
</h5>
<a href="{{ url_for('signals') }}" class="btn btn-primary btn-sm">
<i class="fas fa-arrow-right me-1"></i>查看全部
</a>
</div>
<div class="card-body p-0">
{% if signals %}
<div class="table-container">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<tr>
<th>股票</th>
<th>策略</th>
<th>周期</th>
<th>确认信息</th>
<th>价格信息</th>
<th>技术指标</th>
</tr>
</thead>
<tbody>
{% for signal in signals %}
<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>
</div>
</td>
<td>
<span class="badge bg-primary">{{ signal.strategy_name }}</span>
{% if signal.new_high_confirmed %}
<div class="mt-1">
<small class="badge bg-success">已确认</small>
</div>
{% endif %}
</td>
<td>
<span class="badge bg-{% if signal.timeframe == 'daily' %}primary{% else %}success{% endif %}">
{{ 'D' if signal.timeframe == 'daily' else 'W' }}
</span>
</td>
<td style="min-width: 160px;">
{% if signal.new_high_confirmed %}
<!-- 新格式:时间节点信息 -->
<div class="timeline-compact">
{% if signal.new_high_date %}
<div class="d-flex justify-content-between mb-1">
<small class="text-success fw-bold">🚀 创新高:</small>
<span class="small fw-bold text-success">{{ signal.new_high_date | datetime_format('%m-%d') }}</span>
</div>
{% endif %}
{% if signal.confirmation_date %}
<div class="d-flex justify-content-between mb-1">
<small class="text-warning fw-bold">✅ 确认:</small>
<span class="small fw-bold text-warning">{{ signal.confirmation_date | datetime_format('%m-%d') }}</span>
</div>
{% endif %}
{% if signal.confirmation_days %}
<div class="d-flex justify-content-between mb-1">
<small class="text-muted">用时:</small>
<span class="badge bg-info small">{{ signal.confirmation_days }}天</span>
</div>
{% endif %}
{% if signal.pullback_distance %}
<div class="d-flex justify-content-between">
<small class="text-muted">回踩:</small>
<span class="badge bg-{% if signal.pullback_distance > -2 %}success{% elif signal.pullback_distance > -5 %}warning{% else %}danger{% endif %} small">
{{ signal.pullback_distance | currency }}%
</span>
</div>
{% endif %}
</div>
{% else %}
<!-- 旧格式:兼容显示 -->
<div class="text-muted">{{ signal.signal_date | datetime_format('%m-%d') }}</div>
{% endif %}
</td>
<td style="min-width: 120px;">
{% if signal.new_high_confirmed %}
<!-- 新格式:价格信息 -->
<div class="price-compact">
{% if signal.new_high_price %}
<div class="d-flex justify-content-between">
<small class="text-muted">新高:</small>
<span class="text-success fw-bold small">{{ signal.new_high_price | currency }}</span>
</div>
{% endif %}
<div class="d-flex justify-content-between">
<small class="text-muted">突破:</small>
<span class="text-primary small">{{ signal.breakout_price | currency }}</span>
</div>
<div class="d-flex justify-content-between">
<small class="text-muted">阴高:</small>
<span class="text-secondary small">{{ signal.yin_high | currency }}</span>
</div>
</div>
{% else %}
<!-- 旧格式:兼容显示 -->
<div class="text-success fw-bold">{{ signal.breakout_price | currency }}元</div>
<div class="text-muted small">{{ signal.yin_high | currency }}元</div>
{% endif %}
</td>
<td style="min-width: 120px;">
<div class="tech-compact">
<div class="d-flex justify-content-between">
<small class="text-muted">突破:</small>
<span class="badge bg-{% if signal.breakout_pct and signal.breakout_pct > 3 %}success{% elif signal.breakout_pct and signal.breakout_pct > 1 %}warning{% else %}secondary{% endif %} small">
{{ signal.breakout_pct | percentage }}
</span>
</div>
<div class="d-flex justify-content-between">
<small class="text-muted">实体:</small>
<span class="small">{{ signal.final_yang_entity_ratio | percentage }}</span>
</div>
{% if signal.above_ema20 %}
<div class="d-flex justify-content-between">
<small class="text-muted">EMA20:</small>
<span class="badge bg-{% if signal.above_ema20 %}success{% else %}secondary{% endif %} small">
{{ '✅' if signal.above_ema20 else '❌' }}
</span>
</div>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% else %}
<div class="empty-state">
<i class="fas fa-chart-bar"></i>
<h4>暂无交易信号</h4>
<p>系统将在检测到符合条件的K线形态时显示信号</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- 回踩提醒 -->
{% if pullback_alerts %}
<div class="row mt-4">
<div class="col-12">
<div class="card border-warning">
<div class="card-header bg-warning text-dark">
<h5 class="mb-0">
<i class="fas fa-exclamation-triangle me-2"></i>最近回踩提醒
</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>股票代码</th>
<th>股票名称</th>
<th>回踩日期</th>
<th>当前价格</th>
<th>阴线高点</th>
<th>回调幅度</th>
<th>距离高点</th>
</tr>
</thead>
<tbody>
{% for alert in pullback_alerts[:5] %}
<tr>
<td><span class="badge bg-secondary">{{ alert.stock_code }}</span></td>
<td>{{ alert.stock_name }}</td>
<td>{{ alert.pullback_date | datetime_format('%Y-%m-%d') }}</td>
<td class="text-danger">{{ alert.current_price | currency }}元</td>
<td>{{ alert.yin_high | currency }}元</td>
<td>
<span class="badge bg-danger">{{ alert.pullback_pct | percentage }}</span>
</td>
<td>{{ alert.distance_to_yin_high | percentage }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="text-end">
<a href="{{ url_for('pullbacks') }}" class="btn btn-warning btn-sm">
<i class="fas fa-eye me-1"></i>查看全部回踩提醒
</a>
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}
{% block extra_js %}
<script>
// 自动刷新功能
function autoRefresh() {
setTimeout(function() {
location.reload();
}, 300000); // 5分钟自动刷新
}
$(document).ready(function() {
autoRefresh();
});
</script>
{% endblock %}