Files
finance-talk/ft-app/app/templates/summary.html
T
fish 51792ce4b3 全胜时盈亏比显示∞
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-28 15:32:34 +08:00

218 lines
10 KiB
HTML

{% extends "base.html" %}
{% block title %}平仓汇总{% endblock %}
{% block heading %}平仓汇总{% endblock %}
{% block breadcrumb %}全部已平仓统计{% endblock %}
{% block content %}
<style>
.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; margin-bottom: 28px; }
.stat-card {
background: var(--surface); border: 1px solid var(--border);
border-radius: 10px; padding: 18px 20px; text-align: center;
}
.stat-card .label { font-size: 0.75rem; color: var(--sub); margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.04em; }
.stat-card .value { font-size: 1.4rem; font-weight: 700; }
.tabs { display: flex; gap: 0; margin-bottom: 24px; border-bottom: 2px solid var(--border); }
.tab-btn {
padding: 10px 20px; border: none; background: none;
font-size: 0.88rem; font-weight: 500; color: var(--sub);
cursor: pointer; text-decoration: none; border-bottom: 2px solid transparent;
margin-bottom: -2px; transition: color .12s, border-color .12s;
}
.tab-btn:hover { color: var(--fg); }
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
.tab-panel { display: none; }
.tab-panel.active { display: block; }
.sub-stat { display: flex; gap: 18px; margin-bottom: 20px; flex-wrap: wrap; }
.sub-stat span { font-size: 0.82rem; color: var(--sub); }
.sub-stat b { color: var(--fg); }
</style>
{% set view = request.query_params.get('view', '') %}
{# ── 总览卡片 ── #}
<div class="stat-grid">
<div class="stat-card">
<div class="label">总平仓笔数</div>
<div class="value">{{ total_count }}</div>
</div>
<div class="stat-card">
<div class="label">毛利</div>
<div class="value" style="{% if gross_pnl > 0 %}color:var(--danger-fg);{% elif gross_pnl < 0 %}color:var(--success-fg);{% endif %}">
{% if gross_pnl > 0 %}+{% endif %}{{ "%.2f"|format(gross_pnl) }}
</div>
</div>
<div class="stat-card">
<div class="label">总手续费</div>
<div class="value">{{ "%.2f"|format(total_fee) }}</div>
</div>
<div class="stat-card">
<div class="label">总胜率</div>
<div class="value" style="{% if total_win_rate >= 40 %}color:var(--danger-fg);{% else %}color:var(--success-fg);{% endif %}">
{{ total_win_rate }}%
</div>
</div>
<div class="stat-card">
<div class="label">盈亏比</div>
<div class="value" style="{% if profit_ratio <= 0 %}color:var(--sub);{% elif profit_ratio >= 1 %}color:var(--danger-fg);{% else %}color:var(--success-fg);{% endif %}">
{% if total_loss == 0 and total_profit > 0 %}∞{% else %}{{ "%.2f"|format(profit_ratio) }}{% endif %}
</div>
</div>
<div class="stat-card">
<div class="label">净利润</div>
<div class="value" style="{% if net_pnl > 0 %}color:var(--danger-fg);{% elif net_pnl < 0 %}color:var(--success-fg);{% endif %}">
{% if net_pnl > 0 %}+{% endif %}{{ "%.2f"|format(net_pnl) }}
</div>
</div>
</div>
{# ── 按类型分拆 ── #}
<div class="tabs">
<a href="/summary/?view=futures" class="tab-btn{% if view != 'options' and view != 'dual' %} active{% endif %}">📝 期货</a>
<a href="/summary/?view=options" class="tab-btn{% if view == 'options' %} active{% endif %}">📊 期权</a>
<a href="/summary/?view=dual" class="tab-btn{% if view == 'dual' %} active{% endif %}">🎯 双买</a>
</div>
{# ═══════════ 期货 ═══════════ #}
<div class="tab-panel{% if view != 'options' and view != 'dual' %} active{% endif %}">
<div class="sub-stat">
<span>笔数 <b>{{ future_stats.count }}</b></span>
<span>毛利 <b style="{% if future_stats.gross > 0 %}color:var(--danger-fg);{% elif future_stats.gross < 0 %}color:var(--success-fg);{% endif %}">{% if future_stats.gross > 0 %}+{% endif %}{{ "%.2f"|format(future_stats.gross) }}</b></span>
<span>手续费 <b>{{ "%.2f"|format(future_stats.total_fee) }}</b></span>
<span>净利 <b style="{% if future_stats.net > 0 %}color:var(--danger-fg);{% elif future_stats.net < 0 %}color:var(--success-fg);{% endif %}">{% if future_stats.net > 0 %}+{% endif %}{{ "%.2f"|format(future_stats.net) }}</b></span>
</div>
{% if future_trades %}
<div class="table-wrap">
<table>
<tr><th>品种</th><th>合约</th><th>方向</th><th>开仓日</th><th>平仓日</th><th>持仓</th><th>开仓价</th><th>平仓价</th><th>盈亏</th></tr>
{% for t in future_trades %}
<tr>
<td>{{ t.product_code }}</td>
<td><strong>{{ t.contract_code.replace(t.product_code, '', 1) if t.contract_code.startswith(t.product_code) else t.contract_code }}</strong></td>
<td>
{% if t.direction == 'long' %}
<span class="badge badge-up"></span>
{% else %}
<span class="badge badge-down"></span>
{% endif %}
</td>
<td style="font-size:0.8rem;">{{ t.open_date }} {{ weekdays[t.open_date.weekday()] }}</td>
<td style="font-size:0.8rem;">{{ t.close_date }} {{ weekdays[t.close_date.weekday()] }}</td>
<td>{{ (t.close_date - t.open_date).days }}天</td>
<td>{{ t.open_price }}</td>
<td>{{ t.close_price }}</td>
<td>
{% set p = t.pnl %}
{% if p is not none %}
<span style="font-weight:700;{% if p > 0 %}color:var(--danger-fg);{% elif p < 0 %}color:var(--success-fg);{% endif %}">
{% if p > 0 %}+{% endif %}{{ p }}
</span>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
{% else %}
<div style="text-align:center;padding:40px;color:var(--sub);">暂无已平仓记录</div>
{% endif %}
</div>
{# ═══════════ 期权 ═══════════ #}
<div class="tab-panel{% if view == 'options' %} active{% endif %}">
<div class="sub-stat">
<span>笔数 <b>{{ option_stats.count }}</b></span>
<span>毛利 <b style="{% if option_stats.gross > 0 %}color:var(--danger-fg);{% elif option_stats.gross < 0 %}color:var(--success-fg);{% endif %}">{% if option_stats.gross > 0 %}+{% endif %}{{ "%.2f"|format(option_stats.gross) }}</b></span>
<span>手续费 <b>{{ "%.2f"|format(option_stats.total_fee) }}</b></span>
<span>净利 <b style="{% if option_stats.net > 0 %}color:var(--danger-fg);{% elif option_stats.net < 0 %}color:var(--success-fg);{% endif %}">{% if option_stats.net > 0 %}+{% endif %}{{ "%.2f"|format(option_stats.net) }}</b></span>
</div>
{% if option_trades %}
<div class="table-wrap">
<table>
<tr><th>品种</th><th>合约</th><th>类型</th><th>买卖</th><th>行权价</th><th>开仓日</th><th>平仓日</th><th>持仓</th><th>开仓价</th><th>平仓价</th><th>盈亏</th></tr>
{% for t in option_trades %}
<tr>
<td>{{ t.product_code }}</td>
<td><strong>{{ t.contract_code.replace(t.product_code, '', 1) if t.contract_code.startswith(t.product_code) else t.contract_code }}</strong></td>
<td>
{% if t.option_type == 'C' %}
<span class="badge badge-up">C</span>
{% else %}
<span class="badge badge-down">P</span>
{% endif %}
</td>
<td>
{% if t.direction == 'buy' %}
<span class="badge badge-up"></span>
{% else %}
<span class="badge badge-down"></span>
{% endif %}
</td>
<td>{{ t.strike_price }}</td>
<td style="font-size:0.8rem;">{{ t.open_date }} {{ weekdays[t.open_date.weekday()] }}</td>
<td style="font-size:0.8rem;">{{ t.close_date }} {{ weekdays[t.close_date.weekday()] }}</td>
<td>{{ (t.close_date - t.open_date).days }}天</td>
<td>{{ t.open_price }}</td>
<td>{{ t.close_price }}</td>
<td>
{% set p = t.pnl %}
{% if p is not none %}
<span style="font-weight:700;{% if p > 0 %}color:var(--danger-fg);{% elif p < 0 %}color:var(--success-fg);{% endif %}">
{% if p > 0 %}+{% endif %}{{ p }}
</span>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
{% else %}
<div style="text-align:center;padding:40px;color:var(--sub);">暂无已平仓记录</div>
{% endif %}
</div>
{# ═══════════ 双买 ═══════════ #}
<div class="tab-panel{% if view == 'dual' %} active{% endif %}">
<div class="sub-stat">
<span>笔数 <b>{{ dual_stats.count }}</b></span>
<span>毛利 <b style="{% if dual_stats.gross > 0 %}color:var(--danger-fg);{% elif dual_stats.gross < 0 %}color:var(--success-fg);{% endif %}">{% if dual_stats.gross > 0 %}+{% endif %}{{ "%.2f"|format(dual_stats.gross) }}</b></span>
<span>手续费 <b>{{ "%.2f"|format(dual_stats.total_fee) }}</b></span>
<span>净利 <b style="{% if dual_stats.net > 0 %}color:var(--danger-fg);{% elif dual_stats.net < 0 %}color:var(--success-fg);{% endif %}">{% if dual_stats.net > 0 %}+{% endif %}{{ "%.2f"|format(dual_stats.net) }}</b></span>
</div>
{% if dual_trades %}
<div class="table-wrap">
<table>
<tr><th>品种</th><th>合约</th><th>C行权价</th><th>P行权价</th><th>开仓日</th><th>平仓日</th><th>持仓</th><th>看涨(开/平)</th><th>看跌(开/平)</th><th>盈亏</th></tr>
{% for t in dual_trades %}
<tr>
<td>{{ t.product_code }}</td>
<td><strong>{{ t.contract_code.replace(t.product_code, '', 1) if t.contract_code.startswith(t.product_code) else t.contract_code }}</strong></td>
<td>{{ t.call_strike_price }}</td>
<td>{{ t.put_strike_price }}</td>
<td style="font-size:0.8rem;">{{ t.open_date }} {{ weekdays[t.open_date.weekday()] }}</td>
<td style="font-size:0.8rem;">{{ t.close_date }} {{ weekdays[t.close_date.weekday()] }}</td>
<td>{{ (t.close_date - t.open_date).days }}天</td>
<td>{{ t.call_open_price }} / {{ t.call_close_price }}</td>
<td>{{ t.put_open_price }} / {{ t.put_close_price }}</td>
<td>
{% set p = t.pnl %}
{% if p is not none %}
<span style="font-weight:700;{% if p > 0 %}color:var(--danger-fg);{% elif p < 0 %}color:var(--success-fg);{% endif %}">
{% if p > 0 %}+{% endif %}{{ p }}
</span>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
{% else %}
<div style="text-align:center;padding:40px;color:var(--sub);">暂无已平仓记录</div>
{% endif %}
</div>
{% endblock %}