Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c9a7dee7ff | |||
| 794ca61358 | |||
| 11aff71415 | |||
| e1dc4595a2 | |||
| fa763bd968 | |||
| 9bce381497 | |||
| 227d8b515f |
@@ -56,8 +56,6 @@
|
|||||||
<div style="display:flex;align-items:center;gap:16px;padding:14px 20px;background:var(--th-bg);flex-wrap:wrap;">
|
<div style="display:flex;align-items:center;gap:16px;padding:14px 20px;background:var(--th-bg);flex-wrap:wrap;">
|
||||||
<strong style="font-size:1rem;">{{ round.contract_code }}</strong>
|
<strong style="font-size:1rem;">{{ round.contract_code }}</strong>
|
||||||
<span class="badge badge-up">{{ round.daily_hands }} 手/天</span>
|
<span class="badge badge-up">{{ round.daily_hands }} 手/天</span>
|
||||||
<span style="font-size:0.82rem;color:var(--sub);">已开 {{ round.positions|length }} 天</span>
|
|
||||||
<span style="font-size:0.82rem;color:var(--sub);">开始 {{ round.started_at }}</span>
|
|
||||||
<span style="font-size:0.82rem;font-weight:600;{% if locks >= round.max_locks %}color:var(--danger-fg);{% endif %}">
|
<span style="font-size:0.82rem;font-weight:600;{% if locks >= round.max_locks %}color:var(--danger-fg);{% endif %}">
|
||||||
锁仓 {{ locks }}/{{ round.max_locks }}
|
锁仓 {{ locks }}/{{ round.max_locks }}
|
||||||
{% if locks >= round.max_locks %} ⚠ 熔断{% endif %}
|
{% if locks >= round.max_locks %} ⚠ 熔断{% endif %}
|
||||||
@@ -120,11 +118,10 @@
|
|||||||
<div class="table-wrap" style="margin-bottom:0;">
|
<div class="table-wrap" style="margin-bottom:0;">
|
||||||
<table style="font-size:0.84rem;">
|
<table style="font-size:0.84rem;">
|
||||||
<tr>
|
<tr>
|
||||||
<th>日期</th><th>开仓价</th><th>A</th><th>锁仓价</th><th>手数</th><th>已锁</th><th>状态</th><th>操作</th>
|
<th>开仓价</th><th>A</th><th>锁仓价</th><th>手数</th><th>已锁</th><th>状态</th><th>操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for p in round.positions|reverse %}
|
{% for p in round.positions|reverse %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{{ p.opened_at }}</strong></td>
|
|
||||||
<td>{{ p.open_price }}</td>
|
<td>{{ p.open_price }}</td>
|
||||||
<td>{{ p.amp_threshold }}</td>
|
<td>{{ p.amp_threshold }}</td>
|
||||||
<td style="color:var(--danger-fg);font-weight:600;">{{ p.lock_price }}</td>
|
<td style="color:var(--danger-fg);font-weight:600;">{{ p.lock_price }}</td>
|
||||||
|
|||||||
@@ -5,6 +5,12 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
{% set view = request.query_params.get('view', '') %}
|
{% set view = request.query_params.get('view', '') %}
|
||||||
|
{% set product_tab = request.query_params.get('tab', '全部') %}
|
||||||
|
{% set product_codes = product_contracts.keys()|list %}
|
||||||
|
{% set grouped_open = {} %}
|
||||||
|
{% for t in open_trades %}
|
||||||
|
{% set _ = grouped_open.setdefault(t.product_code, []).append(t) %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.tabs { display: flex; gap: 0; margin-bottom: 24px; border-bottom: 2px solid var(--border); }
|
.tabs { display: flex; gap: 0; margin-bottom: 24px; border-bottom: 2px solid var(--border); }
|
||||||
@@ -18,6 +24,14 @@
|
|||||||
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
|
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
|
||||||
.tab-panel { display: none; }
|
.tab-panel { display: none; }
|
||||||
.tab-panel.active { display: block; }
|
.tab-panel.active { display: block; }
|
||||||
|
.sub-tabs { display: flex; gap: 6px; margin-bottom: 16px; flex-wrap: wrap; }
|
||||||
|
.sub-tab-btn {
|
||||||
|
padding: 4px 14px; border: 1px solid var(--border); background: var(--surface);
|
||||||
|
font-size: 0.78rem; color: var(--sub); cursor: pointer; text-decoration: none;
|
||||||
|
border-radius: 4px; transition: color .12s, border-color .12s;
|
||||||
|
}
|
||||||
|
.sub-tab-btn:hover { color: var(--fg); border-color: var(--accent); }
|
||||||
|
.sub-tab-btn.active { color: var(--accent); border-color: var(--accent); font-weight: 600; background: var(--accent-light); }
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
@@ -76,13 +90,27 @@
|
|||||||
{# ── 持仓列表 ── #}
|
{# ── 持仓列表 ── #}
|
||||||
<div class="section-title">持仓中 · {{ open_trades|length }} 笔</div>
|
<div class="section-title">持仓中 · {{ open_trades|length }} 笔</div>
|
||||||
|
|
||||||
|
<div class="sub-tabs">
|
||||||
|
<a href="/trades/?tab=全部" class="sub-tab-btn{% if product_tab == '全部' %} active{% endif %}">全部</a>
|
||||||
|
{% for pc in product_codes %}
|
||||||
|
{% set count = grouped_open.get(pc, [])|length %}
|
||||||
|
<a href="/trades/?tab={{ pc }}" class="sub-tab-btn{% if product_tab == pc %} active{% endif %}">{{ pc }}{% if count %} · {{ count }}{% endif %}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if open_trades %}
|
{% if open_trades %}
|
||||||
<div class="table-wrap">
|
{% for pc in product_codes %}
|
||||||
|
{% if product_tab == '全部' or product_tab == pc %}
|
||||||
|
{% set trades = grouped_open.get(pc, []) %}
|
||||||
|
{% if trades %}
|
||||||
|
<div class="table-wrap" style="margin-bottom:24px;">
|
||||||
|
{% if product_tab == '全部' %}
|
||||||
|
<div class="section-title" style="font-size:0.88rem;margin-bottom:0;padding:6px 12px;">{{ pc }} · {{ trades|length }} 笔</div>
|
||||||
|
{% endif %}
|
||||||
<table>
|
<table>
|
||||||
<tr><th>品种</th><th>合约</th><th>方向</th><th>开仓日期</th><th>开仓价</th><th>手续费</th><th>操作</th></tr>
|
<tr><th>合约</th><th>方向</th><th>开仓日期</th><th>开仓价</th><th>手续费</th><th>操作</th></tr>
|
||||||
{% for t in open_trades %}
|
{% for t in trades %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ t.product_code }}</td>
|
|
||||||
<td><strong>{{ t.contract_code.replace(t.product_code, '', 1) }}</strong></td>
|
<td><strong>{{ t.contract_code.replace(t.product_code, '', 1) }}</strong></td>
|
||||||
<td>
|
<td>
|
||||||
{% if t.direction == 'short' %}
|
{% if t.direction == 'short' %}
|
||||||
@@ -99,7 +127,7 @@
|
|||||||
onclick="showCloseForm({{ t.id }})">平仓</button>
|
onclick="showCloseForm({{ t.id }})">平仓</button>
|
||||||
<button style="background:var(--success-bg);color:var(--success-fg);border:1px solid var(--success);padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;margin-left:8px;"
|
<button style="background:var(--success-bg);color:var(--success-fg);border:1px solid var(--success);padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;margin-left:8px;"
|
||||||
onclick="showEditForm('trade', {{ t.id }}, '{{ t.product_code }}', '{{ t.contract_code }}', '{{ t.direction }}', {{ t.open_price }}, {{ t.open_fee or 0 }}, '{{ t.open_date }}', null, null, null, '{{ t.status }}')">编辑</button>
|
onclick="showEditForm('trade', {{ t.id }}, '{{ t.product_code }}', '{{ t.contract_code }}', '{{ t.direction }}', {{ t.open_price }}, {{ t.open_fee or 0 }}, '{{ t.open_date }}', null, null, null, '{{ t.status }}')">编辑</button>
|
||||||
<form method="post" action="/trades/{{ t.id }}/delete" style="display:inline;margin-left:8px;">
|
<form method="post" action="/trades/{{ t.id }}/delete" style="display:inline;margin-left:8px;">
|
||||||
<button style="background:transparent;color:#dc2626;border:1px solid #ef4444;padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;" onclick="confirmDelete(event, '确定删除此记录?', this.closest('form').action)">删除</button>
|
<button style="background:transparent;color:#dc2626;border:1px solid #ef4444;padding:3px 10px;border-radius:4px;cursor:pointer;font-size:0.78rem;" onclick="confirmDelete(event, '确定删除此记录?', this.closest('form').action)">删除</button>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
@@ -107,6 +135,9 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div style="text-align:center;padding:40px;color:var(--sub);">暂无持仓</div>
|
<div style="text-align:center;padding:40px;color:var(--sub);">暂无持仓</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -166,7 +197,7 @@
|
|||||||
<td>
|
<td>
|
||||||
{% set p = t.pnl %}
|
{% set p = t.pnl %}
|
||||||
{% if p is not none %}
|
{% if p is not none %}
|
||||||
<span style="font-weight:700;{% if p > 0 %}color:var(--success-fg);{% elif p < 0 %}color:var(--danger-fg);{% else %}color:var(--sub);{% endif %}">
|
<span style="font-weight:700;{% if p > 0 %}color:var(--danger-fg);{% elif p < 0 %}color:var(--success-fg);{% else %}color:var(--sub);{% endif %}">
|
||||||
{% if p > 0 %}+{% endif %}{{ p }}
|
{% if p > 0 %}+{% endif %}{{ p }}
|
||||||
</span>
|
</span>
|
||||||
<span style="color:var(--sub);cursor:pointer;font-size:0.75rem;margin-left:4px;"
|
<span style="color:var(--sub);cursor:pointer;font-size:0.75rem;margin-left:4px;"
|
||||||
@@ -192,7 +223,7 @@
|
|||||||
{% set ns.total_close_fee = ns.total_close_fee + (t.close_fee or 0) %}
|
{% set ns.total_close_fee = ns.total_close_fee + (t.close_fee or 0) %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div style="display:flex;gap:24px;margin-bottom:24px;padding:12px 18px;background:var(--surface);border:1px solid var(--border);border-radius:8px;font-size:0.88rem;flex-wrap:wrap;">
|
<div style="display:flex;gap:24px;margin-bottom:24px;padding:12px 18px;background:var(--surface);border:1px solid var(--border);border-radius:8px;font-size:0.88rem;flex-wrap:wrap;">
|
||||||
<span>盈亏合计 <b style="{% if ns.total_pnl > 0 %}color:var(--success-fg);{% elif ns.total_pnl < 0 %}color:var(--danger-fg);{% endif %}">{% if ns.total_pnl > 0 %}+{% endif %}{{ '%.2f'|format(ns.total_pnl) }}</b></span>
|
<span>盈亏合计 <b style="{% if ns.total_pnl > 0 %}color:var(--danger-fg);{% elif ns.total_pnl < 0 %}color:var(--success-fg);{% endif %}">{% if ns.total_pnl > 0 %}+{% endif %}{{ '%.2f'|format(ns.total_pnl) }}</b></span>
|
||||||
<span style="color:var(--sub);">|</span>
|
<span style="color:var(--sub);">|</span>
|
||||||
<span>开仓手续费 <b>{{ '%.2f'|format(ns.total_open_fee) }}</b></span>
|
<span>开仓手续费 <b>{{ '%.2f'|format(ns.total_open_fee) }}</b></span>
|
||||||
<span style="color:var(--sub);">|</span>
|
<span style="color:var(--sub);">|</span>
|
||||||
@@ -306,7 +337,7 @@ function showPnlDrawer(title, direction, openPrice, closePrice, openFee, closeFe
|
|||||||
html += '<tr><td>开仓手续费</td><td></td><td style="text-align:right;color:var(--danger-fg);">-' + openFee.toFixed(2) + '</td></tr>';
|
html += '<tr><td>开仓手续费</td><td></td><td style="text-align:right;color:var(--danger-fg);">-' + openFee.toFixed(2) + '</td></tr>';
|
||||||
html += '<tr><td>平仓手续费</td><td></td><td style="text-align:right;color:var(--danger-fg);">-' + closeFee.toFixed(2) + '</td></tr>';
|
html += '<tr><td>平仓手续费</td><td></td><td style="text-align:right;color:var(--danger-fg);">-' + closeFee.toFixed(2) + '</td></tr>';
|
||||||
document.getElementById('pnlTable').innerHTML = html;
|
document.getElementById('pnlTable').innerHTML = html;
|
||||||
document.getElementById('pnlResult').innerHTML = '<b>盈亏 = ' + gross.toFixed(2) + ' - ' + openFee.toFixed(2) + ' - ' + closeFee.toFixed(2) + ' = <span style="color:' + (result > 0 ? 'var(--success-fg)' : result < 0 ? 'var(--danger-fg)' : 'var(--sub)') + ';">' + (result > 0 ? '+' : '') + result.toFixed(2) + '</span></b>';
|
document.getElementById('pnlResult').innerHTML = '<b>盈亏 = ' + gross.toFixed(2) + ' - ' + openFee.toFixed(2) + ' - ' + closeFee.toFixed(2) + ' = <span style="color:' + (result > 0 ? 'var(--danger-fg)' : result < 0 ? 'var(--success-fg)' : 'var(--sub)') + ';">' + (result > 0 ? '+' : '') + result.toFixed(2) + '</span></b>';
|
||||||
document.getElementById('pnlOverlay').style.display = 'block';
|
document.getElementById('pnlOverlay').style.display = 'block';
|
||||||
document.getElementById('pnlBox').style.display = 'block';
|
document.getElementById('pnlBox').style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user