#!/usr/bin/env python3 """对 binance/okx/gate_bot 应用与 gate 相同的时间平仓代码替换。""" from __future__ import annotations from pathlib import Path ROOT = Path(__file__).resolve().parents[1] FILES = [ ROOT / "crypto_monitor_binance" / "app.py", ROOT / "crypto_monitor_okx" / "app.py", ROOT / "crypto_monitor_gate_bot" / "app.py", ] REPLACEMENTS: list[tuple[str, str]] = [ ( "def _market_open_for_key_monitor(\n conn,\n symbol,\n direction,\n exchange_symbol,\n stop_loss,\n take_profit,\n key_signal_type=None,\n breakeven_enabled=0,\n):", "def _market_open_for_key_monitor(\n conn,\n symbol,\n direction,\n exchange_symbol,\n stop_loss,\n take_profit,\n key_signal_type=None,\n breakeven_enabled=0,\n time_close_enabled=0,\n time_close_hours=None,\n):", ), ( "def _add_false_breakout_key_monitor(\n conn, symbol, direction_sel, upper_px, lower_px, key_px, breakeven_enabled=0,\n):", "def _add_false_breakout_key_monitor(\n conn, symbol, direction_sel, upper_px, lower_px, key_px, breakeven_enabled=0,\n time_close_enabled=0, time_close_hours=None,\n):", ), ( "def _add_fib_key_monitor(conn, symbol, direction_sel, mt, upper_px, lower_px, breakeven_enabled=0):", "def _add_fib_key_monitor(\n conn, symbol, direction_sel, mt, upper_px, lower_px, breakeven_enabled=0,\n time_close_enabled=0, time_close_hours=None,\n):", ), ( " key_sig = typ if typ in KEY_MONITOR_AUTO_TYPES else None\n be_on = breakeven_enabled_from_row(r, 0)\n ok_trade, trade_err, det = _market_open_for_key_monitor(\n conn,\n sym,\n direction,\n exchange_symbol,\n sl_raw,\n tp_raw,\n key_signal_type=key_sig,\n breakeven_enabled=1 if be_on else 0,\n )", " key_sig = typ if typ in KEY_MONITOR_AUTO_TYPES else None\n be_on = breakeven_enabled_from_row(r, 0)\n tc_en, tc_h, _ = time_close_settings_from_row(r)\n ok_trade, trade_err, det = _market_open_for_key_monitor(\n conn,\n sym,\n direction,\n exchange_symbol,\n sl_raw,\n tp_raw,\n key_signal_type=key_sig,\n breakeven_enabled=1 if be_on else 0,\n time_close_enabled=tc_en,\n time_close_hours=tc_h,\n )", ), ( " res = None\n # 做多\n if direction == \"long\":\n if p >= take_profit: res = \"止盈\"\n elif p <= stop_loss: res = \"止损\"\n # 做空\n elif direction == \"short\":\n if p <= take_profit: res = \"止盈\"\n elif p >= stop_loss: res = \"止损\"", " res = None\n if should_trigger_time_close(r):\n res = TIME_CLOSE_RESULT\n # 做多\n if not res and direction == \"long\":\n if p >= take_profit: res = \"止盈\"\n elif p <= stop_loss: res = \"止损\"\n # 做空\n elif not res and direction == \"short\":\n if p <= take_profit: res = \"止盈\"\n elif p >= stop_loss: res = \"止损\"", ), ( ' "SELECT id,symbol,exchange_symbol,direction,trigger_price,stop_loss,initial_stop_loss,take_profit,margin_capital,leverage FROM order_monitors WHERE status=\'active\'"', ' "SELECT id,symbol,exchange_symbol,direction,trigger_price,stop_loss,initial_stop_loss,take_profit,margin_capital,leverage,"\n "time_close_enabled,time_close_hours,time_close_at_ms,opened_at_ms FROM order_monitors WHERE status=\'active\'"', ), ( " apply_order_price_display_fields(\n payload,\n direction=r[\"direction\"],\n entry_price=entry,\n initial_stop_loss=r[\"initial_stop_loss\"],\n stop_loss=r[\"stop_loss\"],\n take_profit=r[\"take_profit\"],\n calc_rr_ratio_fn=calc_rr_ratio,\n exchange_tpsl=exchange_tpsl,\n format_price_fn=format_price_for_symbol,\n symbol=r[\"symbol\"],\n )\n new_sl, new_tp, changed = order_monitor_tpsl_needs_sync(", " apply_order_price_display_fields(\n payload,\n direction=r[\"direction\"],\n entry_price=entry,\n initial_stop_loss=r[\"initial_stop_loss\"],\n stop_loss=r[\"stop_loss\"],\n take_profit=r[\"take_profit\"],\n calc_rr_ratio_fn=calc_rr_ratio,\n exchange_tpsl=exchange_tpsl,\n format_price_fn=format_price_for_symbol,\n symbol=r[\"symbol\"],\n )\n apply_time_close_to_payload(payload, r)\n new_sl, new_tp, changed = order_monitor_tpsl_needs_sync(", ), ( " be_flag = parse_breakeven_enabled_form(d.get(\"breakeven_enabled\"))\n if is_false_breakout_key_monitor_type(mt):", " be_flag = parse_breakeven_enabled_form(d.get(\"breakeven_enabled\"))\n tc_en = parse_time_close_enabled_form(d.get(\"time_close_enabled\"))\n tc_h = parse_time_close_hours_form(d.get(\"time_close_hours\")) if tc_en else None\n if tc_en and not tc_h:\n tc_en = 0\n if is_false_breakout_key_monitor_type(mt):", ), ( " ok_fb, err_fb = _add_false_breakout_key_monitor(\n conn, symbol, direction_sel, upper_px, lower_px, key_px, breakeven_enabled=be_flag,\n )", " ok_fb, err_fb = _add_false_breakout_key_monitor(\n conn, symbol, direction_sel, upper_px, lower_px, key_px, breakeven_enabled=be_flag,\n time_close_enabled=tc_en, time_close_hours=tc_h,\n )", ), ( " f\"|有效期 {FALSE_BREAKOUT_VALIDITY_HOURS}h|移动保本:{'开' if be_flag else '关'}\"\n )", " f\"|有效期 {FALSE_BREAKOUT_VALIDITY_HOURS}h|移动保本:{'开' if be_flag else '关'}\"\n + (f\"|{time_close_label(tc_h)}\" if tc_en else \"\")\n )", ), ( " ok_fib, err_fib = _add_fib_key_monitor(\n conn, symbol, direction_sel, mt, upper_px, lower_px, breakeven_enabled=be_flag,\n )", " ok_fib, err_fib = _add_fib_key_monitor(\n conn, symbol, direction_sel, mt, upper_px, lower_px, breakeven_enabled=be_flag,\n time_close_enabled=tc_en, time_close_hours=tc_h,\n )", ), ( " f\"|移动保本:{'开' if be_flag else '关'}\"\n )\n return redirect(\"/key_monitor\")", " f\"|移动保本:{'开' if be_flag else '关'}\"\n + (f\"|{time_close_label(tc_h)}\" if tc_en else \"\")\n )\n return redirect(\"/key_monitor\")", ), ( " if mt in KEY_MONITOR_AUTO_TYPES:\n extra = f\"|方案:{sl_tp_mode_label(sl_tp_mode)}|移动保本:{'开' if be_flag else '关'}\"", " if mt in KEY_MONITOR_AUTO_TYPES:\n extra = f\"|方案:{sl_tp_mode_label(sl_tp_mode)}|移动保本:{'开' if be_flag else '关'}\"\n if tc_en:\n extra += f\"|{time_close_label(tc_h)}\"", ), ] MARKET_OPEN_OLD = """ breakeven_price = round_price_to_exchange(exchange_symbol, breakeven_raw) be_enabled = 1 if int(breakeven_enabled or 0) != 0 else 0 conn.execute( "INSERT INTO order_monitors " "(symbol, exchange_symbol, direction, trigger_price, stop_loss, initial_stop_loss, take_profit, " "margin_capital, leverage, trade_style, risk_percent, risk_amount, " "breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, breakeven_armed, breakeven_price, breakeven_enabled, " "notional_value, position_ratio, base_amount, order_amount, exchange_order_id, opened_at, opened_at_ms, session_date, monitor_type, key_signal_type) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, exchange_symbol, direction, trigger_price, stop_loss, stop_loss, take_profit, margin_capital, leverage, trade_style, risk_percent, risk_amount_final, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, 0, breakeven_price, be_enabled, notional_value, position_ratio, base_amount, amount, open_order_id, opened_at_bj, opened_at_ms, trading_day, ORDER_MONITOR_TYPE_KEY_AUTO, stored_key_signal_type(key_signal_type), ), )""" MARKET_OPEN_NEW = """ breakeven_price = round_price_to_exchange(exchange_symbol, breakeven_raw) be_enabled = 1 if int(breakeven_enabled or 0) != 0 else 0 tc_en, tc_h, tc_at = time_close_insert_values( time_close_enabled, time_close_hours, opened_at_ms ) conn.execute( "INSERT INTO order_monitors " "(symbol, exchange_symbol, direction, trigger_price, stop_loss, initial_stop_loss, take_profit, " "margin_capital, leverage, trade_style, risk_percent, risk_amount, " "breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, breakeven_armed, breakeven_price, breakeven_enabled, " "notional_value, position_ratio, base_amount, order_amount, exchange_order_id, opened_at, opened_at_ms, session_date, monitor_type, key_signal_type, " "time_close_enabled, time_close_hours, time_close_at_ms) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, exchange_symbol, direction, trigger_price, stop_loss, stop_loss, take_profit, margin_capital, leverage, trade_style, risk_percent, risk_amount_final, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, 0, breakeven_price, be_enabled, notional_value, position_ratio, base_amount, amount, open_order_id, opened_at_bj, opened_at_ms, trading_day, ORDER_MONITOR_TYPE_KEY_AUTO, stored_key_signal_type(key_signal_type), tc_en, tc_h, tc_at, ), )""" FIB_INSERT_OLD = """ opened_at_bj = app_now_str() opened_at_ms = _to_ms_with_fallback(None, opened_at_bj) conn.execute( "INSERT INTO order_monitors " "(symbol, exchange_symbol, direction, trigger_price, stop_loss, initial_stop_loss, take_profit, " "margin_capital, leverage, trade_style, risk_percent, risk_amount, " "breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, breakeven_armed, breakeven_price, breakeven_enabled, " "notional_value, position_ratio, base_amount, order_amount, exchange_order_id, opened_at, opened_at_ms, session_date, monitor_type, key_signal_type) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, exchange_symbol, direction, trigger_price, stop_loss, stop_loss, take_profit, margin_capital, leverage, trade_style, risk_percent, risk_amount_final, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, 0, breakeven_price, 1 if breakeven_enabled_from_row(row, 0) else 0, notional_value, position_ratio, base_amount, amount, exchange_order_id or "", opened_at_bj, opened_at_ms, trading_day, ORDER_MONITOR_TYPE_KEY_AUTO, stored_key_signal_type(typ), ), )""" FIB_INSERT_NEW = """ opened_at_bj = app_now_str() opened_at_ms = _to_ms_with_fallback(None, opened_at_bj) tc_en, tc_h, _ = time_close_settings_from_row(row) tc_en, tc_h, tc_at = time_close_insert_values(tc_en, tc_h, opened_at_ms) conn.execute( "INSERT INTO order_monitors " "(symbol, exchange_symbol, direction, trigger_price, stop_loss, initial_stop_loss, take_profit, " "margin_capital, leverage, trade_style, risk_percent, risk_amount, " "breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, breakeven_armed, breakeven_price, breakeven_enabled, " "notional_value, position_ratio, base_amount, order_amount, exchange_order_id, opened_at, opened_at_ms, session_date, monitor_type, key_signal_type, " "time_close_enabled, time_close_hours, time_close_at_ms) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, exchange_symbol, direction, trigger_price, stop_loss, stop_loss, take_profit, margin_capital, leverage, trade_style, risk_percent, risk_amount_final, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, 0, breakeven_price, 1 if breakeven_enabled_from_row(row, 0) else 0, notional_value, position_ratio, base_amount, amount, exchange_order_id or "", opened_at_bj, opened_at_ms, trading_day, ORDER_MONITOR_TYPE_KEY_AUTO, stored_key_signal_type(typ), tc_en, tc_h, tc_at, ), )""" KEY_FB_OLD = """ be_flag = 1 if int(breakeven_enabled or 0) != 0 else 0 conn.execute( "INSERT INTO key_monitors " "(symbol, monitor_type, direction, upper, lower, " "fib_limit_order_id, fib_entry_price, fib_stop_loss, fib_take_profit, " "fib_order_amount, fib_margin_capital, fib_leverage, breakeven_enabled) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, FALSE_BREAKOUT_MONITOR_TYPE, direction_sel, upper_px, lower_px, oid, entry, sl, tp, float(amount), margin_capital, leverage, be_flag, ), )""" KEY_FB_NEW = """ be_flag = 1 if int(breakeven_enabled or 0) != 0 else 0 tc_en, tc_h, _ = time_close_insert_values(time_close_enabled, time_close_hours, None) conn.execute( "INSERT INTO key_monitors " "(symbol, monitor_type, direction, upper, lower, " "fib_limit_order_id, fib_entry_price, fib_stop_loss, fib_take_profit, " "fib_order_amount, fib_margin_capital, fib_leverage, breakeven_enabled, time_close_enabled, time_close_hours) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, FALSE_BREAKOUT_MONITOR_TYPE, direction_sel, upper_px, lower_px, oid, entry, sl, tp, float(amount), margin_capital, leverage, be_flag, tc_en, tc_h, ), )""" KEY_FIB_OLD = """ be_flag = 1 if int(breakeven_enabled or 0) != 0 else 0 conn.execute( "INSERT INTO key_monitors " "(symbol, monitor_type, direction, upper, lower, " "fib_limit_order_id, fib_entry_price, fib_stop_loss, fib_take_profit, " "fib_order_amount, fib_margin_capital, fib_leverage, breakeven_enabled) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, mt, direction_sel, upper_px, lower_px, oid, entry, sl, tp, float(amount), margin_capital, leverage, be_flag, ), )""" KEY_FIB_NEW = """ be_flag = 1 if int(breakeven_enabled or 0) != 0 else 0 tc_en, tc_h, _ = time_close_insert_values(time_close_enabled, time_close_hours, None) conn.execute( "INSERT INTO key_monitors " "(symbol, monitor_type, direction, upper, lower, " "fib_limit_order_id, fib_entry_price, fib_stop_loss, fib_take_profit, " "fib_order_amount, fib_margin_capital, fib_leverage, breakeven_enabled, time_close_enabled, time_close_hours) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, mt, direction_sel, upper_px, lower_px, oid, entry, sl, tp, float(amount), margin_capital, leverage, be_flag, tc_en, tc_h, ), )""" ADD_KEY_RS_OLD = """ conn.execute( "INSERT INTO key_monitors " "(symbol,monitor_type,direction,upper,lower,sl_tp_mode,manual_take_profit,breakeven_enabled," "max_notify,notify_interval_min) " "VALUES (?,?,?,?,?,?,?,?,?,?)", ( symbol, mt, direction_sel, upper_px, lower_px, sl_tp_mode, manual_tp, be_flag, KEY_ALERT_MAX_TIMES, KEY_ALERT_INTERVAL_MINUTES, ), ) else: conn.execute( "INSERT INTO key_monitors " "(symbol,monitor_type,direction,upper,lower,sl_tp_mode,manual_take_profit,breakeven_enabled) " "VALUES (?,?,?,?,?,?,?,?)", (symbol, mt, direction_sel, upper_px, lower_px, sl_tp_mode, manual_tp, be_flag), )""" ADD_KEY_RS_NEW = """ conn.execute( "INSERT INTO key_monitors " "(symbol,monitor_type,direction,upper,lower,sl_tp_mode,manual_take_profit,breakeven_enabled," "max_notify,notify_interval_min,time_close_enabled,time_close_hours) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, mt, direction_sel, upper_px, lower_px, sl_tp_mode, manual_tp, be_flag, KEY_ALERT_MAX_TIMES, KEY_ALERT_INTERVAL_MINUTES, tc_en, tc_h, ), ) else: conn.execute( "INSERT INTO key_monitors " "(symbol,monitor_type,direction,upper,lower,sl_tp_mode,manual_take_profit,breakeven_enabled," "time_close_enabled,time_close_hours) " "VALUES (?,?,?,?,?,?,?,?,?,?)", (symbol, mt, direction_sel, upper_px, lower_px, sl_tp_mode, manual_tp, be_flag, tc_en, tc_h), )""" ADD_ORDER_OLD = """ breakeven_enabled = 1 if (d.get("breakeven_enabled") or "").strip() in ("1", "true", "on", "yes") else 0 conn.execute( "INSERT INTO order_monitors (symbol, exchange_symbol, direction, trigger_price, stop_loss, initial_stop_loss, take_profit, margin_capital, leverage, trade_style, risk_percent, risk_amount, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, breakeven_armed, breakeven_price, breakeven_enabled, notional_value, position_ratio, base_amount, order_amount, exchange_order_id, opened_at, opened_at_ms, session_date, monitor_type) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, exchange_symbol, direction, trigger_price, stop_loss, stop_loss, take_profit, margin_capital, leverage, trade_style, risk_percent_db, risk_amount_final, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, 0, breakeven_price, breakeven_enabled, notional_value, position_ratio, base_amount, amount, open_order_id, opened_at_bj, opened_at_ms, trading_day, ORDER_MONITOR_TYPE_MANUAL, ) )""" ADD_ORDER_NEW = """ breakeven_enabled = 1 if (d.get("breakeven_enabled") or "").strip() in ("1", "true", "on", "yes") else 0 tc_en = parse_time_close_enabled_form(d.get("time_close_enabled")) tc_h = parse_time_close_hours_form(d.get("time_close_hours")) if tc_en else None if tc_en and not tc_h: tc_en = 0 tc_en, tc_h, tc_at = time_close_insert_values(tc_en, tc_h, opened_at_ms) conn.execute( "INSERT INTO order_monitors (symbol, exchange_symbol, direction, trigger_price, stop_loss, initial_stop_loss, take_profit, margin_capital, leverage, trade_style, risk_percent, risk_amount, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, breakeven_armed, breakeven_price, breakeven_enabled, notional_value, position_ratio, base_amount, order_amount, exchange_order_id, opened_at, opened_at_ms, session_date, monitor_type, time_close_enabled, time_close_hours, time_close_at_ms) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", ( symbol, exchange_symbol, direction, trigger_price, stop_loss, stop_loss, take_profit, margin_capital, leverage, trade_style, risk_percent_db, risk_amount_final, breakeven_rr_trigger, breakeven_offset_pct, breakeven_step_r, 0, breakeven_price, breakeven_enabled, notional_value, position_ratio, base_amount, amount, open_order_id, opened_at_bj, opened_at_ms, trading_day, ORDER_MONITOR_TYPE_MANUAL, tc_en, tc_h, tc_at, ) )""" BIG_BLOCKS = [ (MARKET_OPEN_OLD, MARKET_OPEN_NEW), (FIB_INSERT_OLD, FIB_INSERT_NEW), (KEY_FB_OLD, KEY_FB_NEW), (KEY_FIB_OLD, KEY_FIB_NEW), (ADD_KEY_RS_OLD, ADD_KEY_RS_NEW), (ADD_ORDER_OLD, ADD_ORDER_NEW), ] def patch(path: Path) -> None: text = path.read_text(encoding="utf-8") for old, new in REPLACEMENTS + BIG_BLOCKS: if old in text: text = text.replace(old, new, 1) path.write_text(text, encoding="utf-8") print("done", path.name) def main() -> None: for f in FILES: patch(f) if __name__ == "__main__": main()