Initialize crypto_monitor_user (user edition) from monitor codebase.
Retarget git remote, install path, and deploy docs from crypto_monitor to crypto_monitor_user. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
{# 实例数据看板:只读活跃监控总览 #}
|
||||
<div class="card full inst-dash-card" id="instance-dashboard" data-inst-dashboard="1">
|
||||
<div class="inst-dash-head">
|
||||
<div>
|
||||
<h2 style="margin-bottom:4px">数据看板</h2>
|
||||
<p class="muted inst-dash-desc">本户活跃监控总览 · 只读 · 无数据的区块不显示 · 有数据按表格展示</p>
|
||||
</div>
|
||||
<div class="inst-dash-head-actions">
|
||||
<span class="muted inst-dash-updated" id="inst-dash-updated">—</span>
|
||||
<button type="button" class="btn-sm" id="inst-dash-refresh">刷新</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="inst-dash-status muted" id="inst-dash-status"></p>
|
||||
<div class="inst-dash-sections" id="inst-dash-sections"></div>
|
||||
</div>
|
||||
@@ -0,0 +1,28 @@
|
||||
{# 系统设置 · 导航显示开关(SSR 预渲染,保存仍走 API) #}
|
||||
<div class="settings-tab-inner" id="display-prefs-card">
|
||||
<h2>导航显示</h2>
|
||||
<p class="settings-env-hint">以下开关控制顶栏导航与系统设置内区块是否显示,保存后立即生效.关键位监控,实盘下单,系统设置为固定项.</p>
|
||||
<div id="display-prefs-form" class="display-prefs-form" data-prefs-ssr="1">
|
||||
{% if display_meta %}
|
||||
{% for group in display_meta %}
|
||||
<div class="display-prefs-group">
|
||||
<h3 class="settings-subcard-title">{{ group.group }}</h3>
|
||||
<div class="display-prefs-checks">
|
||||
{% for item in group.entries %}
|
||||
<label class="chk-label">
|
||||
<input type="checkbox" data-pref-key="{{ item.key }}"{% if display.get(item.key, true) %} checked{% endif %}>
|
||||
{{ item.label }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="display-prefs-loading muted">加载中…</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="settings-actions-row">
|
||||
<button type="button" class="btn-primary btn-sm" id="display-prefs-save">保存导航设置</button>
|
||||
<span class="settings-status-line" id="display-prefs-status"></span>
|
||||
</div>
|
||||
</div>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,357 @@
|
||||
{# Hub iframe tab fragment — shared via embed_templates #}
|
||||
{% macro period_stats_pane(period_key, s) %}
|
||||
{% set win_pct = s.win_rate_pct if s.win_rate_pct is not none else 0 %}
|
||||
{% set profit_sum = (s.net_pnl_u + s.loss_sum_u) if s.closed_count else 0 %}
|
||||
{% set loss_sum = s.loss_sum_u %}
|
||||
{% set pnl_total = profit_sum + loss_sum %}
|
||||
{% set profit_bar_w = (profit_sum / pnl_total * 100) if pnl_total > 0 else 0 %}
|
||||
{% set loss_bar_w = (loss_sum / pnl_total * 100) if pnl_total > 0 else 0 %}
|
||||
{% set net_cls = 'pos-pnl-profit' if s.net_pnl_u > 0 else ('pos-pnl-loss' if s.net_pnl_u < 0 else '') %}
|
||||
<div class="stats-period-pane" data-stats-period="{{ period_key }}" role="tabpanel"{% if period_key != 'day' %} hidden{% endif %}>
|
||||
<div class="stats-period-range">{{ s.range_label }}</div>
|
||||
<div class="inst-stats-viz">
|
||||
{% if s.closed_count %}
|
||||
<div class="inst-stats-kpis">
|
||||
<div class="inst-stats-kpi inst-stats-kpi--pnl">
|
||||
<span class="inst-stats-kpi-val {{ net_cls }}">{% if s.net_pnl_u > 0 %}+{% endif %}{{ funds_fmt(s.net_pnl_u) }}U</span>
|
||||
<span class="inst-stats-kpi-lbl">净盈亏</span>
|
||||
</div>
|
||||
<div class="inst-stats-kpi inst-stats-kpi--win">
|
||||
<div class="inst-stats-ring" style="--win-pct: {{ win_pct }}">
|
||||
<span class="inst-stats-ring-label">{% if s.win_rate_pct is not none %}{{ win_pct|round(0)|int }}%{% else %}—{% endif %}</span>
|
||||
</div>
|
||||
<span class="inst-stats-kpi-lbl">{{ s.win_count }}胜 {{ s.loss_count }}负</span>
|
||||
</div>
|
||||
<div class="inst-stats-kpi inst-stats-kpi--trades">
|
||||
<span class="inst-stats-kpi-val">{{ s.opens_count }} / {{ s.closed_count }}</span>
|
||||
<span class="inst-stats-kpi-lbl">开单 / 平仓</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inst-stats-block">
|
||||
<div class="inst-stats-block-title">盈亏构成</div>
|
||||
<div class="inst-stats-stacked-bar">
|
||||
<div class="inst-stats-stacked-fill inst-stats-stacked-fill--profit" style="width: {{ '%.1f'|format(profit_bar_w) }}%"></div>
|
||||
<div class="inst-stats-stacked-fill inst-stats-stacked-fill--loss" style="width: {{ '%.1f'|format(loss_bar_w) }}%"></div>
|
||||
</div>
|
||||
<div class="inst-stats-bar-labels">
|
||||
<span class="pos-pnl-profit">盈利 {{ funds_fmt(profit_sum) }}U</span>
|
||||
<span class="pos-pnl-loss">亏损 {{ funds_fmt(loss_sum) }}U</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inst-stats-block inst-stats-block--risk">
|
||||
<div class="inst-stats-risk-grid">
|
||||
<div class="inst-stats-risk-item">
|
||||
<span class="k">最大回撤</span>
|
||||
<span class="v pos-pnl-loss">{{ funds_fmt(s.max_drawdown_u) }}U</span>
|
||||
</div>
|
||||
<div class="inst-stats-risk-item">
|
||||
<span class="k">连续亏损</span>
|
||||
<span class="v">{{ s.consecutive_losses }} 笔</span>
|
||||
</div>
|
||||
<div class="inst-stats-risk-item">
|
||||
<span class="k">最长连亏日</span>
|
||||
<span class="v">{{ s.max_loss_streak_days }} 天</span>
|
||||
</div>
|
||||
<div class="inst-stats-risk-item">
|
||||
<span class="k">最大亏损日</span>
|
||||
<span class="v">{% if s.worst_day %}{{ s.worst_day }} ({{ funds_fmt(s.worst_day_pnl) }}U){% else %}—{% endif %}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="inst-stats-empty">当前区间暂无平仓数据</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<details class="inst-stats-details" open>
|
||||
<summary>详细指标</summary>
|
||||
<div class="stats-detail">
|
||||
<div class="stat-item"><div class="label">开单次数</div><div class="value">{{ s.opens_count }}</div></div>
|
||||
<div class="stat-item"><div class="label">平仓笔数</div><div class="value">{{ s.closed_count }}</div></div>
|
||||
<div class="stat-item"><div class="label">胜率</div><div class="value">{% if s.win_rate_pct is not none %}{{ s.win_rate_pct }}%{% else %}-{% endif %}</div></div>
|
||||
<div class="stat-item"><div class="label">净盈亏(U)</div><div class="value">{{ funds_fmt(s.net_pnl_u) }}</div></div>
|
||||
<div class="stat-item"><div class="label">亏损额合计(U)</div><div class="value">{{ funds_fmt(s.loss_sum_u) }}</div></div>
|
||||
<div class="stat-item"><div class="label">单笔最大亏损(U)</div><div class="value">{% if s.max_single_loss is not none %}{{ funds_fmt(s.max_single_loss) }}{% else %}-{% endif %}</div></div>
|
||||
<div class="stat-item"><div class="label">单笔最大盈利(U)</div><div class="value">{% if s.max_single_profit is not none %}{{ funds_fmt(s.max_single_profit) }}{% else %}-{% endif %}</div></div>
|
||||
<div class="stat-item"><div class="label">最大回撤(U)</div><div class="value">{{ funds_fmt(s.max_drawdown_u) }}</div></div>
|
||||
<div class="stat-item"><div class="label">当前连续亏损笔数</div><div class="value">{{ s.consecutive_losses }}</div></div>
|
||||
<div class="stat-item"><div class="label">最长连续亏损(交易日)</div><div class="value">{{ s.max_loss_streak_days }} 天</div></div>
|
||||
<div class="stat-item"><div class="label">期内最大亏损日</div><div class="value">{% if s.worst_day %}{{ s.worst_day }}({{ funds_fmt(s.worst_day_pnl) }}U){% else %}-{% endif %}</div></div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
<div class="grid">
|
||||
{% if page == 'dashboard' %}
|
||||
{% include 'dashboard_panel.html' %}
|
||||
{% elif page == 'key_monitor' %}
|
||||
{% include 'key_monitor_panel.html' %}
|
||||
{% elif page == 'trade' %}
|
||||
<div class="dual-panel-grid" style="grid-column:1/-1">
|
||||
<div class="card">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin-bottom:8px">
|
||||
<h2 style="margin-bottom:0">实盘下单监控</h2>
|
||||
{% if focus_order_id %}
|
||||
<a href="/order_focus?order_id={{ focus_order_id }}" class="btn-del" style="text-decoration:none;background:#1f3a5a;color:#8fc8ff">放大查看K线(100根)</a>
|
||||
{% else %}
|
||||
<span class="btn-del" style="background:#2f2f44;color:#9aa;cursor:not-allowed">暂无持仓可放大</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include order_rule_tips_tpl %}
|
||||
<form id="add-order-form" action="/add_order" method="post" class="form-row" data-risk-percent="{{ risk_percent }}">
|
||||
{% from 'trade_policy_fields.html' import trade_policy_symbol, trade_policy_direction with context %}
|
||||
{{ trade_policy_symbol('symbol', 'order-symbol') }}
|
||||
{{ trade_policy_direction('direction', 'order-direction') }}
|
||||
<select id="sltp-mode" name="sltp_mode">
|
||||
<option value="fixed_rr" selected>止盈止损:固定盈亏比</option>
|
||||
<option value="price">止盈止损:价格模式</option>
|
||||
<option value="pct">止盈止损:百分比模式</option>
|
||||
</select>
|
||||
{% from 'order_entry_model_fields.html' import order_entry_type_fields with context %}
|
||||
{{ order_entry_type_fields() }}
|
||||
{% from 'order_leverage_fields.html' import order_leverage_fields with context %}
|
||||
{{ order_leverage_fields() }}
|
||||
{% if not intraday_discipline %}
|
||||
<label style="display:flex;align-items:center;gap:4px;font-size:.82rem;color:#cfd3ef">
|
||||
<input type="checkbox" name="breakeven_enabled" value="1" checked> 启用移动保本(关闭则仅保留初始止损与交易所挂单)
|
||||
</label>
|
||||
<span id="order-time-close-wrap" class="order-time-close-wrap" style="display:inline-flex;align-items:center;gap:4px;font-size:.82rem;color:#cfd3ef">
|
||||
<label style="display:inline-flex;align-items:center;gap:4px;margin:0;cursor:pointer">
|
||||
<input type="checkbox" name="time_close_enabled" value="1" id="order-time-close-cb"> 时间平仓
|
||||
</label>
|
||||
<select name="time_close_hours" id="order-time-close-hours" title="持仓满该时长后自动平仓">
|
||||
<option value="1">1h</option>
|
||||
<option value="2">2h</option>
|
||||
<option value="4" selected>4h</option>
|
||||
</select>
|
||||
</span>
|
||||
{% else %}
|
||||
<input type="hidden" name="breakeven_enabled" value="0">
|
||||
{% endif %}
|
||||
<label style="display:flex;align-items:center;gap:4px;font-size:.82rem;color:#cfd3ef">
|
||||
<input type="checkbox" name="order_chart" value="true"> 开仓后生成多周期K线图(各周期100根,含开平仓标记)
|
||||
</label>
|
||||
{% from 'symbol_live_price_snippet.html' import symbol_live_price_hint %}
|
||||
{{ symbol_live_price_hint('order-symbol-live-price', 'order-symbol', 'order-direction') }}
|
||||
<span class="symbol-live-price-note">下单成交价以交易所成交回报为准</span>
|
||||
<input id="order-sl" name="sl" step="any" placeholder="止损价格" required>
|
||||
<input id="order-fixed-rr" name="fixed_rr" type="number" min="0.01" step="0.01" placeholder="盈亏比(默认1.5)" value="1.5" title="止盈距离=止损距离×盈亏比">
|
||||
<input id="order-tp" name="tgt" step="any" placeholder="止盈价格" style="display:none">
|
||||
<input id="order-sl-pct" name="sl_pct" type="number" min="0.01" step="0.01" placeholder="止损%" style="display:none">
|
||||
<input id="order-tp-pct" name="tp_pct" type="number" min="0.01" step="0.01" placeholder="止盈%" style="display:none">
|
||||
<button type="submit">{{ open_position_button_label }}</button>
|
||||
</form>
|
||||
{% include 'order_plan_preview_bar.html' %}
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2 style="margin-bottom:8px">实时持仓</h2>
|
||||
{% if ui_orphan_recovery_enabled %}
|
||||
{% if not order and orphan_live_positions %}
|
||||
{% set o = orphan_live_positions[0] %}
|
||||
<div id="orphan-position-recover" class="orphan-recover-banner" style="display:block;margin-bottom:10px;padding:10px 12px;background:#2a2210;border:1px solid #6b5420;border-radius:6px;font-size:.9rem;color:#e8d5a8">
|
||||
检测到交易所仍有 <strong>{{ o.symbol }}</strong> {{ '空' if o.direction == 'short' else '多' }}仓,但本地监控已中断(误同步时可能无交易记录).
|
||||
{% if o.recoverable_monitor_id %}
|
||||
<button type="button" class="pos-entrust-btn" onclick="recoverLivePosition({{ o.recoverable_monitor_id }})">恢复监控{% if o.plan_stop_loss and o.plan_take_profit %}并挂止盈止损{% endif %}</button>
|
||||
{% else %}
|
||||
未找到可恢复的监控记录,需在服务器数据库处理.
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div id="orphan-position-recover" class="orphan-recover-banner" style="display:none;margin-bottom:10px;padding:10px 12px;background:#2a2210;border:1px solid #6b5420;border-radius:6px;font-size:.9rem;color:#e8d5a8"></div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<div class="panel-scroll pos-list pos-list-live">
|
||||
{% for o in order %}
|
||||
<div class="pos-card" id="order-row-{{ o.id }}"
|
||||
data-monitor-id="{{ o.id }}"
|
||||
data-symbol="{{ o.symbol }}"
|
||||
data-direction="{{ o.direction }}"
|
||||
data-plan-sl="{% if o.stop_loss %}{{ price_fmt(o.symbol, o.stop_loss) }}{% endif %}"
|
||||
data-plan-tp="{% if o.take_profit %}{{ price_fmt(o.symbol, o.take_profit) }}{% endif %}"
|
||||
data-entry="{% if o.trigger_price %}{{ price_fmt(o.symbol, o.trigger_price) }}{% endif %}">
|
||||
<div class="pos-card-head">
|
||||
<div class="pos-card-symbol">
|
||||
<strong>{{ o.exchange_symbol or o.symbol }}</strong>
|
||||
{% if o.time_close_enabled %}
|
||||
<span class="pos-symbol-time-close pos-meta-on pos-time-close-meta" id="order-time-close-wrap-{{ o.id }}"
|
||||
data-close-at-ms="{{ o.time_close_at_ms or '' }}">
|
||||
<span class="pos-time-close-label">时间平仓 {{ o.time_close_hours or '' }}h</span>
|
||||
· <span class="pos-time-close-cd" id="order-time-close-cd-{{ o.id }}">--:--:--</span>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% include 'force_close_order_badge.html' %}
|
||||
<span class="pos-side-badge {{ 'pos-side-long' if o.direction == 'long' else 'pos-side-short' }}">{{ '做多' if o.direction == 'long' else '做空' }}</span>
|
||||
</div>
|
||||
<div class="pos-head-actions">
|
||||
{% if not intraday_discipline %}
|
||||
<button type="button" class="pos-entrust-btn" onclick="openTpslEntrustModal({{ o.id }})">委托</button>
|
||||
<a href="/del_order/{{ o.id }}" class="pos-close-btn" onclick="return confirm('删除会触发手动平仓,继续?')">平仓</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pos-meta">
|
||||
<span class="pos-meta-item">来源: {{ o.monitor_type|default('下单监控', true) }}{% if o.key_signal_type %} · {{ o.key_signal_type }}{% endif %}</span>
|
||||
<span class="pos-meta-item">{% if o.entry_model_label %}开仓: {{ o.entry_model_label }}{% elif intraday_discipline %}开仓: —{% else %}风格: {{ '波段单' if o.trade_style == 'swing' else '趋势单' }}{% endif %}</span>
|
||||
<span class="pos-meta-item">风险: {% if position_sizing_mode == 'full_margin' %}{{ funds_fmt(o.risk_amount) if o.risk_amount is not none else '-' }}U{% else %}{{ o.risk_percent or '-' }}%≈{{ funds_fmt(o.risk_amount) if o.risk_amount is not none else '-' }}U{% endif %}</span>
|
||||
<span class="pos-meta-item" id="order-latest-risk-wrap-{{ o.id }}" style="display:none">最新风险: —</span>
|
||||
<span class="pos-meta-item {% if not intraday_discipline %}{% if o.breakeven_enabled %}pos-meta-on{% else %}pos-meta-off{% endif %}{% endif %}">
|
||||
{% if intraday_discipline %}
|
||||
{% elif o.breakeven_enabled %}移动保本:开 {{ o.breakeven_rr_trigger or '-' }}R→{{ price_fmt(o.symbol, o.breakeven_price) }}{% else %}移动保本:关{% endif %}
|
||||
</span>
|
||||
<span class="pos-meta-item" id="order-be-wrap-{{ o.id }}" style="display:none"><span class="pos-breakeven-badge">已保本</span></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>
|
||||
<span class="pos-value" id="order-plan-sl-{{ o.id }}">{{ price_fmt(o.symbol, o.stop_loss) if o.stop_loss else '—' }}</span>
|
||||
</div>
|
||||
<div class="pos-cell">
|
||||
<span class="pos-label">止盈</span>
|
||||
<span class="pos-value" id="order-plan-tp-{{ o.id }}">{{ price_fmt(o.symbol, o.take_profit) if o.take_profit else '—' }}</span>
|
||||
</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-contracts-{{ o.id }}">{% if o.order_amount is not none %}{{ '%.2f'|format(o.order_amount) }}{% else %}—{% endif %}</span>
|
||||
</div>
|
||||
<div class="pos-cell">
|
||||
<span class="pos-label">盈利金额</span>
|
||||
<span class="pos-value pos-tp-profit" id="order-tp-profit-{{ o.id }}">—</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>
|
||||
<span>开仓时间: {{ (o.opened_at or '-')[:16] }}</span>
|
||||
<span>持仓时长: <span class="order-hold-duration" id="order-hold-duration-{{ o.id }}" data-order-opened-ms="{{ o.opened_at_ms or '' }}">—</span></span>
|
||||
</div>
|
||||
<div class="pos-ex-orders">
|
||||
<div class="pos-ex-orders-title">交易所止盈止损</div>
|
||||
<div class="pos-ex-order-row">
|
||||
<span class="pos-ex-order-main" id="ex-sl-text-{{ o.id }}">止损:加载中…</span>
|
||||
{% if not intraday_discipline %}
|
||||
<button type="button" class="pos-ex-cancel-btn" id="ex-sl-cancel-{{ o.id }}" disabled onclick="cancelExchangeTpsl({{ o.id }}, 'sl')">撤单</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="pos-ex-order-row">
|
||||
<span class="pos-ex-order-main" id="ex-tp-text-{{ o.id }}">止盈:加载中…</span>
|
||||
{% if not intraday_discipline %}
|
||||
<button type="button" class="pos-ex-cancel-btn" id="ex-tp-cancel-{{ o.id }}" disabled onclick="cancelExchangeTpsl({{ o.id }}, 'tp')">撤单</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="pos-empty">暂无持仓</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tpsl-modal" class="tpsl-modal-backdrop" onclick="if(event.target===this)closeTpslEntrustModal()">
|
||||
<div class="tpsl-modal" onclick="event.stopPropagation()">
|
||||
<h3 id="tpsl-modal-title">挂止盈止损</h3>
|
||||
<p style="font-size:.78rem;color:#8892b0;margin:0 0 10px">将先撤销该合约已有 TP/SL,再按下列价格重挂.</p>
|
||||
<div class="form-row">
|
||||
<select id="tpsl-modal-mode" onchange="toggleTpslModalMode()">
|
||||
<option value="price">价格模式</option>
|
||||
<option value="pct">百分比模式</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input id="tpsl-modal-sl" step="any" placeholder="止损价格">
|
||||
<input id="tpsl-modal-tp" step="any" placeholder="止盈价格">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input id="tpsl-modal-sl-pct" type="number" min="0.01" step="0.01" placeholder="止损%" style="display:none">
|
||||
<input id="tpsl-modal-tp-pct" type="number" min="0.01" step="0.01" placeholder="止盈%" style="display:none">
|
||||
</div>
|
||||
<div class="tpsl-modal-actions">
|
||||
<button type="button" class="tpsl-modal-cancel" onclick="closeTpslEntrustModal()">取消</button>
|
||||
<button type="button" class="tpsl-modal-submit" onclick="submitTpslEntrust()">先撤后挂</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% elif page in ('strategy', 'strategy_trend', 'strategy_roll') %}
|
||||
{% include 'strategy_trading_page.html' %}
|
||||
{% elif page == 'strategy_records' %}
|
||||
{% include 'strategy_records_page.html' %}
|
||||
{% elif page == 'options' %}
|
||||
{% include 'options_panel.html' %}
|
||||
{% elif page == 'options_review' %}
|
||||
{% include 'options_review_panel.html' %}
|
||||
{% elif page == 'hedge_plan' %}
|
||||
{% include 'hedge_plan_panel.html' %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
{% if page == 'records' %}
|
||||
{% include 'records_panel.html' %}
|
||||
{% endif %}
|
||||
{% if page == 'env_config' %}
|
||||
{% include 'env_config_panel.html' %}
|
||||
{% endif %}
|
||||
|
||||
{% if page == 'risk_policy' %}
|
||||
{% include 'risk_policy_panel.html' %}
|
||||
{% endif %}
|
||||
|
||||
{% if page == 'settings' %}
|
||||
{% include 'settings_panel.html' %}
|
||||
{% endif %}
|
||||
|
||||
{% if page == 'stats' %}
|
||||
<div class="card stats-card full" id="stats-card">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap">
|
||||
<h2 style="margin-bottom:0">数据统计</h2>
|
||||
<button type="button" class="stats-toggle" id="stats-toggle-btn" onclick="toggleStatsCard()">折叠</button>
|
||||
</div>
|
||||
<div class="stats-content" id="stats-content">
|
||||
<div class="sub" style="margin-bottom:12px;color:#8892b0;font-size:.82rem">
|
||||
统计分析按<strong>北京时间 {{ stats_bundle.stats_reset_hour }}:00</strong>切日计入(与顶栏 UTC 列表窗无关).历史总开仓(累计):
|
||||
<strong style="color:#cfd3ef">{{ stats_bundle.total_opens_all }}</strong> 次
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:14px;align-items:center">
|
||||
<label style="display:flex;align-items:center;gap:8px;font-size:.88rem;color:#cfd3ef">
|
||||
统计品类
|
||||
<select id="stats-segment-select" onchange="switchStatsSegment()" style="min-width:200px">
|
||||
{% for seg in stats_bundle.segments %}
|
||||
<option value="{{ seg.key }}">{{ seg.title }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
{% for seg in stats_bundle.segments %}
|
||||
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
||||
<div class="stats-period-tabs" role="tablist" aria-label="统计周期">
|
||||
<button type="button" class="stats-period-tab active" data-stats-period="day" role="tab" aria-selected="true" onclick="switchStatsPeriod('day')">日统计</button>
|
||||
<button type="button" class="stats-period-tab" data-stats-period="week" role="tab" aria-selected="false" onclick="switchStatsPeriod('week')">周统计</button>
|
||||
<button type="button" class="stats-period-tab" data-stats-period="month" role="tab" aria-selected="false" onclick="switchStatsPeriod('month')">月统计</button>
|
||||
</div>
|
||||
{{ period_stats_pane("day", seg.day) }}
|
||||
{{ period_stats_pane("week", seg.week) }}
|
||||
{{ period_stats_pane("month", seg.month) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -0,0 +1,122 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" data-theme="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<script src="/static/instance_theme.js?v=50"></script>
|
||||
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
||||
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
|
||||
<link rel="stylesheet" href="/static/instance_page.css?v=9">
|
||||
<link rel="stylesheet" href="/static/instance_theme.css?v=97">
|
||||
<script src="/static/account_risk_badge.js?v=4"></script>
|
||||
<meta name="theme-color" content="#0b0d14">
|
||||
<title>{{ pwa_app_name }}</title>
|
||||
</head>
|
||||
<body
|
||||
data-embed-shell="1"
|
||||
data-intraday-discipline="{% if intraday_discipline %}1{% else %}0{% endif %}"
|
||||
data-risk-percent="{{ risk_percent }}"
|
||||
data-page="{{ initial_tab }}"
|
||||
data-position-sizing-mode="{{ position_sizing_mode }}"
|
||||
data-btc-leverage="{{ btc_leverage }}"
|
||||
data-alt-leverage="{{ alt_leverage }}"
|
||||
data-full-margin-buffer="{{ full_margin_buffer_ratio }}"
|
||||
data-balance-refresh-ms="{{ balance_refresh_seconds * 1000 }}"
|
||||
data-price-refresh-ms="{{ price_refresh_seconds * 1000 }}"
|
||||
>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>加密货币|交易监控 + AI复盘一体化</h1>
|
||||
</div>
|
||||
<nav class="top-nav embed-top-nav" aria-label="实例导航">
|
||||
<a href="/dashboard" data-embed-tab="dashboard" class="{% if initial_tab == 'dashboard' %}active{% endif %}"{% if not display.show_nav_dashboard %} style="display:none"{% endif %}>数据看板</a>
|
||||
<a href="/key_monitor" data-embed-tab="key_monitor" class="{% if initial_tab == 'key_monitor' %}active{% endif %}">关键位监控</a>
|
||||
<a href="/trade" data-embed-tab="trade" class="{% if initial_tab == 'trade' %}active{% endif %}">实盘下单</a>
|
||||
{% if not intraday_discipline and display.show_nav_strategy %}
|
||||
<a href="/strategy" data-embed-tab="strategy" class="{% if initial_tab == 'strategy' %}active{% endif %}">策略交易</a>
|
||||
{% endif %}
|
||||
{% if not intraday_discipline and display.show_nav_strategy_records %}
|
||||
<a href="/strategy/records" data-embed-tab="strategy_records" class="{% if initial_tab == 'strategy_records' %}active{% endif %}">策略交易记录</a>
|
||||
{% endif %}
|
||||
{% if display.show_nav_records %}
|
||||
<a href="/records" data-embed-tab="records" class="{% if initial_tab == 'records' %}active{% endif %}">交易记录与复盘</a>
|
||||
{% endif %}
|
||||
{% if display.show_nav_stats %}
|
||||
<a href="/stats" data-embed-tab="stats" class="{% if initial_tab == 'stats' %}active{% endif %}">统计分析</a>
|
||||
{% endif %}
|
||||
{% if options_nav_visible and display.show_nav_options %}
|
||||
<a href="/options" data-embed-tab="options" class="{% if initial_tab == 'options' %}active{% endif %}">期权</a>
|
||||
{% endif %}
|
||||
{% if options_nav_visible and display.show_nav_options_review %}
|
||||
<a href="/options/review" data-embed-tab="options_review" class="{% if initial_tab == 'options_review' %}active{% endif %}">期权复盘</a>
|
||||
{% endif %}
|
||||
{% if hedge_plan_nav_visible and display.show_nav_hedge_plan %}
|
||||
<a href="/hedge-plan" data-embed-tab="hedge_plan" class="{% if initial_tab == 'hedge_plan' %}active{% endif %}">对冲计划</a>
|
||||
{% endif %}
|
||||
{% if display.show_nav_risk_policy %}
|
||||
<a href="/risk_policy" data-embed-tab="risk_policy" class="{% if initial_tab == 'risk_policy' %}active{% endif %}">风控说明</a>
|
||||
{% endif %}
|
||||
{% if display.show_nav_env_config %}
|
||||
<a href="/env_config" data-embed-tab="env_config" class="{% if initial_tab == 'env_config' %}active{% endif %}">env配置</a>
|
||||
{% endif %}
|
||||
<a href="/settings" data-embed-tab="settings" class="{% if initial_tab == 'settings' %}active{% endif %}">系统设置</a>
|
||||
</nav>
|
||||
<div id="embed-flash" class="flash" style="display:none" role="status"></div>
|
||||
|
||||
{% include 'instance_header_panel.html' %}
|
||||
{% if initial_tab not in ('settings', 'risk_policy', 'env_config') and include_transfer_block %}
|
||||
{% include 'instance_top_bar.html' %}
|
||||
{% endif %}
|
||||
|
||||
<div id="embed-page-root">
|
||||
{% include 'embed_page_fragment.html' %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="imgModal" onclick="closeModal()">
|
||||
<img id="bigImg" src="" alt="screenshot">
|
||||
</div>
|
||||
<div class="detail-modal" id="detailModal" onclick="closeDetailModal(event)">
|
||||
<div class="panel" onclick="event.stopPropagation()">
|
||||
<div class="panel-head">
|
||||
<div class="panel-title" id="detailTitle">详情</div>
|
||||
<div class="panel-actions">
|
||||
<button type="button" class="panel-fs" onclick="expandDetailToFullscreen()">全屏</button>
|
||||
<button type="button" class="panel-close" onclick="forceCloseDetailModal()">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body" id="detailBody"></div>
|
||||
<div id="detailImages" class="journal-detail-images" style="display:none"></div>
|
||||
<img id="detailImage" class="panel-image" src="" alt="detail-image" style="display:none" onclick="showImage(this.src)">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/instance_ui.js?v=10"></script>
|
||||
<script src="/static/journal_upload_slots.js?v=3"></script>
|
||||
<script src="/static/instance_records_mobile.js?v=2"></script>
|
||||
<script src="/static/time_close_ui.js?v=3"></script>
|
||||
<script src="/static/ai_review_render.js?v=2"></script>
|
||||
<script src="/static/form_submit_guard.js?v=2"></script>
|
||||
<script>
|
||||
const ORDER_ENTRY_MODEL_TRADE_STYLE = {{ entry_model_trade_style_map | tojson }};
|
||||
const ORDER_ENTRY_MODEL_CATEGORIES = {{ entry_model_categories | tojson }};
|
||||
const ORDER_ENTRY_MODEL_CODE_TO_CATEGORY = {{ entry_model_code_to_category | tojson }};
|
||||
</script>
|
||||
<script src="/static/order_entry_model.js?v=5"></script>
|
||||
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
||||
<script src="/static/symbol_live_price.js?v=2"></script>
|
||||
<script src="/static/strategy_roll.js?v=6"></script>
|
||||
<script src="/static/key_monitor_form.js?v=2"></script>
|
||||
<script src="/static/instance_stats.js?v=4"></script>
|
||||
{% include 'embed_boot_scripts.html' %}
|
||||
<script src="/static/records_review_page.js?v=2"></script>
|
||||
<script src="/static/options_expiry_countdown.js?v=1"></script>
|
||||
<script src="/static/instance_dashboard.js?v=3"></script>
|
||||
<script>
|
||||
window.__INSTANCE_DISPLAY__ = {{ display | tojson }};
|
||||
</script>
|
||||
<script src="/static/instance_settings_prefs.js?v=14"></script>
|
||||
<script src="/static/instance_live.js?v=6"></script>
|
||||
<script src="/static/instance_embed.js?v=25"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,83 @@
|
||||
{# env配置:CSS Tab(无需 JS)+ 双列表单 #}
|
||||
<div class="env-config-page full">
|
||||
<div class="env-config-head card">
|
||||
<div class="env-config-head-row">
|
||||
<div>
|
||||
<h2>env 配置</h2>
|
||||
<p class="settings-env-hint env-config-head-hint">按分类修改,改完点保存.含「需重启」的项请用「保存并重启」.<strong>AI 配置</strong>请在中控 → 系统设置 → AI 配置统一维护.</p>
|
||||
</div>
|
||||
<div class="env-config-toolbar">
|
||||
<button type="button" class="btn-primary btn-sm" id="env-config-save">保存</button>
|
||||
<button type="button" class="btn-secondary btn-sm" id="env-config-save-restart">保存并重启</button>
|
||||
<button type="button" class="btn-secondary btn-sm" id="env-config-reload">重新加载</button>
|
||||
</div>
|
||||
</div>
|
||||
<span class="settings-status-line" id="env-config-status"></span>
|
||||
</div>
|
||||
|
||||
{% if env_config_groups %}
|
||||
<div class="env-config-body card" data-env-ssr="1" id="env-config-body">
|
||||
{% for group in env_config_groups %}
|
||||
<input type="radio" name="env-section" id="env-sec-{{ loop.index0 }}" class="env-tab-radio"{% if loop.first %} checked{% endif %}>
|
||||
{% endfor %}
|
||||
<div class="env-config-tabs" role="tablist" aria-label="配置分类">
|
||||
{% for group in env_config_groups %}
|
||||
<label for="env-sec-{{ loop.index0 }}" class="env-tab-btn" role="tab">{{ group.title }}</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="env-config-panels" id="env-config-grid">
|
||||
{% for group in env_config_groups %}
|
||||
<section class="env-panel env-panel--{{ loop.index0 }}" role="tabpanel">
|
||||
{% if group.has_restart %}
|
||||
<p class="env-panel-hint">本组含需重启项,修改后请点「保存并重启」.</p>
|
||||
{% endif %}
|
||||
<div class="env-form-grid">
|
||||
{% for field in group.fields %}
|
||||
<div class="env-field-row{% if field.restart_required %} env-field-row--restart{% endif %}">
|
||||
<label class="env-field-label" for="env-f-{{ field.key }}">
|
||||
{{ field.label or field.key }}
|
||||
{% if field.restart_required %}<span class="env-restart-mark" title="需重启">*</span>{% endif %}
|
||||
</label>
|
||||
{% if field.note %}
|
||||
<div class="env-field-note muted">{{ field.note }}</div>
|
||||
{% endif %}
|
||||
{% if field.type == 'bool' %}
|
||||
<select class="env-field-input" id="env-f-{{ field.key }}" data-env-key="{{ field.key }}">
|
||||
{% set cur = (field.current or field.default or 'false')|lower %}
|
||||
<option value="true"{% if cur in ('true', '1', 'yes', 'on') %} selected{% endif %}>开启</option>
|
||||
<option value="false"{% if cur not in ('true', '1', 'yes', 'on') %} selected{% endif %}>关闭</option>
|
||||
</select>
|
||||
{% elif field.sensitive %}
|
||||
{% if field.has_value %}
|
||||
<div class="env-sensitive-current muted">已配置 <span class="env-masked-value">{{ field.masked }}</span></div>
|
||||
{% endif %}
|
||||
<input
|
||||
class="env-field-input"
|
||||
id="env-f-{{ field.key }}"
|
||||
type="password"
|
||||
data-env-key="{{ field.key }}"
|
||||
placeholder="{% if field.has_value %}修改时填写新值,留空不修改{% else %}请输入{% endif %}"
|
||||
autocomplete="off"
|
||||
>
|
||||
{% else %}
|
||||
<input
|
||||
class="env-field-input"
|
||||
id="env-f-{{ field.key }}"
|
||||
type="text"
|
||||
data-env-key="{{ field.key }}"
|
||||
value="{{ field.current or field.default or '' }}"
|
||||
>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div id="env-config-grid" class="env-config-loading-wrap card">
|
||||
<div class="env-config-loading muted">加载配置中…</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
{% if force_close.enabled %}
|
||||
<span class="force-close-badge" id="force-close-header-badge" role="status"
|
||||
title="北京时间 {{ force_close.hour_label }} 整点未平仓将市价强制清仓(result=强制清仓)"
|
||||
data-force-close-at-ms="{{ force_close.next_at_ms or '' }}"
|
||||
data-force-close-active="{{ '1' if force_close.active else '0' }}">
|
||||
{{ force_close.label }} 已开启 · <span class="force-close-header-cd">{{ force_close.countdown or '--:--:--' }}</span>
|
||||
</span>
|
||||
{% endif %}
|
||||
@@ -0,0 +1,8 @@
|
||||
{% if force_close.enabled %}
|
||||
<span class="pos-symbol-force-close pos-force-close-meta" id="order-force-close-wrap-{{ o.id }}"
|
||||
data-force-close-at-ms="{{ o.force_close_at_ms or force_close.next_at_ms or '' }}"
|
||||
data-force-close-active="{{ '1' if (o.force_close_active or force_close.active) else '0' }}">
|
||||
<span class="pos-force-close-label">{{ o.force_close_label or force_close.label }}</span>
|
||||
· <span class="pos-force-close-cd" id="order-force-close-cd-{{ o.id }}">{{ o.force_close_countdown or force_close.countdown or '--:--:--' }}</span>
|
||||
</span>
|
||||
{% endif %}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
{# 统一顶栏:状态 + 筛选(上)· 统计条(下) #}
|
||||
<div class="instance-header-panel card">
|
||||
<div class="instance-header-toolbar">
|
||||
<div class="instance-header-toolbar-filter">
|
||||
<span class="list-window-label" title="列表按 UTC 时间筛选,默认本月">UTC {{ list_window.label }}</span>
|
||||
<label class="list-window-preset">预设
|
||||
<select id="win-preset-select" onchange="toggleListWindowCustom()">
|
||||
<option value="utc_this_month" {% if list_window.preset == 'utc_this_month' %}selected{% endif %}>本月</option>
|
||||
<option value="utc_last3m" {% if list_window.preset == 'utc_last3m' %}selected{% endif %}>近3月</option>
|
||||
<option value="utc_last6m" {% if list_window.preset == 'utc_last6m' %}selected{% endif %}>近6月</option>
|
||||
<option value="all" {% if list_window.preset == 'all' %}selected{% endif %}>全部</option>
|
||||
<option value="utc_today" {% if list_window.preset == 'utc_today' %}selected{% endif %}>UTC 当日</option>
|
||||
<option value="utc_last24h" {% if list_window.preset == 'utc_last24h' %}selected{% endif %}>近 24 小时</option>
|
||||
<option value="utc_last7d" {% if list_window.preset == 'utc_last7d' %}selected{% endif %}>近 7 天</option>
|
||||
<option value="custom" {% if list_window.preset == 'custom' %}selected{% endif %}>自定义</option>
|
||||
</select>
|
||||
</label>
|
||||
<span id="win-custom-range" class="list-window-custom" style="{% if list_window.preset != 'custom' %}display:none{% endif %}">
|
||||
<label>起 <input type="datetime-local" id="win-from-utc" value="{{ list_window.start_utc.strftime('%Y-%m-%dT%H:%M') }}"></label>
|
||||
<label>止 <input type="datetime-local" id="win-to-utc" value="{{ list_window.end_utc.strftime('%Y-%m-%dT%H:%M') }}"></label>
|
||||
</span>
|
||||
<button type="button" class="list-window-apply" onclick="applyListWindow()">应用</button>
|
||||
<span class="list-window-hint" title="统计分析页按北京时间 {{ stats_bundle.stats_reset_hour|default(reset_hour) }}:00 切交易日">统计切日 {{ stats_bundle.stats_reset_hour|default(reset_hour) }}:00</span>
|
||||
</div>
|
||||
<div class="instance-header-toolbar-end">
|
||||
<div class="instance-toolbar-status">
|
||||
<div class="exchange-tag">{{ exchange_display }}</div>
|
||||
{% if trade_policy.badge_text %}
|
||||
<span class="trade-policy-badge" title="账户交易限制(.env)">{{ trade_policy.badge_text }}</span>
|
||||
{% endif %}
|
||||
{% include 'force_close_header_badge.html' %}
|
||||
<span class="risk-status-badge risk-status-{{ risk_status.status|default('normal') }}" id="account-risk-badge" role="status" title="{{ risk_status.reason|default('', true) }}" data-status-label="{{ risk_status.status_label|default('正常') }}"{% if risk_status.freeze_until_ms %} data-freeze-until-ms="{{ risk_status.freeze_until_ms }}"{% endif %}>{{ risk_status.status_label|default('正常') }}</span>
|
||||
</div>
|
||||
{% include 'instance_theme_toggle.html' %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="instance-header-stats-wrap instance-desktop-only">
|
||||
{% include 'instance_header_stats.html' %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,49 @@
|
||||
{# 资金与统计条(顶栏 / 系统设置共用,单行展示) #}
|
||||
<div class="instance-header-stats{% if options_enabled %} instance-header-stats--options{% endif %}">
|
||||
<div class="stat-strip-item stat-strip-item--primary">
|
||||
<div class="label">交易所</div>
|
||||
<div class="value">{{ exchange_display }}</div>
|
||||
</div>
|
||||
<div class="stat-strip-item">
|
||||
<div class="label">交易日</div>
|
||||
<div class="value">{{ trading_day }}</div>
|
||||
</div>
|
||||
<div class="stat-strip-item stat-strip-item--primary">
|
||||
<div class="label">总交易</div>
|
||||
<div class="value" id="stat-total" data-funds-field="stat-total">{{ total }}</div>
|
||||
</div>
|
||||
<div class="stat-strip-item">
|
||||
<div class="label">胜率</div>
|
||||
<div class="value" id="stat-rate" data-funds-field="stat-rate">{{ rate }}%</div>
|
||||
</div>
|
||||
<div class="stat-strip-item" title="平均盈利 ÷ 平均亏损(当前列表窗口)">
|
||||
<div class="label">盈亏比</div>
|
||||
<div class="value" id="stat-pl-ratio" data-funds-field="stat-pl-ratio">{% if profit_loss_ratio is not none %}{{ profit_loss_ratio }}{% else %}—{% endif %}</div>
|
||||
</div>
|
||||
<div class="stat-strip-item">
|
||||
<div class="label">总资金</div>
|
||||
<div class="value" id="total-funds" data-funds-field="total-funds">{% if total_funds is not none %}{{ funds_fmt(total_funds) }}U{% else %}—{% endif %}</div>
|
||||
</div>
|
||||
<div class="stat-strip-item">
|
||||
<div class="label">资金账户</div>
|
||||
<div class="value" id="total-capital" data-funds-field="total-capital">{% if funding_usdt is not none %}{{ funds_fmt(funding_usdt) }}U{% else %}—{% endif %}</div>
|
||||
</div>
|
||||
<div class="stat-strip-item">
|
||||
<div class="label">交易账户</div>
|
||||
<div class="value" id="current-capital" data-funds-field="current-capital">{{ funds_fmt(current_capital) }}U</div>
|
||||
</div>
|
||||
{% if options_enabled %}
|
||||
<div class="stat-strip-item">
|
||||
<div class="label">期权资金账户</div>
|
||||
<div class="value" id="options-funding-usdc" data-funds-field="options-funding-usdc">{{ options_funding_label(options_funding_usdc, options_funding_usdt) }}</div>
|
||||
</div>
|
||||
<div class="stat-strip-item">
|
||||
<div class="label">期权交易账户</div>
|
||||
<div class="value" id="options-trading-usdc" data-funds-field="options-trading-usdc">{{ options_funding_label(options_trading_usdc, options_trading_usdt) }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="stat-strip-item stat-strip-item--pnl">
|
||||
<div class="label">实时盈亏</div>
|
||||
<div class="value" id="realtime-pnl" data-funds-field="realtime-pnl">—</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class="theme-toggle instance-theme-toggle" role="group" aria-label="界面主题">
|
||||
<button type="button" class="theme-toggle-btn is-active" data-theme-value="dark" aria-pressed="true" title="暗色主题">
|
||||
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
|
||||
<path fill="currentColor" d="M12.1 3a9 9 0 1 0 8.9 11 6.5 6.5 0 1 1-8.9-11z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" class="theme-toggle-btn" data-theme-value="light" aria-pressed="false" title="亮色主题">
|
||||
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
{# 三所统一顶栏:实时价 + 可选整点前开仓开关(划转已移至系统设置) #}
|
||||
<div class="rule-tip instance-price-bar">
|
||||
实时价格更新:<span id="price-last-updated">--</span>(北京时间 UTC+8)
|
||||
</div>
|
||||
{% if ui_open_guard_enabled %}
|
||||
<div class="rule-tip" id="open-guard-bar" style="display:flex;align-items:center;gap:10px;flex-wrap:wrap">
|
||||
<label style="display:flex;align-items:center;gap:6px;cursor:pointer;color:#cfd3ef">
|
||||
<input type="checkbox" id="allow-open-before-reset" {% if not open_guard_enabled %}checked{% endif %}>
|
||||
允许北京时间 {{ reset_hour }}:00 前开仓(斐波成交登记,人工下单)
|
||||
</label>
|
||||
<span id="open-guard-status" style="color:#8892b0;font-size:.75rem">
|
||||
{% if open_guard_enabled %}已限制:{{ reset_hour }}:00 前不可开仓{% else %}已放开:{{ reset_hour }}:00 前允许开仓{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -0,0 +1,25 @@
|
||||
{# 系统设置 · 资金划转(三所共用) #}
|
||||
<div class="settings-transfer-panel">
|
||||
<p class="rule-tip settings-transfer-auto">
|
||||
自动划转 <strong>{{ '开启' if auto_transfer_enabled else '关闭' }}</strong>:
|
||||
每天<strong>北京时间 {{ auto_transfer_bj_hour }}:00</strong> 起该整点小时内尝试;
|
||||
账簿按 <strong>UTC 自然日</strong> 去重;
|
||||
将 <code>{{ auto_transfer_to }}</code> 调整至 <strong>{{ transfer_amount_fmt|default(funds_fmt(auto_transfer_amount)) }}U</strong>:
|
||||
不足从 <code>{{ auto_transfer_from }}</code> 划入,超出划回 <code>{{ auto_transfer_from }}</code>;
|
||||
<strong>持仓中不划转</strong>并微信通知.
|
||||
</p>
|
||||
<form action="/manual_transfer" method="post" class="form-row gate-transfer-form settings-transfer-form">
|
||||
<input name="amount" type="number" min="0.01" step="0.01" placeholder="手动划转金额 U" required>
|
||||
<select name="from_account" aria-label="划出账户">
|
||||
<option value="funding" {% if auto_transfer_from == 'funding' %}selected{% endif %}>from: funding</option>
|
||||
<option value="swap" {% if auto_transfer_from == 'swap' %}selected{% endif %}>from: swap</option>
|
||||
<option value="spot" {% if auto_transfer_from == 'spot' %}selected{% endif %}>from: spot</option>
|
||||
</select>
|
||||
<select name="to_account" aria-label="划入账户">
|
||||
<option value="swap" {% if auto_transfer_to == 'swap' %}selected{% endif %}>to: swap</option>
|
||||
<option value="funding" {% if auto_transfer_to == 'funding' %}selected{% endif %}>to: funding</option>
|
||||
<option value="spot" {% if auto_transfer_to == 'spot' %}selected{% endif %}>to: spot</option>
|
||||
</select>
|
||||
<button type="submit">执行手动划转</button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,150 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" data-theme="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<script src="/static/instance_theme.js?v=4"></script>
|
||||
<meta name="theme-color" content="#0b0d14">
|
||||
<meta name="apple-mobile-web-app-title" content="{{ pwa_app_name }}">
|
||||
<link rel="icon" href="/static/icons/favicon.ico" sizes="32x32">
|
||||
<link rel="icon" href="/static/icons/icon.svg" type="image/svg+xml">
|
||||
<link rel="apple-touch-icon" href="/static/icons/apple-touch-icon.png">
|
||||
<link rel="manifest" href="/static/icons/manifest.webmanifest">
|
||||
<title>登录 · {{ pwa_app_name }}</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
background: #0a0a10;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
padding: 24px;
|
||||
color: #fff;
|
||||
}
|
||||
.login-theme-bar {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
.login-box {
|
||||
background: #12121a;
|
||||
padding: 2.5rem;
|
||||
border-radius: 16px;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
border: 1px solid #242435;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.3);
|
||||
}
|
||||
.login-box h2 {
|
||||
margin-bottom: 0.75rem;
|
||||
text-align: center;
|
||||
font-size: 1.5rem;
|
||||
background: linear-gradient(90deg, #4cc2ff, #7b42ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
color: #a9a9ff;
|
||||
}
|
||||
.form-group input {
|
||||
width: 100%;
|
||||
padding: 0.85rem 1rem;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #2e2e45;
|
||||
background: #1a1a29;
|
||||
color: #fff;
|
||||
font-size: 0.95rem;
|
||||
outline: none;
|
||||
}
|
||||
.form-group input:focus {
|
||||
border-color: #4cc2ff;
|
||||
}
|
||||
.login-box > form > button {
|
||||
width: 100%;
|
||||
padding: 0.9rem;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
background: linear-gradient(90deg, #4285f4, #7b42ff);
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
.login-box > form > button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.flash {
|
||||
padding: 0.8rem;
|
||||
margin-bottom: 1rem;
|
||||
background: #331e24;
|
||||
color: #ff6666;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.exchange-line {
|
||||
text-align: center;
|
||||
font-size: 0.82rem;
|
||||
color: #8892b0;
|
||||
margin: 0 0 1.5rem;
|
||||
}
|
||||
.exchange-line strong {
|
||||
color: #b8f5d0;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/static/instance_theme.css?v=5">
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-theme-bar">
|
||||
<div class="theme-toggle instance-theme-toggle" role="group" aria-label="界面主题">
|
||||
<button type="button" class="theme-toggle-btn is-active" data-theme-value="dark" aria-pressed="true" title="暗色主题">
|
||||
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
|
||||
<path fill="currentColor" d="M12.1 3a9 9 0 1 0 8.9 11 6.5 6.5 0 1 1-8.9-11z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" class="theme-toggle-btn" data-theme-value="light" aria-pressed="false" title="亮色主题">
|
||||
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="login-box">
|
||||
<h2>{{ pwa_app_name }}</h2>
|
||||
<p class="exchange-line">登录 · <strong>{{ exchange_display }}</strong></p>
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{% if messages %}
|
||||
<div class="flash">{{ messages[0] }}</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<form method="POST" autocomplete="off">
|
||||
<div class="form-group">
|
||||
<label>账号</label>
|
||||
<input type="text" name="username" required placeholder="请输入账号" autocomplete="off" autocapitalize="off" spellcheck="false">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>密码</label>
|
||||
<input type="password" name="password" required placeholder="请输入密码" autocomplete="new-password">
|
||||
</div>
|
||||
<button type="submit">登录</button>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,72 @@
|
||||
{# 趋势户:两级开仓类型 → 自动 trade_style;日内户:假破 / 结构突破 #}
|
||||
|
||||
{% macro order_entry_type_fields() -%}
|
||||
|
||||
{% if order_entry_profile == 'trend_div' %}
|
||||
|
||||
<div class="order-entry-model-row">
|
||||
|
||||
<select id="order-entry-category" class="order-entry-category" required title="反转 / 顺势 / 波段" aria-label="开仓性质">
|
||||
|
||||
<option value="">性质</option>
|
||||
|
||||
{% for cat in entry_model_categories %}
|
||||
|
||||
<option value="{{ cat.key }}">{{ cat.label }}</option>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
</select>
|
||||
|
||||
<select name="entry_model" id="order-entry-model" class="order-entry-model-sub" required disabled title="启动A/B,大分歧A/B,小分歧" aria-label="开仓类型">
|
||||
|
||||
<option value="">类型</option>
|
||||
|
||||
{% for cat in entry_model_categories %}
|
||||
|
||||
{% for opt in cat.options %}
|
||||
|
||||
<option value="{{ opt.code }}" data-entry-category="{{ cat.key }}" data-trade-style="{{ opt.trade_style }}"{% if opt.help %} title="{{ opt.help }}"{% endif %} hidden disabled>{{ opt.label }}</option>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
</select>
|
||||
|
||||
<input type="hidden" name="trade_style" id="order-trade-style-hidden" value="trend">
|
||||
|
||||
<span id="order-trade-style-hint" class="order-trade-style-hint" title="由开仓类型自动设定">趋势单</span>
|
||||
|
||||
</div>
|
||||
|
||||
{% elif order_entry_profile == 'intraday' %}
|
||||
|
||||
<select name="entry_model" id="order-entry-model" class="order-entry-intraday" required title="日内开仓类型" aria-label="开仓类型">
|
||||
|
||||
<option value="">开仓类型</option>
|
||||
|
||||
{% for opt in intraday_entry_model_options %}
|
||||
|
||||
<option value="{{ opt.code }}"{% if opt.help %} title="{{ opt.help }}"{% endif %}>{{ opt.label }}</option>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
</select>
|
||||
|
||||
<input type="hidden" name="trade_style" value="trend">
|
||||
|
||||
{% else %}
|
||||
|
||||
<select name="trade_style" required>
|
||||
|
||||
<option value="trend">趋势单</option>
|
||||
|
||||
<option value="swing">波段单</option>
|
||||
|
||||
</select>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{%- endmacro %}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{# 以损定仓:杠杆按币种默认(BTC/ETH 10x,其它 5x),不可选手输 #}
|
||||
{% macro order_leverage_fields() -%}
|
||||
{% if position_sizing_mode != 'full_margin' %}
|
||||
<input type="hidden" id="order-leverage" name="leverage" value="">
|
||||
<span id="order-leverage-hint" class="order-leverage-hint" title="BTC/ETH 默认10x,其它默认5x">杠杆 —</span>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
@@ -0,0 +1,13 @@
|
||||
{# 系统设置 · 账户密码(外层 card 由 settings_panel 提供) #}
|
||||
<h2>账户密码修改</h2>
|
||||
<p class="settings-subcard-desc">修改网页登录账号密码,写入 <code>.env</code> 后需重启实例生效.</p>
|
||||
<div class="settings-password-form">
|
||||
<label>当前密码 <input type="password" id="pwd-old" autocomplete="current-password"></label>
|
||||
<label>新用户名(可选) <input type="text" id="pwd-new-username" autocomplete="username"></label>
|
||||
<label>新密码 <input type="password" id="pwd-new" autocomplete="new-password"></label>
|
||||
<label>确认新密码 <input type="password" id="pwd-confirm" autocomplete="new-password"></label>
|
||||
</div>
|
||||
<div class="settings-actions-row">
|
||||
<button type="button" class="btn-primary btn-sm" id="pwd-save-btn">保存密码</button>
|
||||
<span class="settings-status-line" id="pwd-save-status"></span>
|
||||
</div>
|
||||
@@ -0,0 +1,153 @@
|
||||
{# 三所共用:交易记录(5/页) → 填入复盘出表单 → 交易复盘记录 / AI历史复盘 #}
|
||||
<style>
|
||||
.records-panel-wrap{display:flex;flex-direction:column;gap:14px}
|
||||
.records-panel-wrap .rr-pager{display:flex;align-items:center;gap:8px;margin-top:8px;font-size:.74rem}
|
||||
.records-panel-wrap .rr-list-loading{opacity:.55;pointer-events:none;transition:opacity .12s ease}
|
||||
.records-panel-wrap .rr-trades-wrap{min-height:9.5rem}
|
||||
.records-panel-wrap .journal-card.hidden{display:none!important}
|
||||
.records-panel-wrap .rr-hint{font-size:.72rem;color:#8892b0;margin:0 0 8px}
|
||||
</style>
|
||||
<div class="records-panel-wrap" id="records-panel-root" style="grid-column:1/-1">
|
||||
<div class="card full records-card">
|
||||
<h2>交易记录</h2>
|
||||
<p class="rr-hint">每页5条.点「填入复盘」打开下方复盘表单.</p>
|
||||
<div class="form-row" style="margin-bottom:10px;gap:8px">
|
||||
<label style="display:flex;align-items:center;gap:6px;font-size:.82rem;color:#cfd3ef">
|
||||
<input id="review-mode-toggle" type="checkbox">
|
||||
修改/核对开关(开启后可编辑关键字段)
|
||||
</label>
|
||||
</div>
|
||||
<div class="table-wrap rr-trades-wrap" id="rr-trades-wrap">
|
||||
<table id="rr-trades-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>盈亏U</th><th>结果</th><th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="rr-trades-tbody">
|
||||
<tr><td colspan="15" class="muted">加载中…</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="rr-pager" id="rr-trades-pager">
|
||||
<button type="button" class="btn-secondary" id="rr-trades-prev" style="font-size:.72rem;padding:2px 8px">上一页</button>
|
||||
<span class="muted" id="rr-trades-page-label">第 1 / 1 页</span>
|
||||
<button type="button" class="btn-secondary" id="rr-trades-next" style="font-size:.72rem;padding:2px 8px">下一页</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card full journal-card hidden" id="journal-card">
|
||||
<div class="form-row" style="align-items:center;gap:8px;margin-bottom:6px">
|
||||
<h2 style="margin:0;margin-right:auto">交易复盘记录上传(含截图)</h2>
|
||||
<button type="button" class="btn-secondary" id="rr-journal-hide-btn" style="font-size:.76rem;padding:4px 10px">收起</button>
|
||||
</div>
|
||||
<p class="rr-hint" id="rr-journal-fill-hint" style="display:none">已从交易记录填入,请补充主观原因后保存.</p>
|
||||
<form id="journal-form" action="/add_journal" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="risk_amount_hint" id="risk-amount-hint">
|
||||
<input type="hidden" name="entry_price_hint" id="entry-price-hint">
|
||||
<input type="hidden" name="stop_loss_hint" id="stop-loss-hint">
|
||||
<input type="hidden" name="exit_price_hint" id="exit-price-hint">
|
||||
<input type="hidden" name="direction_hint" id="direction-hint">
|
||||
{% from 'journal_form_fields.html' import journal_form_fields %}
|
||||
{{ journal_form_fields(entry_reason_options, order_type_options) }}
|
||||
{% from 'journal_upload_slots.html' import journal_upload_slots %}
|
||||
{{ journal_upload_slots() }}
|
||||
<div class="form-row journal-chart-options" style="flex-wrap:wrap;align-items:center">
|
||||
<label style="display:flex;align-items:center;gap:6px;font-size:.82rem;color:#cfd3ef">
|
||||
<input type="checkbox" name="journal_exchange_chart" value="true">
|
||||
保存时自动生成 K 线图并作为截图
|
||||
</label>
|
||||
<label style="font-size:.82rem;color:#9aa">周期1</label>
|
||||
<select name="journal_chart_tf1" style="min-width:72px">
|
||||
{% for tf in journal_chart_tf_choices %}
|
||||
<option value="{{ tf }}" {% if tf == journal_chart_default_tf1 %}selected{% endif %}>{{ tf }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label style="font-size:.82rem;color:#9aa">周期2</label>
|
||||
<select name="journal_chart_tf2" style="min-width:72px">
|
||||
{% for tf in journal_chart_tf_choices %}
|
||||
<option value="{{ tf }}" {% if tf == journal_chart_default_tf2 %}selected{% endif %}>{{ tf }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label style="font-size:.82rem;color:#9aa">K线数</label>
|
||||
<select name="journal_chart_limit" style="min-width:72px">
|
||||
{% for n in [100, 150, 200, 250, 300, 400, 500] %}
|
||||
<option value="{{ n }}" {% if n == journal_chart_default_limit %}selected{% endif %}>{{ n }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label style="font-size:.82rem;color:#9aa">K线截止</label>
|
||||
<select name="journal_chart_anchor" id="journal-chart-anchor" style="min-width:96px" title="K线窗口右端对齐的时间">
|
||||
<option value="close" {% if journal_chart_default_anchor == 'close' %}selected{% endif %}>平仓时间</option>
|
||||
<option value="now" {% if journal_chart_default_anchor == 'now' %}selected{% endif %}>当前时间</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="sub" id="journal-chart-anchor-hint" style="font-size:.72rem;color:#8892b0;margin-top:2px;margin-bottom:0">双周期上下排列;截止=平仓时间:开仓前背景至平仓;截止=当前时间:最近 N 根至此刻(可看平仓后走势);标注开仓,平仓与止损位</div>
|
||||
<div class="mood-grid">
|
||||
<label><input type="checkbox" name="mood_issues" value="怕踏空">怕踏空</label>
|
||||
<label><input type="checkbox" name="mood_issues" value="报复开仓">报复开仓</label>
|
||||
<label><input type="checkbox" name="mood_issues" value="盈利飘了">盈利飘了</label>
|
||||
<label><input type="checkbox" name="mood_issues" value="拿不住单">拿不住单</label>
|
||||
<label><input type="checkbox" name="mood_issues" value="扛单">扛单</label>
|
||||
<label><input type="checkbox" name="mood_issues" value="重仓违规">重仓违规</label>
|
||||
</div>
|
||||
<textarea name="note" rows="2" placeholder="备注"></textarea>
|
||||
<button type="submit" style="margin-top:8px">保存复盘记录</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card full review-card" id="review-card">
|
||||
<div class="review-card-head">
|
||||
<h2>AI复盘(按交易记录)</h2>
|
||||
<button type="button" class="review-card-fs-btn" id="review-card-fs-btn" onclick="toggleReviewCardFullscreen()">全屏</button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input type="date" id="day_date">
|
||||
<button type="button" id="gen-daily-btn" onclick="genDaily()">生成日复盘</button>
|
||||
<button type="button" onclick="exportDailyBundleMd()" style="background:#1f3a5a">导出当日日复盘MD</button>
|
||||
<input type="date" id="week_start">
|
||||
<input type="date" id="week_end">
|
||||
<button type="button" id="gen-weekly-btn" onclick="genWeekly()">生成周复盘</button>
|
||||
<button type="button" onclick="exportWeeklyBundleMd()" style="background:#1f3a5a">导出当周复盘MD</button>
|
||||
</div>
|
||||
<div class="ai-result-wrap" id="daily_result_wrap" style="display:none">
|
||||
<div id="daily_result" class="ai-result"></div>
|
||||
<div class="ai-result-toolbar">
|
||||
<button type="button" class="btn-fs" onclick="openAiInlineResultFullscreen('日复盘结果', 'daily_result')">全屏查看</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ai-result-wrap" id="weekly_result_wrap" style="display:none">
|
||||
<div id="weekly_result" class="ai-result"></div>
|
||||
<div class="ai-result-toolbar">
|
||||
<button type="button" class="btn-fs" onclick="openAiInlineResultFullscreen('周复盘结果', 'weekly_result')">全屏查看</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card full" id="rr-journals-card">
|
||||
<h3 style="margin-top:0">交易复盘记录</h3>
|
||||
<p class="rr-hint" id="rr-journals-hint">已保存的复盘(每页5条).</p>
|
||||
<div id="journal-list-wrap" class="rr-list-wrap rr-journals-wrap">
|
||||
<div id="journal-list"></div>
|
||||
</div>
|
||||
<div class="rr-pager" id="rr-journals-pager">
|
||||
<button type="button" class="btn-secondary" id="rr-journals-prev" style="font-size:.72rem;padding:2px 8px">上一页</button>
|
||||
<span class="muted" id="rr-journals-page-label">第 1 / 1 页</span>
|
||||
<button type="button" class="btn-secondary" id="rr-journals-next" style="font-size:.72rem;padding:2px 8px">下一页</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card full" id="rr-ai-history-card">
|
||||
<h3 style="margin-top:0">AI历史复盘</h3>
|
||||
<p class="rr-hint">日/周 AI 复盘历史(每页5条).</p>
|
||||
<div id="review-list-wrap" class="rr-list-wrap">
|
||||
<div id="review-list"></div>
|
||||
</div>
|
||||
<div class="rr-pager" id="rr-reviews-pager">
|
||||
<button type="button" class="btn-secondary" id="rr-reviews-prev" style="font-size:.72rem;padding:2px 8px">上一页</button>
|
||||
<span class="muted" id="rr-reviews-page-label">第 1 / 1 页</span>
|
||||
<button type="button" class="btn-secondary" id="rr-reviews-next" style="font-size:.72rem;padding:2px 8px">下一页</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,39 @@
|
||||
{# 风控说明:只读展示 .env 风控参数与当前账户状态 #}
|
||||
<div class="risk-policy-page full">
|
||||
<div class="card settings-card settings-card--risk">
|
||||
<h2>风控说明</h2>
|
||||
<p class="settings-live-status">
|
||||
当前账户状态:
|
||||
<span class="risk-status-badge risk-status-{{ risk_status.status|default('normal') }}">
|
||||
{{ instance_settings.risk_status_label }}
|
||||
</span>
|
||||
{% if instance_settings.risk_status_reason %}
|
||||
<span class="settings-status-reason">{{ instance_settings.risk_status_reason }}</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% if instance_settings.trade_policy_note %}
|
||||
<p class="settings-policy-note">账户限制:{{ instance_settings.trade_policy_note }}</p>
|
||||
{% endif %}
|
||||
<p class="settings-env-hint">以下参数读取自本实例 <code>.env</code>,修改后需重启进程生效.</p>
|
||||
<div class="settings-risk-sections">
|
||||
{% for section in instance_settings.sections %}
|
||||
<div class="card settings-subcard">
|
||||
<h3 class="settings-subcard-title">{{ section.title }}</h3>
|
||||
<dl class="settings-kv settings-kv--compact">
|
||||
{% for row in section.rows %}
|
||||
<div class="settings-kv-row">
|
||||
<dt>{{ row.label }}</dt>
|
||||
<dd>
|
||||
<span class="settings-kv-value">{{ row.value }}</span>
|
||||
{% if row.note %}
|
||||
<span class="settings-kv-note">{{ row.note }}</span>
|
||||
{% endif %}
|
||||
</dd>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,54 @@
|
||||
{# 系统设置:CSS Tab(与 env 配置同方案) #}
|
||||
<div class="settings-page full">
|
||||
<div class="env-config-head card">
|
||||
<h2>系统设置</h2>
|
||||
<p class="settings-env-hint env-config-head-hint">各区块说明见 <code>docs/系统设置说明.md</code>.</p>
|
||||
</div>
|
||||
|
||||
{% if settings_tabs %}
|
||||
<div class="env-config-body card settings-config-body">
|
||||
{% for tab in settings_tabs %}
|
||||
<input type="radio" name="settings-section" id="settings-sec-{{ loop.index0 }}" class="env-tab-radio"{% if loop.first %} checked{% endif %}>
|
||||
{% endfor %}
|
||||
<div class="env-config-tabs" role="tablist" aria-label="系统设置分类">
|
||||
{% for tab in settings_tabs %}
|
||||
<label for="settings-sec-{{ loop.index0 }}" class="env-tab-btn" role="tab">{{ tab.title }}</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="env-config-panels">
|
||||
{% for tab in settings_tabs %}
|
||||
<section class="env-panel env-panel--{{ loop.index0 }} settings-tab-panel" role="tabpanel">
|
||||
{% if tab.key == 'nav' %}
|
||||
{% include 'display_prefs_panel.html' %}
|
||||
{% elif tab.key == 'password' %}
|
||||
{% include 'password_settings_panel.html' %}
|
||||
{% elif tab.key == 'transfer' %}
|
||||
<h2>永续资金划转</h2>
|
||||
<p class="settings-subcard-desc">子账户永续:资金账户与交易账户之间划转 USDT.</p>
|
||||
{% include 'instance_transfer_panel.html' %}
|
||||
{% elif tab.key == 'export' %}
|
||||
<h2>数据导出</h2>
|
||||
<p class="settings-subcard-desc muted">CSV · v{{ instance_settings.data_export_version }}</p>
|
||||
<div class="settings-export-links-inline settings-export-links-block">
|
||||
<a href="/export/trade_records">交易记录</a>
|
||||
<a href="/export/journal_entries">复盘记录</a>
|
||||
<a href="/export/key_monitors">关键位(当前)</a>
|
||||
<a href="/export/key_monitor_history">关键位历史</a>
|
||||
</div>
|
||||
{% elif tab.key == 'options_swap' %}
|
||||
<h2>币种兑换</h2>
|
||||
{% include 'options_settings_swap.html' %}
|
||||
{% elif tab.key == 'options_transfer' %}
|
||||
<h2>期权资金划转</h2>
|
||||
{% include 'options_settings_transfer.html' %}
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if instance_settings.options_settings_enabled %}
|
||||
{% include 'options_settings_panel.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
Reference in New Issue
Block a user