Isolate CTP in worker process and improve strategy roll UX.
Split vn.py into qihuo-ctp worker with IPC client bridge, keep CTP connected during breaks with cached account fallback, speed up strategy page loads, and allow off-session breakout roll submissions. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+10
-4
@@ -136,7 +136,10 @@
|
||||
<button type="button" class="btn-primary" id="btn-roll-exec" hidden {% if not roll_allowed %}disabled{% endif %}>执行滚仓</button>
|
||||
</div>
|
||||
<div id="roll-preview" class="strategy-preview" hidden></div>
|
||||
<p class="hint" id="roll-exec-hint" hidden style="font-size:.75rem;margin-top:.45rem">市价加仓:须交易时段内确认,10 秒倒计时执行;突破加仓:任意时间可提交,开盘后再监控触价</p>
|
||||
<p class="hint" id="roll-exec-hint" hidden style="font-size:.75rem;margin-top:.45rem">市价加仓:须交易时段内确认,10 秒倒计时执行;突破加仓:休盘也可提交,开盘后再监控触价</p>
|
||||
{% if not trading_session %}
|
||||
<p class="hint text-muted" id="roll-off-session-hint" style="font-size:.75rem;margin-top:.35rem">当前{{ session_clock.status_label or '休盘' }}:请选「突破加仓」填写突破价后预览并提交监控。</p>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% else %}
|
||||
<p class="empty-hint">暂无可用持仓监控</p>
|
||||
@@ -151,7 +154,7 @@
|
||||
<div class="table-responsive">
|
||||
<table class="strategy-preview-table">
|
||||
<thead><tr>
|
||||
<th>ID</th><th>品种</th><th>方向</th><th>腿数</th><th>首仓TP</th><th>当前SL</th><th>当前均价</th><th>止盈盈利(元)</th>
|
||||
<th>ID</th><th>品种</th><th>方向</th><th>腿数</th><th>首仓手数</th><th>当前总手数</th><th>首仓TP</th><th>当前SL</th><th>当前均价</th><th>止盈盈利(元)</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
{% for g in roll_groups %}
|
||||
@@ -160,6 +163,8 @@
|
||||
<td>{{ g.symbol_name or g.symbol }}</td>
|
||||
<td>{{ '多' if g.direction == 'long' else '空' }}</td>
|
||||
<td>{{ g.leg_count or 0 }}/3</td>
|
||||
<td>{{ g.first_lots if g.first_lots is not none else '—' }}</td>
|
||||
<td>{{ g.total_lots if g.total_lots is not none else '—' }}</td>
|
||||
<td>{{ g.initial_take_profit or '—' }}</td>
|
||||
<td>{{ g.current_stop_loss or '—' }}</td>
|
||||
<td>{{ g.avg_entry or '—' }}</td>
|
||||
@@ -172,12 +177,12 @@
|
||||
{% else %}
|
||||
<p class="hint text-muted">暂无</p>
|
||||
{% endif %}
|
||||
<h3 style="font-size:.85rem;margin:1rem 0 .45rem">最近滚仓腿</h3>
|
||||
<h3 style="font-size:.85rem;margin:1rem 0 .45rem">正在滚仓</h3>
|
||||
{% if roll_legs %}
|
||||
<div class="table-responsive">
|
||||
<table class="strategy-preview-table">
|
||||
<thead><tr>
|
||||
<th>#</th><th>组</th><th>方式</th><th>手数</th><th>触发/限价</th><th>新SL</th><th>状态</th><th>操作</th>
|
||||
<th>#</th><th>组</th><th>方式</th><th>手数</th><th>触发/限价</th><th>新SL</th><th>当前价</th><th>状态</th><th>操作</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
{% for l in roll_legs %}
|
||||
@@ -188,6 +193,7 @@
|
||||
<td>{{ l.lots or '—' }}</td>
|
||||
<td>{{ l.breakthrough_price or l.limit_price or l.fill_price or '—' }}</td>
|
||||
<td>{{ l.new_stop_loss or '—' }}</td>
|
||||
<td>{{ l.current_price if l.current_price is not none else '—' }}</td>
|
||||
<td title="{{ l.invalidated_reason or '' }}">{{ roll_leg_status_labels.get(l.status, l.status) }}{% if l.status == 'invalidated' and l.invalidated_reason %} · {{ l.invalidated_reason[:24] }}{% endif %}</td>
|
||||
<td>{% if l.status == 'pending' %}<button type="button" class="btn-link roll-cancel-leg" data-leg-id="{{ l.id }}">删除</button>{% else %}—{% endif %}</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
{# Copyright (c) 2025-2026 马建军. All rights reserved. 专有软件,详见 LICENSE.zh-CN.txt #}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}策略记录 - 国内期货 · 交易复盘系统{% endblock %}
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
.strategy-preview{background:var(--card-inner);border:1px solid var(--card-border);border-radius:8px;padding:.65rem .85rem;font-size:.78rem;line-height:1.5}
|
||||
.strategy-preview-table{width:100%;border-collapse:collapse;font-size:.72rem;min-width:520px}
|
||||
.strategy-preview-table th,.strategy-preview-table td{padding:.35rem .4rem;border-bottom:1px solid var(--table-border);text-align:right;white-space:nowrap}
|
||||
.strategy-preview-table th:first-child,.strategy-preview-table td:first-child{text-align:left}
|
||||
.strategy-preview-table thead th{color:var(--text-muted);font-weight:600;background:var(--list-item-bg)}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="split-grid">
|
||||
<div class="card card-scroll">
|
||||
@@ -15,7 +24,33 @@
|
||||
<h2>顺势加仓</h2>
|
||||
{% if roll_rows %}
|
||||
<ul class="list">{% for r in roll_rows %}
|
||||
<li class="list-item"><span>{{ r.symbol }} {{ r.result_label }} · {{ r.closed_at or r.created_at }}</span></li>
|
||||
<li class="list-item">
|
||||
<details style="width:100%">
|
||||
<summary>{{ r.symbol }} {{ r.result_label }} · {{ r.closed_at or r.created_at }}</summary>
|
||||
<div class="strategy-preview" style="margin-top:.55rem">
|
||||
<p>方向:{{ '多' if r.direction == 'long' else '空' }}</p>
|
||||
<p>首仓手数:{{ r.detail.first_lots or '—' }} · 加仓次数:{{ r.detail.add_count or 0 }} · 加仓手数:{{ r.detail.add_lots or 0 }} · 当前总手数:{{ r.detail.total_lots or '—' }}</p>
|
||||
<p>最新止损:{{ r.detail.latest_stop_loss or '—' }} · 平仓价格:{{ r.detail.close_price or '—' }} · 盈利情况:{{ r.detail.pnl if r.detail.pnl is not none else '—' }}</p>
|
||||
{% if r.detail.legs %}
|
||||
<table class="strategy-preview-table">
|
||||
<thead><tr><th>腿</th><th>方式</th><th>手数</th><th>成交/触发价</th><th>新SL</th><th>时间</th></tr></thead>
|
||||
<tbody>
|
||||
{% for l in r.detail.legs %}
|
||||
<tr>
|
||||
<td>{{ l.leg_index or loop.index }}</td>
|
||||
<td>{{ l.add_mode }}</td>
|
||||
<td>{{ l.lots or '—' }}</td>
|
||||
<td>{{ l.fill_price or l.breakthrough_price or l.limit_price or '—' }}</td>
|
||||
<td>{{ l.new_stop_loss or '—' }}</td>
|
||||
<td>{{ l.created_at or '—' }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</details>
|
||||
</li>
|
||||
{% endfor %}</ul>
|
||||
{% else %}<p class="empty-hint">暂无记录</p>{% endif %}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user