增加关键位监控自动下单
This commit is contained in:
@@ -87,7 +87,7 @@
|
||||
.review-card{grid-column:1/-1}
|
||||
@media (min-width: 1900px){
|
||||
.container{max-width:2100px}
|
||||
.monitor-card .list,.order-card .list{max-height:420px}
|
||||
.monitor-card .list,.order-card .pos-list{max-height:420px}
|
||||
.records-card .table-wrap{max-height:620px;overflow:auto}
|
||||
}
|
||||
@media (max-width: 1400px){
|
||||
@@ -112,6 +112,34 @@
|
||||
.key-history h3{font-size:.88rem;color:#b8c4ff;margin-bottom:6px}
|
||||
.key-history .sub{font-size:.72rem;color:#8892b0;margin-bottom:6px}
|
||||
.key-history .list{max-height:200px}
|
||||
.pos-section{margin-top:12px}
|
||||
.pos-section-title{font-size:.82rem;color:#8892b0;margin-bottom:8px;font-weight:500}
|
||||
.pos-list{display:flex;flex-direction:column;gap:10px;max-height:280px;overflow:auto}
|
||||
.pos-card{background:#141923;border:1px solid #2a3348;border-radius:10px;padding:12px 14px}
|
||||
.pos-card-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px}
|
||||
.pos-meta{font-size:.74rem;color:#8b95a8;line-height:1.45;margin-bottom:12px;display:flex;flex-wrap:wrap;align-items:center;gap:4px 0}
|
||||
.pos-meta-item{display:inline-flex;align-items:center}
|
||||
.pos-meta-item:not(:last-child)::after{content:'|';margin:0 8px;color:#3d4659}
|
||||
.pos-meta-on{color:#6eb5ff}
|
||||
.pos-meta-off{color:#7d8799}
|
||||
.pos-card-symbol{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
|
||||
.pos-card-symbol strong{font-size:.95rem;color:#fff;font-weight:600}
|
||||
.pos-side-badge{padding:3px 8px;border-radius:6px;font-size:.72rem;font-weight:500;line-height:1.2}
|
||||
.pos-side-long{background:#253a6e;color:#6eb5ff}
|
||||
.pos-side-short{background:#4a2230;color:#ff8a8a}
|
||||
.pos-close-btn{padding:6px 14px;background:#c45454;color:#fff;border-radius:8px;text-decoration:none;font-size:.82rem;font-weight:500;flex-shrink:0;white-space:nowrap}
|
||||
.pos-close-btn:hover{background:#d66565;color:#fff}
|
||||
.pos-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px 14px;margin-bottom:12px}
|
||||
.pos-cell{display:flex;flex-direction:column;gap:4px;min-width:0}
|
||||
.pos-label{font-size:.72rem;color:#7d8799}
|
||||
.pos-value{font-size:.88rem;color:#e8ecf4;font-weight:500;line-height:1.25}
|
||||
.pos-val-dash{opacity:.75;color:#8b95a8}
|
||||
.pos-value.price-up{color:#4cd97f}
|
||||
.pos-value.price-down{color:#ff6666}
|
||||
.pos-value.price-flat{color:#e8ecf4}
|
||||
.pos-footer{display:flex;flex-wrap:wrap;gap:14px 18px;font-size:.75rem;color:#6d7689}
|
||||
.pos-empty{padding:18px;text-align:center;color:#8892b0;font-size:.85rem;background:#141923;border:1px dashed #2a3348;border-radius:10px}
|
||||
@media (max-width:520px){.pos-grid{grid-template-columns:repeat(2,1fr)}}
|
||||
.stats-card{grid-column:1/-1;margin-top:14px}
|
||||
.stats-card .stats-toggle{background:#1f3a5a;color:#8fc8ff;border:none;border-radius:8px;padding:6px 10px;cursor:pointer}
|
||||
.stats-card.collapsed .stats-content{display:none}
|
||||
@@ -216,7 +244,7 @@
|
||||
</div>
|
||||
<div class="key-history">
|
||||
<h3>关键位历史(满次提醒或手动删除)</h3>
|
||||
<div class="sub">满 {{ key_alert_max_times }} 次企业微信提醒后自动移入此处;手动删除也会归档。</div>
|
||||
<div class="sub">每种关键位触发后<strong>一次性结案</strong>并写入下方历史:箱体/收敛在计划 RR 达标时<strong>自动市价开仓</strong>;阻力/支撑仅<strong>单次企业微信提醒</strong>。详见项目根目录「关键位自动下单说明.md」。满多次提醒的旧逻辑已不适用。</div>
|
||||
<div class="list">
|
||||
{% for h in key_history %}
|
||||
<div class="list-item">
|
||||
@@ -295,24 +323,71 @@
|
||||
<input id="order-tp-pct" name="tp_pct" type="number" min="0.01" step="0.01" placeholder="止盈%" style="display:none">
|
||||
<button type="submit">开仓(以损定仓)</button>
|
||||
</form>
|
||||
<div class="list">
|
||||
<div class="pos-section">
|
||||
<div class="pos-section-title">实时持仓</div>
|
||||
<div class="pos-list">
|
||||
{% for o in order %}
|
||||
<div class="list-item">
|
||||
<div><strong>{{ o.symbol }}</strong> | <span class="badge direction">{{ '做多' if o.direction == 'long' else '做空' }}</span></div>
|
||||
<div>
|
||||
风格:{{ o.trade_style or 'trend' }} | 风险:{{ o.risk_percent or '-' }}%≈{{ funds_fmt(o.risk_amount) if o.risk_amount is not none else '-' }}U
|
||||
| {% if o.breakeven_enabled %}移动保本:开 {{ o.breakeven_rr_trigger or '-' }}R→{{ price_fmt(o.symbol, o.breakeven_price) }}{% else %}移动保本:关{% endif %}
|
||||
<br>
|
||||
成交:{{ price_fmt(o.symbol, o.trigger_price) }} 止损:{{ price_fmt(o.symbol, o.stop_loss) }} 止盈:{{ price_fmt(o.symbol, o.take_profit) }}
|
||||
| 盈亏比:<span id="order-rr-{{ o.id }}">{% if o.rr_ratio is not none %}1:{{ '%.2f'|format(o.rr_ratio) }}{% else %}-{% endif %}</span>
|
||||
| 现价:<span id="order-price-{{ o.id }}">-</span>
|
||||
| 浮盈亏:<span id="order-pnl-{{ o.id }}">-</span>
|
||||
| 计划基数:{{ funds_fmt(o.margin_capital) if o.margin_capital is not none else '-' }}U | 所保证金:<span id="order-ex-margin-{{ o.id }}">-</span>
|
||||
| 杠杆:{{ o.leverage }}x | 仓位占比:{{ o.position_ratio }}%
|
||||
<div class="pos-card" id="order-row-{{ o.id }}">
|
||||
<div class="pos-card-head">
|
||||
<div class="pos-card-symbol">
|
||||
<strong>{{ o.exchange_symbol or o.symbol }}</strong>
|
||||
<span class="pos-side-badge {{ 'pos-side-long' if o.direction == 'long' else 'pos-side-short' }}">{{ '做多' if o.direction == 'long' else '做空' }}</span>
|
||||
</div>
|
||||
<a href="/del_order/{{ o.id }}" class="pos-close-btn" onclick="return confirm('删除会触发手动平仓,继续?')">平仓</a>
|
||||
</div>
|
||||
<div class="pos-meta">
|
||||
<span class="pos-meta-item">来源: {{ o.monitor_type|default('下单监控', true) }}</span>
|
||||
<span class="pos-meta-item">风格: {{ o.trade_style or 'trend' }}</span>
|
||||
<span class="pos-meta-item">风险: {{ o.risk_percent or '-' }}%≈{{ funds_fmt(o.risk_amount) if o.risk_amount is not none else '-' }}U</span>
|
||||
<span class="pos-meta-item {% if o.breakeven_enabled %}pos-meta-on{% else %}pos-meta-off{% endif %}">
|
||||
{% if o.breakeven_enabled %}移动保本:开 {{ o.breakeven_rr_trigger or '-' }}R→{{ price_fmt(o.symbol, o.breakeven_price) }}{% else %}移动保本:关{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="pos-grid">
|
||||
<div class="pos-cell">
|
||||
<span class="pos-label">成交价</span>
|
||||
<span class="pos-value">{{ price_fmt(o.symbol, o.trigger_price) }}</span>
|
||||
</div>
|
||||
<div class="pos-cell">
|
||||
<span class="pos-label">止损</span>
|
||||
{% if o.stop_loss %}
|
||||
<span class="pos-value">{{ price_fmt(o.symbol, o.stop_loss) }}</span>
|
||||
{% else %}
|
||||
<span class="pos-value pos-val-dash">—</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="pos-cell">
|
||||
<span class="pos-label">止盈</span>
|
||||
{% if o.take_profit %}
|
||||
<span class="pos-value">{{ price_fmt(o.symbol, o.take_profit) }}</span>
|
||||
{% else %}
|
||||
<span class="pos-value pos-val-dash">—</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="pos-cell">
|
||||
<span class="pos-label">盈亏比</span>
|
||||
<span class="pos-value" id="order-rr-{{ o.id }}">{% if o.rr_ratio is not none %}{{ '%g'|format(o.rr_ratio) }}:1{% else %}-:1{% endif %}</span>
|
||||
</div>
|
||||
<div class="pos-cell">
|
||||
<span class="pos-label">标记价</span>
|
||||
<span class="pos-value" id="order-price-{{ o.id }}">-</span>
|
||||
</div>
|
||||
<div class="pos-cell">
|
||||
<span class="pos-label">浮盈亏</span>
|
||||
<span class="pos-value" id="order-pnl-{{ o.id }}">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pos-footer">
|
||||
<span>保证金: <span id="order-ex-margin-{{ o.id }}">-</span></span>
|
||||
<span>计划基数: {{ funds_fmt(o.margin_capital) if o.margin_capital is not none else '-' }}U</span>
|
||||
<span>杠杆: {{ o.leverage or '-' }}x</span>
|
||||
<span>仓位占比: {{ o.position_ratio if o.position_ratio is not none else '-' }}%</span>
|
||||
</div>
|
||||
<a href="/del_order/{{ o.id }}" class="btn-del" onclick="return confirm('删除会触发手动平仓,继续?')">平仓</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="pos-empty">暂无持仓</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -1098,6 +1173,14 @@ function formatSigned(v, digits=2){
|
||||
return `${sign}${n.toFixed(digits)}`;
|
||||
}
|
||||
|
||||
function formatRrRatio(rr){
|
||||
if(rr === null || typeof rr === "undefined") return "-:1";
|
||||
const n = Number(rr);
|
||||
if(Number.isNaN(n)) return "-:1";
|
||||
const body = Number.isInteger(n) ? String(n) : String(parseFloat(n.toFixed(2)));
|
||||
return `${body}:1`;
|
||||
}
|
||||
|
||||
function paintPriceTrend(el, key, value){
|
||||
if(!el) return;
|
||||
const prev = lastPriceMap[key];
|
||||
@@ -1180,7 +1263,7 @@ function refreshPriceSnapshot(){
|
||||
}
|
||||
const rrEl = document.getElementById(`order-rr-${o.id}`);
|
||||
if(rrEl){
|
||||
rrEl.innerText = (typeof o.rr_ratio !== "undefined" && o.rr_ratio !== null) ? `1:${Number(o.rr_ratio).toFixed(2)}` : "-";
|
||||
rrEl.innerText = formatRrRatio(o.rr_ratio);
|
||||
}
|
||||
});
|
||||
}).catch(()=>{});
|
||||
|
||||
Reference in New Issue
Block a user