9b4bbbe8a3
Co-authored-by: Cursor <cursoragent@cursor.com>
175 lines
11 KiB
HTML
175 lines
11 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}交易记录与复盘 - 国内期货监控系统{% endblock %}
|
|
{% block content %}
|
|
<h1 class="page-title">交易记录与复盘</h1>
|
|
|
|
<div class="split-grid">
|
|
<div class="card">
|
|
<h2>交易复盘记录上传(含截图)</h2>
|
|
<div class="card-body card-scroll">
|
|
<form id="review-form" action="{{ url_for('add_review') }}" method="post" enctype="multipart/form-data">
|
|
<div class="form-grid">
|
|
<div class="field"><label>品种</label><input name="symbol" placeholder="ag2608" required></div>
|
|
<div class="field">
|
|
<label>方向</label>
|
|
<select name="direction" required>
|
|
<option value="">请选择</option>
|
|
<option value="long">做多</option>
|
|
<option value="short">做空</option>
|
|
</select>
|
|
</div>
|
|
<div class="field"><label>成交价</label><input name="entry_price" type="number" step="0.0001" required></div>
|
|
<div class="field"><label>止损</label><input name="stop_loss" type="number" step="0.0001" required></div>
|
|
<div class="field"><label>止盈</label><input name="take_profit" type="number" step="0.0001" required></div>
|
|
<div class="field"><label>平仓价格</label><input name="close_price" type="number" step="0.0001" required></div>
|
|
<div class="field"><label>张数</label><input name="lots" type="number" step="1" min="1" value="1" required></div>
|
|
<div class="field"><label>开仓时间</label><input type="datetime-local" name="open_time" required></div>
|
|
<div class="field"><label>平仓时间</label><input type="datetime-local" name="close_time" required></div>
|
|
<div class="field"><label>持仓时长(自动)</label><input id="holding_duration" type="text" readonly class="calc-readonly" placeholder="自动计算"></div>
|
|
<div class="field"><label>初始盈亏(自动)</label><input id="initial_pnl" type="text" readonly class="calc-readonly" placeholder="按止盈测算"></div>
|
|
<div class="field"><label>实际盈亏(自动)</label><input id="actual_pnl" type="text" readonly class="calc-readonly" placeholder="按平仓价测算"></div>
|
|
<div class="field"><label>盈亏金额(手动)</label><input name="pnl" type="number" step="0.01" placeholder="实际盈亏金额"></div>
|
|
<div class="field"><label>周期</label><input name="timeframe" value="5m"></div>
|
|
<div class="field full">
|
|
<label>开仓类型(必选)</label>
|
|
<select name="open_type" required>
|
|
<option value="">请选择</option>
|
|
{% for t in open_types %}<option value="{{ t }}">{{ t }}</option>{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="field"><label>预期 RR</label><input name="expected_rr" type="number" step="0.01"></div>
|
|
<div class="field"><label>实际 RR</label><input name="actual_rr" type="number" step="0.01"></div>
|
|
<div class="field">
|
|
<label>离场触发(必选)</label>
|
|
<select name="exit_trigger" required>
|
|
<option value="">请选择</option>
|
|
{% for t in exit_triggers %}<option value="{{ t }}">{{ t }}</option>{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="field"><label>离场补充</label><input name="exit_supplement" placeholder="手工平仓说明"></div>
|
|
<div class="field">
|
|
<label>保本后盯盘</label>
|
|
<select name="watch_after_breakeven"><option value="否">否</option><option value="是">是</option></select>
|
|
</div>
|
|
<div class="field">
|
|
<label>占用时新开仓</label>
|
|
<select name="new_position_while_occupied"><option value="否">否</option><option value="是">是</option></select>
|
|
</div>
|
|
<div class="field"><label>截图上传</label><input type="file" name="screenshot" accept="image/*"></div>
|
|
</div>
|
|
|
|
<div class="check-row"><label><input type="checkbox" name="auto_kline" value="1"> 保存时自动生成 K 线图并作为截图</label></div>
|
|
<div class="form-grid">
|
|
<div class="field"><label>周期1</label><select name="kline_period1">{% for p in kline_periods %}<option value="{{ p }}" {% if p=='15m' %}selected{% endif %}>{{ p }}</option>{% endfor %}</select></div>
|
|
<div class="field"><label>周期2</label><select name="kline_period2">{% for p in kline_periods %}<option value="{{ p }}" {% if p=='1h' %}selected{% endif %}>{{ p }}</option>{% endfor %}</select></div>
|
|
<div class="field"><label>K线数</label><input name="kline_count" type="number" value="300"></div>
|
|
<div class="field"><label>K线截止</label><select name="kline_cutoff">{% for c in kline_cutoffs %}<option value="{{ c }}">{{ c }}</option>{% endfor %}</select></div>
|
|
</div>
|
|
|
|
<p class="hint">下方勾选行为标签的均为<strong>情绪单</strong></p>
|
|
<div class="check-row">
|
|
{% for tag in behavior_tags %}
|
|
<label><input type="checkbox" name="tag_{{ tag }}" value="1"> {{ tag }}</label>
|
|
{% endfor %}
|
|
</div>
|
|
<div class="field" style="margin-top:.75rem"><label>备注</label><textarea name="notes"></textarea></div>
|
|
<button type="submit" class="btn-primary" style="margin-top:1rem">保存复盘记录</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>复盘历史</h2>
|
|
<div class="card-body">
|
|
<div class="preset-tabs">
|
|
<a href="{{ url_for('records', preset='today') }}" class="{% if preset=='today' %}active{% endif %}">本日</a>
|
|
<a href="{{ url_for('records', preset='week') }}" class="{% if preset=='week' %}active{% endif %}">本周</a>
|
|
<a href="{{ url_for('records', preset='month') }}" class="{% if preset=='month' %}active{% endif %}">本月</a>
|
|
<a href="{{ url_for('records', preset='custom') }}" class="{% if preset=='custom' %}active{% endif %}">自定义</a>
|
|
</div>
|
|
{% if preset == 'custom' or start or end %}
|
|
<form method="get" class="filter-row">
|
|
<input type="hidden" name="preset" value="custom">
|
|
<div class="field"><label>开始</label><input type="date" name="start" value="{{ start }}"></div>
|
|
<div class="field"><label>结束</label><input type="date" name="end" value="{{ end }}"></div>
|
|
<button type="submit" class="btn-primary">筛选</button>
|
|
</form>
|
|
{% endif %}
|
|
<div class="card-scroll">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>平仓</th><th>品种</th><th>方向</th><th>盈亏</th><th>情绪单</th><th>详情</th><th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for r in reviews %}
|
|
<tr>
|
|
<td>{{ r.close_time[:16] if r.close_time else '' }}</td>
|
|
<td>{{ r.symbol }}</td>
|
|
<td><span class="badge dir">{{ '多' if r.direction == 'long' else '空' }}</span></td>
|
|
<td>
|
|
{% if r.pnl and r.pnl > 0 %}<span class="badge profit">{{ r.pnl }}</span>
|
|
{% elif r.pnl and r.pnl < 0 %}<span class="badge loss">{{ r.pnl }}</span>
|
|
{% else %}{{ r.actual_pnl or '-' }}{% endif %}
|
|
</td>
|
|
<td>{% if r.is_emotion %}<span class="badge loss">情绪</span>{% else %}-{% endif %}</td>
|
|
<td>
|
|
<button type="button" class="btn-link review-view-btn" data-review='{{ {
|
|
"symbol": r.symbol, "direction": "做多" if r.direction=="long" else "做空",
|
|
"entry_price": r.entry_price, "stop_loss": r.stop_loss, "take_profit": r.take_profit,
|
|
"close_price": r.close_price, "lots": r.lots,
|
|
"open_time": r.open_time, "close_time": r.close_time,
|
|
"holding_duration": r.holding_duration, "initial_pnl": r.initial_pnl,
|
|
"actual_pnl": r.actual_pnl, "pnl": r.pnl,
|
|
"open_type": r.open_type, "expected_rr": r.expected_rr, "actual_rr": r.actual_rr,
|
|
"exit_trigger": r.exit_trigger, "exit_supplement": r.exit_supplement,
|
|
"is_emotion": r.is_emotion, "behavior_tags": r.behavior_tags,
|
|
"notes": r.notes, "screenshot": r.screenshot
|
|
} | tojson }}'>放大查看</button>
|
|
</td>
|
|
<td><a href="{{ url_for('del_review', rid=r.id) }}" class="btn-del" onclick="return confirm('删除?')">删</a></td>
|
|
</tr>
|
|
{% else %}
|
|
<tr><td colspan="7" style="color:#888">暂无复盘记录</td></tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="review-modal" class="modal-mask">
|
|
<div class="modal-box">
|
|
<span class="modal-close">✕</span>
|
|
<h3>复盘详情</h3>
|
|
<div id="review-modal-body"></div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if auto_records %}
|
|
<div class="card" style="margin-top:1.5rem">
|
|
<h2>系统自动记录(止盈/止损)</h2>
|
|
<table>
|
|
<thead><tr><th>品种</th><th>类型</th><th>方向</th><th>触发价</th><th>结果</th><th>时间</th></tr></thead>
|
|
<tbody>
|
|
{% for r in auto_records %}
|
|
<tr>
|
|
<td>{{ r.symbol_name or r.symbol }}</td>
|
|
<td>{{ r.monitor_type }}</td>
|
|
<td><span class="badge dir">{{ '多' if r.direction == 'long' else '空' }}</span></td>
|
|
<td>{{ r.trigger_price }}</td>
|
|
<td>{% if r.result == '止盈' %}<span class="badge profit">止盈</span>{% else %}<span class="badge loss">止损</span>{% endif %}</td>
|
|
<td>{{ r.created_at[:16] if r.created_at else '' }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% endif %}
|
|
{% endblock %}
|
|
{% block extra_js %}
|
|
<script src="{{ url_for('static', filename='js/review.js') }}"></script>
|
|
{% endblock %}
|