diff --git a/crypto_monitor_gate_bot/app.py b/crypto_monitor_gate_bot/app.py
index 60179d0..ef78a2b 100644
--- a/crypto_monitor_gate_bot/app.py
+++ b/crypto_monitor_gate_bot/app.py
@@ -67,6 +67,17 @@ def resolve_path(path_value):
app = Flask(__name__)
app.secret_key = os.getenv("FLASK_SECRET_KEY", "crypto_monitor_2026_secret_key")
+
+def trend_add_zone_label(direction):
+ """趋势回调:做多=补仓上沿,做空=补仓下沿(库字段仍为 add_upper)。"""
+ return "补仓上沿" if (direction or "long").strip().lower() == "long" else "补仓下沿"
+
+
+@app.context_processor
+def _inject_trend_ui_helpers():
+ return {"trend_add_zone_label": trend_add_zone_label}
+
+
# ====================== 登录配置 ======================
USERNAME = os.getenv("APP_USERNAME", "dekun")
PASSWORD = os.getenv("APP_PASSWORD", "Woaini88@")
@@ -2648,7 +2659,7 @@ def parse_and_compute_trend_pullback_plan(form_dict):
return None, "做多:止损价须低于补仓上沿"
else:
if not (stop_loss > add_upper):
- return None, "做空:止损价须高于补仓上沿"
+ return None, "做空:止损价须高于补仓下沿"
snap = get_available_trading_usdt()
if snap is None or snap <= 0:
return None, "无法读取合约账户 USDT 可用余额,请检查 API 与账户类型"
@@ -2658,7 +2669,7 @@ def parse_and_compute_trend_pullback_plan(form_dict):
exchange_symbol = normalize_exchange_symbol(symbol)
rf = calc_risk_fraction(direction, add_upper, stop_loss)
if rf is None or rf <= 0:
- return None, "止损与补仓上沿组合无法计算风险比例"
+ return None, "止损与补仓区间边界组合无法计算风险比例"
risk_budget = float(snap) * (risk_percent / 100.0)
notional = risk_budget / rf
margin_plan = notional / float(leverage)
@@ -2679,7 +2690,7 @@ def parse_and_compute_trend_pullback_plan(form_dict):
remainder_total = 0.0
n_legs, leg_json, per_ref = _trend_build_leg_amounts_json(exchange_symbol, remainder_total, TREND_PULLBACK_DCA_LEGS)
if n_legs <= 0:
- return None, "剩余计划张数不足以拆出补仓档(低于交易所最小张数),请提高风险比例、放宽止损与补仓上沿间距,或减少补仓档数"
+ return None, "剩余计划张数不足以拆出补仓档(低于交易所最小张数),请提高风险比例、放宽止损与补仓区间间距,或减少补仓档数"
grid = _trend_build_grid_prices(direction, stop_loss, add_upper, n_legs)
if len(grid) != n_legs:
return None, "补仓网格生成失败"
@@ -4067,7 +4078,7 @@ def breakout_too_far(p, edge_price, limit_pct):
def _trend_build_grid_prices(direction, sl, upper, n_legs):
- """在 (止损, 补仓上沿) 开区间内生成 n_legs 个补仓触发价(不含端点)。"""
+ """在 (止损, 补仓区间远侧边界 add_upper) 开区间内生成 n_legs 个补仓触发价(不含端点)。"""
sl, upper = float(sl), float(upper)
out = []
if n_legs <= 0:
diff --git a/crypto_monitor_gate_bot/templates/index.html b/crypto_monitor_gate_bot/templates/index.html
index 580040d..edea9c2 100644
--- a/crypto_monitor_gate_bot/templates/index.html
+++ b/crypto_monitor_gate_bot/templates/index.html
@@ -339,12 +339,12 @@
趋势回调策略
① 生成预览:读取合约 USDT 可用余额快照并计算计划(不下单)。预览有效期 {{ trend_pullback_preview_ttl }} 秒。
- ② 确认执行:市价首仓 50% + 挂交易所止损;剩余 50% 在止损与补仓上沿之间共 {{ trend_pullback_dca_legs }} 档(程序可能因最小张数自动减档)市价补仓;止盈由程序监控。
+ ② 确认执行:市价首仓 50% + 挂交易所止损;剩余 50% 在止损与补仓区间之间共 {{ trend_pullback_dca_legs }} 档(做多为上沿、做空为下沿;程序可能因最小张数自动减档)市价补仓;止盈由程序监控。
确认执行时若当前可用余额与预览快照相对偏差 > {{ trend_preview_max_drift_pct }}% 会拒绝并要求重新预览。
-
+
{% if trend_preview %}
@@ -367,7 +382,7 @@
{{ trend_preview.symbol }} {{ '做多' if trend_preview.direction == 'long' else '做空' }} {{ trend_preview.leverage }}x |
预览可用快照 {{ money_fmt(trend_preview.snapshot_available_usdt) }} U | 参考价 {{ price_fmt(trend_preview.symbol, trend_preview.live_price_ref) }} |
计划保证金≈{{ money_fmt(trend_preview.plan_margin_capital) }} U | 总张≈{{ amt_fmt(trend_preview.symbol, trend_preview.target_order_amount) }}(首仓 {{ amt_fmt(trend_preview.symbol, trend_preview.first_order_amount) }} + 补仓 {{ amt_fmt(trend_preview.symbol, trend_preview.remainder_total) }})
- 止损 {{ price_fmt(trend_preview.symbol, trend_preview.stop_loss) }} | 补仓上沿 {{ price_fmt(trend_preview.symbol, trend_preview.add_upper) }} | 止盈 {{ price_fmt(trend_preview.symbol, trend_preview.take_profit) }} | 风险比例 {{ trend_preview.risk_percent }}%
+ 止损 {{ price_fmt(trend_preview.symbol, trend_preview.stop_loss) }} | {{ trend_add_zone_label(trend_preview.direction) }} {{ price_fmt(trend_preview.symbol, trend_preview.add_upper) }} | 止盈 {{ price_fmt(trend_preview.symbol, trend_preview.take_profit) }} | 风险比例 {{ trend_preview.risk_percent }}%
@@ -442,7 +457,7 @@
来源: 趋势回调计划 | 风险: {% if t.risk_percent is not none %}{{ t.risk_percent }}%{% else %}—{% endif %}
- | 补仓上沿 {{ price_fmt(sym, t.add_upper) }}
+ | {{ trend_add_zone_label(t.direction) }} {{ price_fmt(sym, t.add_upper) }}
| 已补仓 {{ t.legs_done }}/{{ t.dca_legs }}
@@ -713,7 +728,7 @@ function openPreviewSnapshotDetail(id){
`总张数:${s.target_order_amount != null ? s.target_order_amount : "-"}`,
`首仓/补仓余:${s.first_order_amount != null ? s.first_order_amount : "-"} / ${s.remainder_total != null ? s.remainder_total : "-"}`,
`补仓档数:${s.dca_legs != null ? s.dca_legs : "-"}`,
- `止损 / 补仓上沿 / 止盈:${s.stop_loss} / ${s.add_upper} / ${s.take_profit}`,
+ `止损 / ${s.direction === "long" ? "补仓上沿" : "补仓下沿"} / 止盈:${s.stop_loss} / ${s.add_upper} / ${s.take_profit}`,
`风险%:${s.risk_percent != null ? s.risk_percent : "-"}`,
`网格价 JSON:${s.grid_prices_json || "[]"}`,
`分档张数 JSON:${s.leg_amounts_json || "[]"}`,
diff --git a/crypto_monitor_gate_bot/趋势回调策略说明.md b/crypto_monitor_gate_bot/趋势回调策略说明.md
index 0fd2e71..2b64062 100644
--- a/crypto_monitor_gate_bot/趋势回调策略说明.md
+++ b/crypto_monitor_gate_bot/趋势回调策略说明.md
@@ -7,7 +7,7 @@
## 1. 适用场景
- 单独用于跑策略的 **Gate.io USDT 永续** 子账户(建议与主资金隔离)。
-- 你已明确:**方向、止损价、补仓上沿、止盈价、杠杆**,并接受程序按风险预算拆分 **首仓 50% + 多档补仓 50%**。
+- 你已明确:**方向、止损价、补仓区间边界价、止盈价、杠杆**,并接受程序按风险预算拆分 **首仓 50% + 多档补仓 50%**。
---
@@ -16,9 +16,9 @@
| 名称 | 含义 |
|------|------|
| **合约 USDT 可用余额** | **生成预览**时通过 API 读取的 **swap 账户 USDT `free`** 快照;**确认执行**时再次读取并与快照比对偏差。 |
-| **风险比例** | 默认 **5%**:指「若整笔计划在 **补仓上沿** 这一侧的最坏价格结构下触及止损」,目标亏损上限约为 **可用余额快照 × 风险比例**(实现上用 `calc_risk_fraction` 与 `prepare_order_amount` 反推总张数,受交易所最小张数与精度约束)。 |
+| **风险比例** | 默认 **5%**:指「若整笔计划在 **补仓区间远侧边界**(做多=上沿、做空=下沿)这一侧的最坏价格结构下触及止损」,目标亏损上限约为 **可用余额快照 × 风险比例**(实现上用 `calc_risk_fraction` 与 `prepare_order_amount` 反推总张数,受交易所最小张数与精度约束)。 |
| **止损价** | 用户填写;开仓后挂 **交易所仓位类止损触发单**(全平)。 |
-| **补仓上沿** | 用户填写;**仅在该价位与止损价构成的区间内** 才允许程序触发剩余 50% 的市价补仓(做多:`止损 < 补仓上沿`;做空:`止损 > 补仓上沿`)。 |
+| **补仓区间边界**(库字段 `add_upper`) | 用户填写;**仅在该价位与止损价构成的区间内** 才允许程序触发剩余 50% 的市价补仓。**界面文案**:做多显示「补仓上沿」,做空显示「补仓下沿」。校验:做多 `止损 < 边界价`;做空 `止损 > 边界价`。 |
| **止盈价** | 用户填写的 **固定价格**;**不由交易所条件止盈单触发**,由应用后台 **按标记价/行情价轮询**,达到后 **市价全平**。 |
| **杠杆** | 计划内固定写入;用于 `set_leverage` 与名义换算。 |
| **补仓档位数** | 默认 **5** 档(环境变量 `TREND_PULLBACK_DCA_LEGS` 可调);程序在满足最小张数前提下可能 **自动减少档数**。 |
@@ -32,7 +32,7 @@
1. **风控**:与「机器人下单监控」**互斥**——存在活跃机器人持仓或运行中趋势计划时,不可生成预览。
2. **读取可用余额快照** `get_available_trading_usdt()`,失败则拒绝。
3. **计算**(写入表 `trend_pullback_previews`,并跳转带 `preview_id`):
- - 在 **补仓上沿 ↔ 止损** 区间内生成 `N` 个补仓触发价;
+ - 在 **补仓区间边界 ↔ 止损** 区间内生成 `N` 个补仓触发价(做多从上沿向止损、做空从下沿向止损);
- 将 **剩余 50% 计划张数** 拆成 `N` 份写入 `leg_amounts_json`。
4. **预览有效期**:默认 **120 秒**(`TREND_PULLBACK_PREVIEW_TTL_SECONDS`),超时须重新点「生成预览」。
@@ -41,7 +41,7 @@
5. 再次校验:预览未过期;**当前可用余额**与预览快照相对偏差 ≤ `TREND_PREVIEW_MAX_BALANCE_DRIFT_PCT`(默认 **5%**),否则拒绝执行并要求重新预览。
6. **首仓**:**立即市价** 开立 **总计划张数 × 50%**(不附带交易所止盈单)。
7. **止损**:撤销旧条件单后,挂 **仅止损** 的仓位触发单;之后每次补仓成交会 **刷新** 止损挂单。
-8. **补仓**:当价格 **穿越** 下一档触发价(做多为自上向下穿越)时,按该档张数 **市价加仓**;直至 `N` 档执行完毕或计划结束。
+8. **补仓**:当价格 **穿越** 下一档触发价(做多为自上向下穿越,做空为自下向上穿越)时,按该档张数 **市价加仓**;直至 `N` 档执行完毕或计划结束。
9. **止盈监控**:后台线程若发现价格触及止盈,则 **市价全平**。
10. **止损触发**:若仓位被交易所止损打光,本地检测到 **持仓为 0** 后记账为 **止损** 并结束计划。
11. **计划结束**:任一结束路径(止盈 / 止损 / 用户手动结束)均会 **撤单**(条件单 + 普通挂单,尽力而为)。
@@ -57,7 +57,8 @@
- **不包含**仅存在于 `trend_pullback_previews`、从未「确认执行」的预览。
- 每行提供 **删除**:删除该计划行,并删除 `trade_records` 中 **`trend_plan_id` 与之相同** 且类型为「趋势回调」的记录(用于与计划一一对应的新数据;历史旧行若无 `trend_plan_id` 则不会随删)。
- **运行中的计划(交易执行页)**
- - 在计划摘要下方展示 **浮盈亏(交易所)**:来自 Gate 当前持仓接口的 **未实现盈亏**(及标记价,若可得);与本地按均价估算可能略有差异,以交易所为准便于对照。
+ - 在计划摘要下方展示 **浮盈亏(交易所)**:来自 Gate 当前持仓接口的 **未实现盈亏**(及标记价,若可得);与本地按均价估算可能略有差异,以交易所为准便于对照。
+ - **补仓边界**按方向显示「补仓上沿」或「补仓下沿」(数值仍为 `add_upper` 字段)。
### 3.5 交易记录与交易所「已实现盈亏」对齐
@@ -109,7 +110,7 @@
## 7. 数据库
- **`trend_pullback_previews`**:未执行的预览行(含 `expires_at_ms`),执行成功或取消后删除;过期可被清理。
-- **`trend_pullback_plans`**:趋势回调计划。执行后写入一行,`status='active'` 表示运行中;止盈 / 止损 / 手动结束后变为 **`stopped_tp` / `stopped_sl` / `stopped_manual`** 等非 `active` 状态,并出现在页顶 **计划历史**。字段含快照可用余额、计划保证金、总张数、首仓张数、补仓 JSON、网格价 JSON、已补仓档数、均价、`opened_at`、`message`(结束说明)等。
+- **`trend_pullback_plans`**:趋势回调计划。执行后写入一行,`status='active'` 表示运行中;止盈 / 止损 / 手动结束后变为 **`stopped_tp` / `stopped_sl` / `stopped_manual`** 等非 `active` 状态,并出现在页顶 **计划历史**。字段含快照可用余额、计划保证金、总张数、首仓张数、补仓 JSON、网格价 JSON、已补仓档数、均价、`opened_at`、`message`(结束说明)等;**`add_upper`** 存补仓区间远侧边界价(做多=上沿、做空=下沿)。
- **`trade_records`**(`monitor_type=趋势回调`):每次计划结束插入一行;含本地估算盈亏等。新写入行带 **`trend_plan_id`** 指向 `trend_pullback_plans.id`。另含 **`exchange_realized_pnl`、`exchange_opened_at`、`exchange_closed_at`、`exchange_sync_key`**,由页面触发的交易所平仓历史同步填充(见 3.5)。
**CSV 导出**:交易记录导出为 **v3**,包含上述交易所对齐字段及 `trend_plan_id`。