feat: KEY_AUTO_ORDER_ENABLED 三所统一开关,联动关键位自动单与开仓类型

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-05 23:39:06 +08:00
parent f688a504e1
commit 21894334f8
13 changed files with 457 additions and 29 deletions
+16
View File
@@ -93,6 +93,22 @@ GATE_TPSL_LAST_PRICE_GAP_PCT=0.05
# 页面与浏览器标签展示的交易所名称(多环境区分时可改成例如 Gate·模拟)
# EXCHANGE_DISPLAY_NAME=Gate.io
# =============================================================================
# 关键位程序自动下单(与 POSITION_SIZING_MODE 联动,修改后须重启 PM2)
# =============================================================================
# 默认 false = 关闭所有关键位程序自动单(箱体/收敛/斐波/假突破/触价)
#
# POSITION_SIZING_MODE=risk(以损定仓)
# false → 不执行任何关键位自动单;支撑/阻力提醒、人工下单、顺势加仓不受影响
# true → 允许关键位全套自动(含触价)
#
# POSITION_SIZING_MODE=full_margin(全仓杠杆,须无仓切换)
# false → 不执行触价自动单
# true → 仅回调/突破触价可程序自动开仓;箱体/斐波等仍禁止
#
# 顺势加仓、趋势回调不受本开关控制;全仓模式下策略自动仍禁止。
KEY_AUTO_ORDER_ENABLED=false
# =============================================================================
# 关键位门控(页面「关键位监控」规则条与 _key_hard_checks 共用)
# =============================================================================
+31 -7
View File
@@ -175,6 +175,12 @@ from lib.trade.trade_policy_app_lib import (
default_symbol_for_policy,
trade_policy_template_context,
)
from lib.key_monitor.key_auto_order_lib import (
check_monitor_type_add_allowed,
effective_entry_reason_options,
effective_stats_segment_defs,
load_key_auto_order_enabled,
)
from lib.key_monitor.key_monitor_full_margin_lib import (
monitor_type_disallowed_in_full_margin,
purge_disallowed_key_monitors,
@@ -353,6 +359,7 @@ FORCE_CLOSE_BJ_HOUR = int(os.getenv("FORCE_CLOSE_BJ_HOUR", "0"))
# 自动划转:仅在北京时间该整点「小时」内尝试;transfer_logs.transfer_day 存 UTC 自然日便于对账
AUTO_TRANSFER_BJ_HOUR = int(os.getenv("AUTO_TRANSFER_BJ_HOUR", "8"))
POSITION_SIZING_MODE = load_position_sizing_mode()
KEY_AUTO_ORDER_ENABLED = load_key_auto_order_enabled()
TRADE_POLICY = load_trade_policy()
WECHAT_TIMEOUT_SECONDS = int(os.getenv("WECHAT_TIMEOUT_SECONDS", "10"))
AI_TIMEOUT_SECONDS = int(os.getenv("AI_TIMEOUT_SECONDS", "120"))
@@ -1839,7 +1846,10 @@ def compute_stats_bundle(conn, trading_day, now_dt=None):
return dm, wm, mm
segments = []
for seg_key, seg_title, _meta in STATS_SEGMENT_DEFS:
seg_defs = effective_stats_segment_defs(
STATS_SEGMENT_DEFS, POSITION_SIZING_MODE, KEY_AUTO_ORDER_ENABLED
)
for seg_key, seg_title, _meta in seg_defs:
dm, wm, mm = slice_metrics(seg_key)
segments.append({"key": seg_key, "title": seg_title, "day": dm, "week": wm, "month": mm})
@@ -5560,6 +5570,8 @@ def _execute_trigger_entry_cross(conn, row):
def check_trigger_entry_key_monitors():
if not KEY_AUTO_ORDER_ENABLED:
return
conn = get_db()
placeholders = ",".join("?" * len(TRIGGER_ENTRY_MONITOR_TYPES))
rows = conn.execute(
@@ -5624,6 +5636,8 @@ def check_trigger_entry_key_monitors():
def check_fib_key_monitors():
if not KEY_AUTO_ORDER_ENABLED:
return
conn = get_db()
rows = conn.execute("SELECT * FROM key_monitors").fetchall()
for r in rows:
@@ -5858,6 +5872,9 @@ def check_key_monitors():
print(f"[key_rs_level_alert] {sym} id={r['id']}: {e}")
continue
if not KEY_AUTO_ORDER_ENABLED:
continue
direction = (r["direction"] or "long").lower()
if direction == KEY_DIRECTION_WATCH:
continue
@@ -7018,8 +7035,15 @@ def render_main_page(page="trade", embed_mode=None):
funds_fmt=format_usdt,
usdt_fmt=format_usdt,
signed_usdt_fmt=format_signed_usdt,
entry_reason_options=list(ENTRY_REASON_OPTIONS),
entry_reason_options=list(
effective_entry_reason_options(
ENTRY_REASON_OPTIONS,
POSITION_SIZING_MODE,
KEY_AUTO_ORDER_ENABLED,
)
),
entry_reason_other_value=ENTRY_REASON_OTHER,
key_auto_order_enabled=KEY_AUTO_ORDER_ENABLED,
journal_chart_tf_choices=JOURNAL_CHART_TF_CHOICES,
journal_chart_default_tf1=JOURNAL_CHART_DEFAULT_TF1,
journal_chart_default_tf2=JOURNAL_CHART_DEFAULT_TF2,
@@ -7905,11 +7929,11 @@ def add_key():
if mt not in allowed_types:
flash("监控类型无效")
return redirect("/key_monitor")
if is_full_margin_mode(POSITION_SIZING_MODE) and monitor_type_disallowed_in_full_margin(mt):
flash(
"全仓杠杆模式下不可添加箱体/收敛突破、斐波或假突破监控;"
"可使用「回调/突破触价开仓」或阻力/支撑(仅提醒),或切换 POSITION_SIZING_MODE=risk 并重启(须无持仓)。"
)
ok_mt, mt_msg = check_monitor_type_add_allowed(
mt, POSITION_SIZING_MODE, KEY_AUTO_ORDER_ENABLED
)
if not ok_mt:
flash(mt_msg)
return redirect("/key_monitor")
skip_volume_rank = is_false_breakout_key_monitor_type(mt)
rank, total = None, None
@@ -1,7 +1,24 @@
# 关键位监控说明(自动开仓 + 人工盯盘)
**适用:Gate / Binance / OKX 三所实例(共用 `lib/key_monitor/key_auto_order_lib.py`**
## 环境开关 `KEY_AUTO_ORDER_ENABLED`(默认 `false`
| 计仓模式 | 开关 | 关键位程序自动单 |
|----------|------|------------------|
| `risk`(以损定仓) | `false` | **全部关闭**(含触价);支撑/阻力微信提醒仍可用 |
| `risk` | `true` | 箱体/收敛/斐波/假突破/触价均可自动(旧行为) |
| `full_margin`(全仓) | `false` | 全部关闭(含触价) |
| `full_margin` | `true` | **仅触价**自动;箱体/斐波等仍禁止 |
**不受本开关影响:** 人工实盘下单、关键支撑/阻力提醒、**顺势加仓**(`risk` 下)、趋势回调(`risk` 下)。全仓模式下策略自动仍禁止。
修改 `.env` 后须 **重启 PM2**。复盘「开仓类型」与统计分段会随开关联动隐藏关键位选项。
---
**适用:`crypto_monitor_gate`Gate U 本位永续)**
Binance / OKX 见各自目录下同名文档;共享逻辑在仓库根目录 `key_monitor_lib.py`
Binance / OKX 见各自目录下同名文档;共享逻辑在 `lib/key_monitor/`
本文档与 `.env``check_key_monitors``add_key``_key_hard_checks``_process_key_rs_level_alert` 一致。