3ba3be6035
改用 split-grid 全宽布局;手机/平板/电脑断点适配;更新 manifest 与 Service Worker 支持安装为 App。 Co-authored-by: Cursor <cursoragent@cursor.com>
148 lines
8.8 KiB
HTML
148 lines
8.8 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}持仓监控 - 国内期货监控系统{% endblock %}
|
|
{% block extra_css %}
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/trade.css') }}">
|
|
{% endblock %}
|
|
{% block content %}
|
|
<div class="trade-page">
|
|
<div class="trade-top-bar">
|
|
<div class="trade-top-bar-main">
|
|
<span class="badge dir">{{ trading_mode_label }}</span>
|
|
<span class="badge {% if ctp_status.connected %}profit{% else %}planned{% endif %}" id="ctp-badge">
|
|
{% if ctp_status.connected %}CTP 已连接{% else %}CTP 未连接{% endif %}
|
|
</span>
|
|
<span class="badge {% if risk_status.can_trade %}profit{% else %}loss{% endif %}" id="risk-badge">{{ risk_status.status_label }}</span>
|
|
<span class="text-muted">权益 <strong id="cap-display">{{ '%.2f'|format(capital) }}</strong> 元</span>
|
|
{% if ctp_account.available is defined and ctp_status.connected %}
|
|
<span class="text-muted">可用 <strong id="avail-display">{{ '%.2f'|format(ctp_account.available) }}</strong> 元</span>
|
|
{% endif %}
|
|
</div>
|
|
<div class="trade-top-bar-actions">
|
|
<button type="button" class="btn-primary btn-ctp-sm" id="btn-ctp-connect">{% if ctp_status.connected %}重连 CTP{% else %}连接 CTP{% endif %}</button>
|
|
<span class="text-muted trade-top-hint">断线自动重连</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="split-grid trade-split">
|
|
<div class="card trade-card" id="order">
|
|
<h2>期货下单</h2>
|
|
<div class="card-body">
|
|
<div class="trade-order-status trade-order-status-compact">
|
|
<div class="status-row">
|
|
<span class="text-muted">计仓</span>
|
|
<strong id="sizing-label">{{ sizing_mode_label }}</strong>
|
|
{% if sizing_mode == 'risk' %}<span class="text-muted">· 单笔风险 {{ risk_percent }}%</span>{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="trade-form-rows">
|
|
<div class="trade-form-line line-3">
|
|
<div class="symbol-wrap trade-field">
|
|
<label class="text-label">品种</label>
|
|
<input type="text" id="trade-symbol" class="symbol-input" placeholder="主力合约 rb2610" autocomplete="off">
|
|
<div class="symbol-dropdown"></div>
|
|
<div class="symbol-selected" id="sym-selected"></div>
|
|
</div>
|
|
<div class="trade-field">
|
|
<label class="text-label">方向</label>
|
|
<select id="trade-direction">
|
|
<option value="long">做多</option>
|
|
<option value="short">做空</option>
|
|
</select>
|
|
</div>
|
|
<div class="trade-field" id="field-lots">
|
|
<label class="text-label">手数</label>
|
|
<input type="number" id="trade-lots" min="1" step="1" value="1" {% if sizing_mode == 'risk' %}hidden{% endif %}>
|
|
<input type="text" id="trade-lots-calc" class="lots-auto" readonly placeholder="填写止损后自动计算" {% if sizing_mode != 'risk' %}hidden{% endif %}>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="trade-form-line line-3">
|
|
<div class="trade-field">
|
|
<label class="text-label">入场价</label>
|
|
<div class="price-type-tabs">
|
|
<button type="button" class="price-tab active" data-type="limit">限价</button>
|
|
<button type="button" class="price-tab" data-type="market">市价</button>
|
|
</div>
|
|
<input type="number" id="trade-price" step="any" placeholder="限价">
|
|
<p class="hint market-hint" id="market-hint" hidden>市价将按最新行情价报单</p>
|
|
</div>
|
|
<div class="trade-field">
|
|
<label class="text-label">止盈</label>
|
|
<input type="number" id="trade-tp" step="any">
|
|
</div>
|
|
<div class="trade-field">
|
|
<label class="text-label">止损</label>
|
|
<input type="number" id="trade-sl" step="any">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="trade-action-row">
|
|
<button type="button" class="btn-primary btn-open" id="btn-open">开仓</button>
|
|
<p class="trade-order-msg" id="order-msg" hidden></p>
|
|
</div>
|
|
|
|
<div class="trade-footer" id="trade-footer">
|
|
<p class="hint" id="trade-metrics-hint">填写品种后显示精度与每跳价值;策略自动化请用 <a href="{{ url_for('strategy_page') }}">策略交易</a>。</p>
|
|
{% if ctp_status.last_error %}
|
|
<p class="text-loss ctp-install-hint" style="font-size:.78rem;margin-top:.35rem">{{ ctp_status.last_error }}</p>
|
|
{% else %}
|
|
<p class="text-muted ctp-install-hint" style="font-size:.72rem;margin-top:.35rem">报单需安装 vnpy 并连接 CTP(SimNow 模拟盘)。</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card trade-card" id="positions">
|
|
<h2>持仓监控</h2>
|
|
<p class="hint pos-hint">数据来自 CTP 柜台(交易所回报),浮盈等为柜台实际值。</p>
|
|
<div class="card-body card-scroll" id="position-live-list">
|
|
<div class="empty-hint">{% if ctp_status.connected %}加载中…{% else %}请先连接 CTP 查看柜台持仓{% endif %}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card trade-card trade-card-full" id="recommend">
|
|
<h2>品种推荐</h2>
|
|
<div class="card-body">
|
|
<p class="hint">按权益 <strong class="text-accent" id="rec-capital">{{ '%.2f'|format(capital) }}</strong> 元筛选,仅显示可开 1 手的品种。
|
|
{% if recommend_updated_at %}<span class="text-muted">更新 {{ recommend_updated_at }}</span>{% else %}<span class="text-muted" id="rec-updated">后台刷新中…</span>{% endif %}
|
|
</p>
|
|
<div class="trade-table-wrap">
|
|
<table class="trade-table">
|
|
<thead>
|
|
<tr>
|
|
<th>品种</th><th>交易所</th><th>参考价</th><th>1手保证金</th><th>建议最低资金</th><th>状态</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="recommend-list">
|
|
{% if recommend_rows %}
|
|
{% for r in recommend_rows %}
|
|
<tr class="rec-{{ r.status }}">
|
|
<td><strong>{{ r.name }}</strong> <span class="text-muted">{{ r.ths }}</span></td>
|
|
<td>{{ r.exchange }}</td>
|
|
<td>{% if r.price %}{{ r.price }}{% else %}—{% endif %}</td>
|
|
<td>{% if r.margin_one_lot %}{{ r.margin_one_lot }}{% else %}—{% endif %}</td>
|
|
<td>{% if r.min_capital_one_lot %}{{ r.min_capital_one_lot }}{% else %}—{% endif %}</td>
|
|
<td><span class="badge {% if r.status=='ok' %}profit{% else %}planned{% endif %}">{{ r.status_label }}</span></td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% else %}
|
|
<tr><td colspan="6" class="empty-hint">等待后台推送推荐…</td></tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
{% block extra_js %}
|
|
<script>
|
|
window.TRADE_SIZING_MODE = {{ sizing_mode|tojson }};
|
|
window.TRADE_RISK_PERCENT = {{ risk_percent }};
|
|
</script>
|
|
<script src="{{ url_for('static', filename='js/trade.js') }}"></script>
|
|
{% endblock %}
|