持仓监控平仓自动记入交易记录,新增交易记录页与实盘资金设置
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+35
-4
@@ -331,11 +331,41 @@
|
||||
.review-detail-image{flex-shrink:0;padding-top:.75rem;border-top:1px solid var(--table-border)}
|
||||
.review-detail-image img{width:100%;border-radius:10px;border:1px solid var(--card-border)}
|
||||
.review-detail-image .no-img{color:var(--text-muted);font-size:.85rem;padding:2rem;text-align:center;background:var(--card-inner);border-radius:10px}
|
||||
.key-live{display:flex;flex-direction:column;align-items:center;gap:.15rem;min-width:100px;font-size:.8rem}
|
||||
.key-live .live-price{font-size:1rem;font-weight:600;color:var(--accent)}
|
||||
.key-live .live-dist{color:var(--text-muted);font-size:.72rem;white-space:nowrap}
|
||||
.key-live{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex:1;min-width:160px}
|
||||
.key-live .live-price-line{font-size:.85rem;font-weight:600;color:var(--accent);white-space:nowrap}
|
||||
.key-live .live-dist{font-size:.72rem;color:var(--text-muted);white-space:nowrap}
|
||||
.key-live .live-dist span{color:var(--text-primary)}
|
||||
.list-item.key-item{gap:.65rem}
|
||||
.pos-card{background:var(--card-inner);border:1px solid var(--card-border);border-radius:12px;padding:1rem;margin-bottom:.75rem}
|
||||
.pos-card-head{display:flex;justify-content:space-between;align-items:flex-start;gap:.5rem;margin-bottom:.65rem}
|
||||
.pos-card-head .title{font-size:1rem;font-weight:600;color:var(--text-title)}
|
||||
.pos-card-meta{font-size:.75rem;color:var(--text-muted);margin-bottom:.65rem}
|
||||
.pos-card-meta strong{color:var(--text-primary)}
|
||||
.pos-metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:.5rem .65rem;margin-bottom:.65rem}
|
||||
.pos-metrics .cell label{display:block;font-size:.68rem;color:var(--text-muted);margin-bottom:.15rem}
|
||||
.pos-metrics .cell div{font-size:.88rem;color:var(--text-primary)}
|
||||
.pos-metrics .cell.pnl-pos div{color:var(--profit)}
|
||||
.pos-metrics .cell.pnl-neg div{color:var(--loss)}
|
||||
.pos-footer{font-size:.72rem;color:var(--text-muted);display:flex;flex-wrap:wrap;gap:.35rem 1rem;padding-top:.65rem;border-top:1px solid var(--table-border)}
|
||||
.pos-footer span{color:var(--text-primary)}
|
||||
.pos-del{font-size:.75rem;padding:.35rem .65rem}
|
||||
.trade-toolbar{display:flex;align-items:center;gap:1rem;margin-bottom:1rem;flex-wrap:wrap}
|
||||
.trade-toolbar label{display:flex;align-items:center;gap:.4rem;font-size:.85rem;cursor:pointer;color:var(--text-muted)}
|
||||
.trade-table-wrap{overflow-x:auto}
|
||||
.trade-table{font-size:.8rem}
|
||||
.trade-table th{font-size:.75rem;padding:.55rem .45rem}
|
||||
.trade-table td{padding:.45rem .4rem;vertical-align:middle}
|
||||
.trade-table input,.trade-table select{
|
||||
padding:.35rem .45rem;font-size:.78rem;border-radius:6px;width:100%;min-width:0;
|
||||
}
|
||||
.trade-table .cell-readonly{color:var(--text-primary)}
|
||||
.trade-actions{display:flex;gap:.35rem;flex-wrap:wrap}
|
||||
.trade-actions a,.trade-actions button{font-size:.72rem;padding:.3rem .55rem;border-radius:6px;text-decoration:none;border:none;cursor:pointer}
|
||||
.btn-fill{background:var(--dir-bg);color:var(--accent)}
|
||||
.btn-verify{background:var(--nav-active);color:#fff}
|
||||
.btn-verify:disabled{opacity:.45;cursor:not-allowed}
|
||||
.badge.result-manual{background:var(--dir-bg);color:var(--accent)}
|
||||
.badge.result-external{background:var(--expired-bg);color:var(--expired-text)}
|
||||
.calc-readonly{background:var(--calc-bg);color:var(--accent)}
|
||||
@media(max-width:1100px){
|
||||
.split-grid{grid-template-columns:1fr}
|
||||
@@ -366,7 +396,8 @@
|
||||
<nav class="site-nav">
|
||||
<a href="{{ url_for('plans') }}" class="{% if request.endpoint == 'plans' %}active{% endif %}">开单计划</a>
|
||||
<a href="{{ url_for('keys') }}" class="{% if request.endpoint == 'keys' %}active{% endif %}">关键位监控</a>
|
||||
<a href="{{ url_for('records') }}" class="{% if request.endpoint == 'records' %}active{% endif %}">交易记录与复盘</a>
|
||||
<a href="{{ url_for('trades') }}" class="{% if request.endpoint == 'trades' %}active{% endif %}">交易记录</a>
|
||||
<a href="{{ url_for('records') }}" class="{% if request.endpoint == 'records' %}active{% endif %}">复盘</a>
|
||||
<a href="{{ url_for('stats') }}" class="{% if request.endpoint == 'stats' %}active{% endif %}">统计分析</a>
|
||||
<a href="{{ url_for('settings') }}" class="{% if request.endpoint == 'settings' %}active{% endif %}">系统设置</a>
|
||||
</nav>
|
||||
|
||||
+43
-2
@@ -43,8 +43,8 @@
|
||||
<span class="badge dir">{{ '多' if k.direction == 'long' else '空' }}</span>
|
||||
</div>
|
||||
<div class="key-live">
|
||||
<span class="live-price">--</span>
|
||||
<span class="live-dist">距上 <span class="dist-up">--</span> · 距下 <span class="dist-down">--</span></span>
|
||||
<span class="live-price-line">现价:<span class="live-price">--</span></span>
|
||||
<span class="live-dist">距上<span class="dist-up">--</span> 距下<span class="dist-down">--</span></span>
|
||||
</div>
|
||||
<div>上{{ k.upper }} 下{{ k.lower }}</div>
|
||||
<a href="{{ url_for('del_key', pid=k.id) }}" class="btn-del" onclick="return confirm('移入历史?')">删</a>
|
||||
@@ -79,6 +79,47 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="split-grid" style="margin-top:1.5rem">
|
||||
<div class="card">
|
||||
<h2>持仓录入</h2>
|
||||
<div class="card-body">
|
||||
<form action="{{ url_for('add_position') }}" method="post" class="form-compact">
|
||||
<div class="form-line line-3">
|
||||
<div class="symbol-wrap">
|
||||
<input type="text" class="symbol-input" placeholder="主力合约" autocomplete="off" required>
|
||||
<input type="hidden" name="symbol" required>
|
||||
<input type="hidden" name="symbol_name">
|
||||
<input type="hidden" name="market_code" required>
|
||||
<input type="hidden" name="sina_code">
|
||||
<div class="symbol-dropdown"></div>
|
||||
<div class="symbol-selected"></div>
|
||||
</div>
|
||||
<div class="mini-field"><span>开仓时间</span><input type="datetime-local" name="open_time" required></div>
|
||||
<input name="lots" type="number" step="1" min="1" value="1" placeholder="张数" required>
|
||||
</div>
|
||||
<div class="form-line line-3">
|
||||
<input name="entry_price" type="number" step="0.0001" placeholder="成交价格" required>
|
||||
<input name="stop_loss" type="number" step="0.0001" placeholder="止损" required>
|
||||
<input name="take_profit" type="number" step="0.0001" placeholder="止盈" required>
|
||||
</div>
|
||||
<div class="form-line line-btn">
|
||||
<button type="submit" class="btn-primary">添加持仓</button>
|
||||
</div>
|
||||
</form>
|
||||
<p class="hint" style="margin-top:.5rem">方向根据止损与成交价自动判断;风险比例依赖系统设置中的实盘资金。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>实时持仓</h2>
|
||||
<div class="card-body card-scroll" id="position-live-list">
|
||||
{% if not positions %}
|
||||
<div class="empty-hint">暂无持仓,左侧录入后显示</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/keys.js') }}"></script>
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
{% else %}<span class="badge active">已激活</span>{% endif %}
|
||||
</div>
|
||||
<div class="key-live">
|
||||
<span class="live-price">--</span>
|
||||
<span class="live-dist">距上 <span class="dist-up">--</span> · 距下 <span class="dist-down">--</span></span>
|
||||
<span class="live-price-line">现价:<span class="live-price">--</span></span>
|
||||
<span class="live-dist">距上<span class="dist-up">--</span> 距下<span class="dist-down">--</span></span>
|
||||
</div>
|
||||
<div>
|
||||
区间{{ p.zone_lower }}~{{ p.zone_upper }}
|
||||
|
||||
+17
-1
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}交易记录与复盘 - 国内期货监控系统{% endblock %}
|
||||
{% block title %}复盘 - 国内期货监控系统{% endblock %}
|
||||
{% block content %}
|
||||
<div class="split-grid records-split">
|
||||
<div class="card">
|
||||
@@ -178,4 +178,20 @@
|
||||
{% endblock %}
|
||||
{% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/review.js') }}"></script>
|
||||
{% if prefill %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var form = document.getElementById('review-form');
|
||||
if (!form) return;
|
||||
var map = {{ prefill | tojson }};
|
||||
Object.keys(map).forEach(function (k) {
|
||||
var el = form.querySelector('[name="' + k + '"]');
|
||||
if (el && map[k] != null && map[k] !== '') el.value = map[k];
|
||||
});
|
||||
var symInput = form.querySelector('.symbol-input');
|
||||
if (symInput && map.symbol_name) symInput.value = map.symbol_name;
|
||||
if (typeof recalc === 'function') recalc();
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -2,6 +2,16 @@
|
||||
{% block title %}系统设置 - 国内期货监控系统{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<div class="card">
|
||||
<h2>实盘资金</h2>
|
||||
<form action="{{ url_for('settings') }}" method="post" class="form-row">
|
||||
<input type="hidden" name="action" value="capital">
|
||||
<input name="live_capital" type="number" step="0.01" min="0" placeholder="实盘资金(元)" value="{{ live_capital }}" style="flex:1;min-width:200px;max-width:320px">
|
||||
<button type="submit" class="btn-primary">保存</button>
|
||||
</form>
|
||||
<p class="hint" style="margin-top:.75rem">用于持仓监控的风险比例、仓位占比计算,保存在数据库中。</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>行情说明</h2>
|
||||
<p class="hint" style="font-size:.9rem;line-height:1.6">
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}交易记录 - 国内期货监控系统{% endblock %}
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
<h2>交易记录</h2>
|
||||
<div class="card-body">
|
||||
<div class="trade-toolbar">
|
||||
<label><input type="checkbox" id="trade-edit-switch"> 修改/核对开关(开启后可编辑关键字段)</label>
|
||||
</div>
|
||||
<div class="trade-table-wrap card-scroll">
|
||||
<table class="trade-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>品种</th><th>类型</th><th>方向</th>
|
||||
<th>成交</th><th>止损(开仓)</th><th>止盈</th>
|
||||
<th>基数</th><th>杠杆</th><th>持仓分钟</th>
|
||||
<th>开仓时间</th><th>平仓时间</th>
|
||||
<th>盈亏(元)</th><th>结果</th><th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for t in trades %}
|
||||
<tr data-trade-id="{{ t.id }}">
|
||||
<td><span class="cell-readonly">{{ t.symbol_name or t.symbol }}</span></td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide">{{ t.monitor_type }}</span>
|
||||
<input class="cell-edit-show" type="hidden" name="monitor_type" value="{{ t.monitor_type }}">
|
||||
</td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide">
|
||||
<span class="badge dir">{{ '做多' if t.direction == 'long' else '做空' }}</span>
|
||||
</span>
|
||||
<select class="cell-edit-show" name="direction" style="display:none">
|
||||
<option value="long" {% if t.direction=='long' %}selected{% endif %}>做多</option>
|
||||
<option value="short" {% if t.direction=='short' %}selected{% endif %}>做空</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide">{{ t.entry_price }}</span>
|
||||
<input class="cell-edit-show" type="number" step="0.0001" name="entry_price" value="{{ t.entry_price }}" style="display:none">
|
||||
</td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide">{{ t.stop_loss }}</span>
|
||||
<input class="cell-edit-show" type="number" step="0.0001" name="stop_loss" value="{{ t.stop_loss }}" style="display:none">
|
||||
</td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide">{{ t.take_profit }}</span>
|
||||
<input class="cell-edit-show" type="number" step="0.0001" name="take_profit" value="{{ t.take_profit }}" style="display:none">
|
||||
</td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide">{{ t.lots }}手 / {{ t.margin or '-' }}</span>
|
||||
<input class="cell-edit-show" type="number" step="0.01" name="margin" value="{{ t.margin or '' }}" placeholder="保证金" style="display:none">
|
||||
<input type="hidden" name="lots" value="{{ t.lots }}">
|
||||
</td>
|
||||
<td><span class="cell-readonly">—</span></td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide">{{ t.holding_minutes or 0 }}</span>
|
||||
<input class="cell-edit-show" type="number" name="holding_minutes" value="{{ t.holding_minutes or 0 }}" style="display:none">
|
||||
</td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide">{{ (t.open_time or '')[:16].replace('T',' ') }}</span>
|
||||
<input class="cell-edit-show" type="text" name="open_time" value="{{ t.open_time or '' }}" style="display:none">
|
||||
</td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide">{{ (t.close_time or '')[:16].replace('T',' ') }}</span>
|
||||
<input class="cell-edit-show" type="text" name="close_time" value="{{ t.close_time or '' }}" style="display:none">
|
||||
</td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide {% if t.pnl and t.pnl > 0 %}text-profit{% elif t.pnl and t.pnl < 0 %}text-loss{% endif %}">
|
||||
{{ t.pnl if t.pnl is not none else '-' }}
|
||||
</span>
|
||||
<input class="cell-edit-show" type="number" step="0.01" name="pnl" value="{{ t.pnl or '' }}" style="display:none">
|
||||
<input type="hidden" name="close_price" value="{{ t.close_price or '' }}">
|
||||
<input type="hidden" name="symbol_name" value="{{ t.symbol_name or t.symbol }}">
|
||||
</td>
|
||||
<td>
|
||||
<span class="cell-readonly cell-edit-hide">
|
||||
{% if t.result == '止盈' %}<span class="badge profit">{{ t.result }}</span>
|
||||
{% elif t.result == '止损' %}<span class="badge loss">{{ t.result }}</span>
|
||||
{% elif t.result == '手动平仓' %}<span class="badge result-manual">{{ t.result }}</span>
|
||||
{% else %}<span class="badge result-external">{{ t.result }}</span>{% endif %}
|
||||
{% if t.verified %}<span class="badge active" style="margin-left:.25rem">已核对</span>{% endif %}
|
||||
</span>
|
||||
<select class="cell-edit-show" name="result" style="display:none">
|
||||
<option value="手动平仓" {% if t.result=='手动平仓' %}selected{% endif %}>手动平仓</option>
|
||||
<option value="止盈" {% if t.result=='止盈' %}selected{% endif %}>止盈</option>
|
||||
<option value="止损" {% if t.result=='止损' %}selected{% endif %}>止损</option>
|
||||
<option value="外部平仓" {% if t.result=='外部平仓' %}selected{% endif %}>外部平仓</option>
|
||||
<option value="时间平仓" {% if t.result=='时间平仓' %}selected{% endif %}>时间平仓</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<div class="trade-actions">
|
||||
<a href="{{ url_for('fill_review_from_trade', tid=t.id) }}" class="btn-fill">填入复盘</a>
|
||||
<button type="button" class="btn-verify trade-save-btn" disabled>核对修改</button>
|
||||
<a href="{{ url_for('del_trade', tid=t.id) }}" class="btn-del" onclick="return confirm('删除?')">删除</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="14" class="text-muted">暂无交易记录</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/trades.js') }}"></script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user