对齐币安

This commit is contained in:
dekun
2026-05-17 09:09:18 +08:00
parent ff62666c4d
commit e7f24b5bb6
5 changed files with 60 additions and 36 deletions
+14 -1
View File
@@ -74,17 +74,24 @@ GATE_TPSL_PRICE_TYPE=0
# EXCHANGE_DISPLAY_NAME=Gate.io
# =============================================================================
# 关键位门控(页面「关键位监控」)
# 关键位门控(页面「关键位监控」规则条与 _key_hard_checks 共用
# =============================================================================
# 【周期】门控 K 线周期,如 5m、15m
KLINE_TIMEFRAME=5m
# 【确认K】闭合 K 序列中的棒偏移:突破棒默认 -2,确认棒默认 -1
KEY_CONFIRM_BREAKOUT_BAR=-2
KEY_CONFIRM_BAR=-1
# 【量能】突破棒成交量 > 前 N 根均量 × 倍数
KEY_VOLUME_MA_BARS=20
KEY_VOLUME_RATIO_MIN=1.3
# 【突破K实体幅度】占开盘价百分比区间
KEY_BREAKOUT_AMP_MIN_PCT=0.03
KEY_BREAKOUT_AMP_MAX_PCT=0.5
# 【日成交量排名】品种须在该排名前 N 名
KEY_DAILY_VOLUME_RANK_MAX=30
# 【关键位自动开仓盈亏比】严格大于该值才市价开仓
KEY_AUTO_MIN_PLANNED_RR=1.5
# 止损:突破 K 极值向外缓冲的百分比(默认 0.5 即 0.5%)
KEY_STOP_OUTSIDE_BREAKOUT_PCT=0.5
KEY_ALERT_MAX_TIMES=3
KEY_ALERT_INTERVAL_MINUTES=5
@@ -92,14 +99,20 @@ KEY_ALERT_INTERVAL_MINUTES=5
# =============================================================================
# 交易执行 / 人工风控(页面「实盘下单」)
# =============================================================================
# 【最大同时持仓】默认 1=单仓
MAX_ACTIVE_POSITIONS=1
# 【人工下单最低盈亏比】低于该值前后端均拒绝(默认 1.4,即须 >=1.4:1
MANUAL_MIN_PLANNED_RR=1.4
# 【关键位连开计仓】已有持仓时按无仓时资金快照算基数
KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT=true
# 资金与仓位刷新周期(秒)
BALANCE_REFRESH_SECONDS=60
# 前端价格快照轮询(秒)
PRICE_REFRESH_SECONDS=5
# 后台监控轮询周期(秒)
MONITOR_POLL_SECONDS=3
# 使用可用资金时的缓冲比例(如0.98代表用98%)
FULL_MARGIN_BUFFER_RATIO=0.98
# 自动划转:将目标账户补足到 AUTO_TRANSFER_AMOUNT
+16 -15
View File
@@ -81,19 +81,21 @@
.detail-modal .panel-body{white-space:pre-wrap;line-height:1.5;font-size:.86rem;color:#e5e9ff}
.detail-modal .panel-image{margin-top:10px;max-width:min(100%,680px);border-radius:8px;cursor:pointer;border:1px solid #2a3150}
.table-wrap{overflow-x:auto}
.monitor-card{grid-column:1}
.order-card{grid-column:2}
.dual-panel-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:stretch}
.dual-panel-grid .card{height:100%;display:flex;flex-direction:column}
.panel-scroll{flex:1;min-height:280px;max-height:420px;overflow:auto}
.records-card{grid-column:1/-1}
.review-card{grid-column:1/-1}
@media (min-width: 1900px){
.container{max-width:2100px}
.monitor-card .list,.order-card .pos-list{max-height:420px}
.panel-scroll,.pos-list{max-height:420px}
.records-card .table-wrap{max-height:620px;overflow:auto}
}
@media (max-width: 1400px){
.container{width:min(99vw,1600px)}
.grid{grid-template-columns:1fr}
.monitor-card,.order-card,.records-card,.review-card{grid-column:auto}
.dual-panel-grid{grid-template-columns:1fr}
.records-card,.review-card{grid-column:auto}
.panel-list{grid-template-columns:1fr}
}
@media (max-width: 960px){
@@ -175,7 +177,8 @@
<div class="exchange-tag">{{ exchange_display }}</div>
</div>
<div class="top-nav">
<a href="/trade" class="{% if page == 'trade' %}active{% endif %}">交易执行</a>
<a href="/key_monitor" class="{% if page == 'key_monitor' %}active{% endif %}">关键位监控</a>
<a href="/trade" class="{% if page == 'trade' %}active{% endif %}">实盘下单</a>
<a href="/records" class="{% if page == 'records' %}active{% endif %}">交易记录与复盘</a>
<a href="/stats" class="{% if page == 'stats' %}active{% endif %}">统计分析</a>
</div>
@@ -1373,7 +1376,7 @@ function refreshAccountSnapshot(){
const tip = document.getElementById("order-rule-tip");
const avail = (latestAvailableUsdt !== null && !Number.isNaN(latestAvailableUsdt)) ? `;交易账户可用约 ${formatUsdt2(latestAvailableUsdt)}U` : "";
if(tip){
tip.innerText = `规则:最多 ${data.max_active_positions || {{ max_active_positions }}} 仓;BTC {{ btc_leverage }}x / 山寨 {{ alt_leverage }}x${canTradeText}${avail}`;
tip.innerText = `规则:最多 ${data.max_active_positions || {{ max_active_positions }}} 仓;BTC {{ btc_leverage }}x / 山寨 {{ alt_leverage }}x${canTradeText}${avail};人工开仓盈亏比不得低于 ${data.manual_min_planned_rr || {{ manual_min_planned_rr }}}:1`;
}
}).catch(()=>{});
}
@@ -1487,25 +1490,23 @@ function refreshPriceSnapshotConditional(){
(data.order_prices || []).forEach(o=>{
const pEl = document.getElementById(`order-price-${o.id}`);
if(pEl){
const pxd = (o.price_display && o.price_display !== "-") ? o.price_display : null;
const hasMark = (()=>{ const x = o.exchange_mark_price; if(x===null||x===undefined||x==="")return false; const n=Number(x); return !Number.isNaN(n); })();
let disp = "";
if(hasMark && o.exchange_mark_price_display) disp = o.exchange_mark_price_display;
else if(o.price_display) disp = o.price_display;
else { const px = hasMark ? Number(o.exchange_mark_price) : Number(o.price); disp = Number.isFinite(px) ? px.toFixed(6) : "-"; }
pEl.innerText = disp;
const pxNum = hasMark ? Number(o.exchange_mark_price) : Number(o.price);
paintPriceTrend(pEl, `o-${o.id}`, Number.isFinite(pxNum) ? pxNum : px);
const px = hasMark ? Number(o.exchange_mark_price) : Number(o.price);
const decimals = hasMark ? 8 : 6;
pEl.innerText = pxd !== null ? pxd : px.toFixed(decimals);
paintPriceTrend(pEl, `o-${o.id}`, pxd !== null ? Number(pxd) : px);
}
const exM = document.getElementById(`order-ex-margin-${o.id}`);
if(exM){
const mv = o.exchange_initial_margin;
const mn = (mv === null || mv === undefined || mv === "") ? NaN : Number(mv);
if(!Number.isNaN(mn)) exM.innerText = `${mn.toFixed(2)}U`;
if(!Number.isNaN(mn)) exM.innerText = `${formatUsdt2(mn)}U`;
else { const prc = (typeof data.positions_raw_count === "number") ? data.positions_raw_count : null; exM.innerText = (prc === 0) ? "无仓数据" : "-"; }
}
const pnlEl = document.getElementById(`order-pnl-${o.id}`);
if(pnlEl){
pnlEl.innerText = `${formatSigned(o.float_pnl, 2)}U (${formatSigned(o.float_pct, 2)}%)`;
pnlEl.innerText = `${formatSignedUsdt2(o.float_pnl)}U (${formatSigned(o.float_pct, 2)}%)`;
pnlEl.classList.remove("price-up","price-down","price-flat");
if(Number(o.float_pnl) > 0) pnlEl.classList.add("price-up");
else if(Number(o.float_pnl) < 0) pnlEl.classList.add("price-down");
+7 -4
View File
@@ -46,9 +46,11 @@
2. 启动 Flask 应用(本仓库可用 **`ecosystem.config.cjs`** 交给 PM2,或本地 `python app.py` / `flask run`,以你当前脚本为准)。
3. 浏览器访问站点,打开 **`/login`**,使用 **`.env` 里的 `APP_PASSWORD`** 登录。
登录后顶栏为四页:**关键位监控** | **实盘下单**(默认首页)| **交易记录与复盘** | **统计分析**
---
## 4. 关键位监控(页面「关键位监控」卡片
## 4. 关键位监控(顶栏「关键位监控」→ `/key_monitor`
### 4.1 添加一条关键位
@@ -66,7 +68,7 @@
4. **上沿 / 下沿**:必填;保存时会按交易所 **价格精度** 取整。
**限制:**
当前已有 **`order_monitors` 活跃持仓** 时,**不允许**再添加「**箱体突破** / **收敛突破**(否则会与「单仓 + 自动开仓」冲突);仍可添加「**关键阻力位 / 支撑位**」。
活跃持仓数达到 **`MAX_ACTIVE_POSITIONS`**(默认 1时,**不允许**再添加「**箱体突破** / **收敛突破**」;仍可添加「**关键阻力位 / 支撑位**」。
**4h EMA55** 与你的方向逆势,页面会 **额外 Flash 提示****不阻挡**提交。
### 4.2 触发后会发生什么(简版)
@@ -83,11 +85,12 @@
---
## 5. 实盘下单监控(手工开仓
## 5. 实盘下单(顶栏「实盘下单」→ `/trade`
用于 **自己点按钮** 开单:
- **同一时间系统只允许一笔「活跃持仓」监视**(与关键位自动单共用该限制)。
- 持仓上限由 **`MAX_ACTIVE_POSITIONS`** 控制(默认 1与关键位自动单共用)。
- **人工开仓**时计划盈亏比不得低于 **`MANUAL_MIN_PLANNED_RR`**(默认 1.4:1),否则页面弹窗且后端拒绝。
- 填写币种、方向、杠杆(可选)、止损/止盈(价格或百分比按表单说明)。
- 勾选是否启用 **移动保本** 等行为以 `.env`/页面默认值为准。
+16 -12
View File
@@ -1,7 +1,5 @@
# 界面与风控更新说明(Gate 实例)
`crypto_monitor_binance` 同版界面结构,交易所对接为 Gate.io。
## 顶栏导航(4 项)
| 顺序 | 名称 | 路由 | 说明 |
@@ -13,21 +11,27 @@
## 关键位监控页
- 标题去掉「5m」;规则条从 `.env` 读取。
- 左列活跃关键位、右列历史,均为 pos-card 风格,双列对齐
- 标题去掉「5m」;规则条从 `.env` 读取(周期、确认K、量能、自动开仓盈亏比、日成交量排名)
- 左列活跃关键位**pos-card** 样式展示现价/距上沿/距下沿/门控
- 右列:关键位历史(失效/结案),与左列等高滚动。
## 实盘下单页
- 左列下单表单,右列实时持仓
- 人工开仓盈亏比不得低于 `MANUAL_MIN_PLANNED_RR`(默认 1.4)。
- 左列:实盘下单监控(表单、划转、规则)
- 右列:实时持仓(独立模块)。
- **人工开仓门控**:计划盈亏比 &lt; `MANUAL_MIN_PLANNED_RR`(默认 **1.4**)时前端弹窗 + 后端拒绝。
## 持仓与计仓
- `MAX_ACTIVE_POSITIONS` 默认 **1**
- 关键位连开时使用无仓资金快照(见 `KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT`)。
- `MAX_ACTIVE_POSITIONS` 默认 **1**(可在 `.env` 调大)
- 关键位自动开仓:在已有持仓时,若 `KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT=true`,按**首笔开仓前**交易账户资金快照计仓(`trading_sessions.key_sizing_capital_snapshot`)。
## 配置与升级
## 配置
1. 合并 `.env.example` 新增项到本地 `.env`
2. 重启 Gate 实例服务。
3. 强刷浏览器缓存。
详见 `.env.example` 中「关键位门控」「交易执行 / 人工风控」注释段。Gate 专用项(`GATE_*`、止盈止损触发等)保持原有段落不变
## 升级步骤
1. `git pull` 后对比 `.env.example`,把新增变量合并进本地 `.env`
2. 重启 Gate 实例服务(如 `pm2 restart`)。
3. 浏览器强刷(Ctrl+F5)避免旧版 `index.html` 缓存。