auto_trade_sys/docs/止损止盈双通道说明.md
薇薇安 a1b54d658f 1
2026-02-15 10:06:25 +08:00

66 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 止损/止盈的两种实现方式(双通道)
当前确实存在**两种**止损(以及止盈)执行方式,互为备份;逻辑如下。
---
## 一、两种方式分别是什么
### 1. 币安条件单(交易所侧,自动执行)
- **做法**:开仓或补挂时,在币安挂 **STOP_MARKET**(止损)和 **TAKE_PROFIT_MARKET**(止盈)条件单,触发价为策略算出的 `stop_loss` / `take_profit` 价格。
- **触发**:价格到达触发价时,**由币安自动撮合**,无需本机程序在线。
- **代码位置**`position_manager._ensure_exchange_sltp_orders` → `client.place_trigger_close_position_order(trigger_type="STOP_MARKET" / "TAKE_PROFIT_MARKET", stop_price=...)`
- **特点**:服务重启、断网、本机崩溃后,只要仓位和条件单还在,仍能按价止损/止盈。
### 2. 系统 WebSocket 监控(本机侧,到价后市价平仓)
- **做法**本机对每个持仓订阅该交易对价格WebSocket`_check_single_position` 里用**当前价**和**目标止损/止盈**比较(按保证金的亏损/盈利比例),到价则调用 `close_position(symbol, reason='stop_loss'/'take_profit'/...)`,即**市价平仓**。
- **触发**:程序判定「当前盈亏已到止损或止盈目标」时,**本机主动发市价平仓单**。
- **代码位置**`position_manager._monitor_position_price` → `_check_single_position` → 比较 `pnl_percent_margin``stop_loss_pct_margin` / 止盈目标 → `close_position(...)`
- **特点**:可以做**移动止损、分步止盈TP1 部分平仓)**等复杂逻辑,这些无法用交易所单一张单实现。
---
## 二、当前整体流程(开仓后)
1. 开仓成交后(或补建/修复后)调用 **`_ensure_exchange_sltp_orders`**
- 先取消该 symbol 上已有的 STOP_MARKET / TAKE_PROFIT_MARKET / TRAILING_STOP_MARKET
- 再按当前 `position_info` 的止损价、止盈价挂**一张止损 + 一张止盈**(交易所条件单)。
2. 同时对该 symbol 启动 **WebSocket 监控**`_monitor_position_price`
- 每次收到价格,用**保证金盈亏比例**判断是否到止损/到第一止盈/到第二止盈/到移动止损;
- 到则 **`close_position(..., reason=...)`**(市价平仓)。
因此:**同一笔仓位既有交易所条件单,又有本机监控**,两条路都能触发平仓,形成双通道。
---
## 三、设计意图与分工
- **交易所条件单**:保证在**本机不在线**时(重启、断网、崩溃)仍有止损/止盈保护。
- **本机 WebSocket**
- 实现**移动止损、TP1 部分平仓**等(交易所只挂固定止损/止盈,不会自动“移动”或“分步”);
- 在**挂单失败**时作为兜底(见下)。
---
## 四、可能的问题与现状
| 问题 | 说明 | 当前处理 |
|------|------|----------|
| **重复平仓** | 交易所先触发平仓后,本机再判“到价”可能再发平仓。 | `close_position` 会先查币安是否还有仓位;无仓位则不再下单,仅同步 DB避免重复市价单。 |
| **挂单失败只剩 WS** | 若 STOP_MARKET 挂单失败(如 -2021、网络错误则**只有** WebSocket 能止损。 | 代码已写:挂单失败时打日志「将依赖 WebSocket 监控」,并再次检查当前价是否已穿止损,若已穿则立即市价平仓;未穿则仅靠 WS进程若挂则无交易所保护。 |
| **价格源不一致** | 交易所条件单多用 **MARK_PRICE**,本机 WS 多用 last/mark。 | 可能有毫秒级差异,一般先触发的一方完成平仓,另一方发现无仓位即不再操作。 |
| **移动止损仅本机** | 移动止损(盈利到 X% 上移止损)只能由本机逻辑实现。 | **已改**:在移动止损**激活**或**更新**时,会调用 `_ensure_exchange_sltp_orders`,取消原止损/止盈条件单并按新止损价重挂,使移动止损也有交易所保护。 |
---
## 五、小结
- **是,止损(和止盈)有两种**
1**币安条件单**:到价由交易所自动止损/止盈;
2**系统 WebSocket 监控**:到价由本机市价平仓。
- **两者并存**同一仓位既有交易所单又有本机监控互为备份本机还负责移动止损、TP1 部分平仓等。
- **主要风险点**:交易所止损/止盈**挂单失败**时,只剩 WebSocket进程挂了就无交易所保护。
- **移动止损**:已在「移动止损激活」与「移动止损更新」时同步至交易所(取消原条件单并按新止损价重挂),本机宕机后交易所仍能按最新移动止损价执行。