更新bot前端显示
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -339,12 +339,12 @@
|
||||
<h2 style="margin-bottom:8px">趋势回调策略</h2>
|
||||
<div class="rule-tip">
|
||||
① <strong>生成预览</strong>:读取合约 USDT <strong>可用余额快照</strong>并计算计划(不下单)。预览有效期 <strong>{{ trend_pullback_preview_ttl }} 秒</strong>。<br>
|
||||
② <strong>确认执行</strong>:市价首仓 50% + 挂交易所止损;剩余 50% 在止损与补仓上沿之间共 {{ trend_pullback_dca_legs }} 档(程序可能因最小张数自动减档)市价补仓;<strong>止盈由程序监控</strong>。<br>
|
||||
② <strong>确认执行</strong>:市价首仓 50% + 挂交易所止损;剩余 50% 在止损与补仓区间之间共 {{ trend_pullback_dca_legs }} 档(做多为<strong>上沿</strong>、做空为<strong>下沿</strong>;程序可能因最小张数自动减档)市价补仓;<strong>止盈由程序监控</strong>。<br>
|
||||
确认执行时若当前可用余额与预览快照相对偏差 > <strong>{{ trend_preview_max_drift_pct }}%</strong> 会拒绝并要求重新预览。
|
||||
</div>
|
||||
<form action="{{ url_for('preview_trend_pullback') }}" method="post" class="form-row">
|
||||
<form id="trend-pullback-form" action="{{ url_for('preview_trend_pullback') }}" method="post" class="form-row">
|
||||
<input name="symbol" placeholder="BTC 或 ETH/USDT" required>
|
||||
<select name="direction" required>
|
||||
<select name="direction" id="trend-direction" required>
|
||||
<option value="">方向</option>
|
||||
<option value="long">做多</option>
|
||||
<option value="short">做空</option>
|
||||
@@ -352,10 +352,25 @@
|
||||
<input name="leverage" type="number" min="1" step="1" placeholder="杠杆(必填)" required>
|
||||
<input name="risk_percent" type="number" min="0.1" step="0.1" value="5" placeholder="风险%相对可用快照" title="默认5:最坏亏损约≤可用余额×5%">
|
||||
<input name="sl" step="any" placeholder="止损价" required>
|
||||
<input name="add_upper" step="any" placeholder="补仓上沿价" required>
|
||||
<input name="add_upper" id="trend-add-upper" step="any" placeholder="补仓上沿价" required>
|
||||
<input name="take_profit" step="any" placeholder="止盈价(固定)" required>
|
||||
<button type="submit" {% if not can_trade %}disabled style="opacity:.5;cursor:not-allowed"{% endif %}>生成预览</button>
|
||||
</form>
|
||||
<script>
|
||||
(function(){
|
||||
const dirSel = document.getElementById("trend-direction");
|
||||
const addInp = document.getElementById("trend-add-upper");
|
||||
function syncAddUpperPlaceholder(){
|
||||
if(!addInp || !dirSel) return;
|
||||
const d = (dirSel.value || "long").toLowerCase();
|
||||
addInp.placeholder = d === "short" ? "补仓下沿价" : "补仓上沿价";
|
||||
}
|
||||
if(dirSel){
|
||||
dirSel.addEventListener("change", syncAddUpperPlaceholder);
|
||||
syncAddUpperPlaceholder();
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
{% if trend_preview %}
|
||||
<div style="margin-top:14px;padding:12px;background:#141a2e;border:1px solid #2a3150;border-radius:8px">
|
||||
@@ -367,7 +382,7 @@
|
||||
{{ trend_preview.symbol }} {{ '做多' if trend_preview.direction == 'long' else '做空' }} {{ trend_preview.leverage }}x |
|
||||
预览可用快照 <strong>{{ money_fmt(trend_preview.snapshot_available_usdt) }}</strong> 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) }})<br>
|
||||
止损 {{ 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 }}%
|
||||
</div>
|
||||
<div class="table-wrap" style="margin-bottom:10px">
|
||||
<table>
|
||||
@@ -442,7 +457,7 @@
|
||||
</div>
|
||||
<div class="plan-card-meta">
|
||||
来源: 趋势回调计划 | 风险: {% if t.risk_percent is not none %}{{ t.risk_percent }}%{% else %}—{% endif %}
|
||||
| <span class="accent">补仓上沿 {{ price_fmt(sym, t.add_upper) }}</span>
|
||||
| <span class="accent">{{ trend_add_zone_label(t.direction) }} {{ price_fmt(sym, t.add_upper) }}</span>
|
||||
| 已补仓 <strong>{{ t.legs_done }}/{{ t.dca_legs }}</strong>
|
||||
</div>
|
||||
<div class="plan-card-grid">
|
||||
@@ -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 || "[]"}`,
|
||||
|
||||
@@ -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`。
|
||||
|
||||
Reference in New Issue
Block a user