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
+31 -7
View File
@@ -176,6 +176,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,
@@ -363,6 +369,7 @@ FORCE_CLOSE_BJ_HOUR = int(os.getenv("FORCE_CLOSE_BJ_HOUR", "0"))
AUTO_TRANSFER_BJ_HOUR = int(os.getenv("AUTO_TRANSFER_BJ_HOUR", "8"))
# 计仓模式:risk=以损定仓(默认);full_margin=合约可用保证金×比例全仓杠杆(仅 env 切换,须无仓)
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"))
@@ -1842,7 +1849,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})
@@ -5919,6 +5929,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(
@@ -5983,6 +5995,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:
@@ -6217,6 +6231,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
@@ -7239,8 +7256,15 @@ def render_main_page(page="trade", embed_mode=None):
breakeven_offset_pct=BREAKEVEN_OFFSET_PCT,
price_fmt=format_price_for_symbol,
funds_fmt=format_funds_u,
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,
@@ -8108,11 +8132,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