fix: Gate force-close badge and classify midnight closes correctly
Narrow executing window to 15 minutes after the hour, show countdown when flat, run force_close before reconcile, and map 00:00 synced closes to 强制清仓 instead of 手动平仓. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -123,6 +123,8 @@ from lib.trade.time_close_lib import (
|
||||
)
|
||||
from lib.trade.force_close_lib import (
|
||||
apply_force_close_to_payload,
|
||||
apply_force_close_display_result,
|
||||
coerce_force_close_result,
|
||||
enrich_orders_force_close,
|
||||
force_close_template_context,
|
||||
)
|
||||
@@ -2106,6 +2108,12 @@ def to_effective_trade_dict(row):
|
||||
item.get("effective_result"),
|
||||
item.get("effective_pnl_amount"),
|
||||
)
|
||||
item["effective_result"] = apply_force_close_display_result(
|
||||
item.get("effective_result"),
|
||||
item.get("effective_closed_at"),
|
||||
enabled=FORCE_CLOSE_ENABLED,
|
||||
bj_hour=FORCE_CLOSE_BJ_HOUR,
|
||||
)
|
||||
return item
|
||||
|
||||
|
||||
@@ -4084,6 +4092,17 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None, *, prefer_m
|
||||
交易所已无仓、本地仍为 active 时,推断平仓类型/时间/盈亏。
|
||||
返回 (result, pnl_amount, closed_at_str, miss_reason)。
|
||||
"""
|
||||
|
||||
def _finish(result, pnl_amount, closed_at_str, miss_reason):
|
||||
res, note = coerce_force_close_result(
|
||||
result,
|
||||
closed_at_str,
|
||||
enabled=FORCE_CLOSE_ENABLED,
|
||||
bj_hour=FORCE_CLOSE_BJ_HOUR,
|
||||
miss_reason=miss_reason,
|
||||
)
|
||||
return res, pnl_amount, closed_at_str, note
|
||||
|
||||
direction = row["direction"]
|
||||
sym = row["symbol"]
|
||||
trigger_price = row["trigger_price"]
|
||||
@@ -4109,7 +4128,7 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None, *, prefer_m
|
||||
if pnl_hist is not None:
|
||||
note = "中控平仓后按 Gate 平仓历史同步盈亏" if prefer_manual else "按 Gate 平仓历史同步盈亏"
|
||||
res = "手动平仓" if prefer_manual else "外部平仓"
|
||||
return (res, float(pnl_hist), closed_at_str, note)
|
||||
return _finish(res, float(pnl_hist), closed_at_str, note)
|
||||
|
||||
if exit_px is None or exit_px <= 0:
|
||||
p = get_price(sym)
|
||||
@@ -4117,13 +4136,13 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None, *, prefer_m
|
||||
guessed = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, p)
|
||||
if guessed:
|
||||
pnl = calc_pnl(direction, trigger_price, p, margin_capital, leverage)
|
||||
return (
|
||||
return _finish(
|
||||
normalize_result_with_pnl(guessed, pnl),
|
||||
pnl,
|
||||
closed_at_str,
|
||||
"未能拉取成交明细,按当前市价与止盈/止损位近似归类(建议核对交易所账单)",
|
||||
)
|
||||
return (
|
||||
return _finish(
|
||||
"外部平仓",
|
||||
0.0,
|
||||
closed_at_str,
|
||||
@@ -4133,20 +4152,20 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None, *, prefer_m
|
||||
result = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, exit_px)
|
||||
pnl = calc_pnl(direction, trigger_price, exit_px, margin_capital, leverage)
|
||||
if prefer_manual:
|
||||
return (
|
||||
return _finish(
|
||||
"手动平仓",
|
||||
pnl,
|
||||
closed_at_str,
|
||||
"中控平仓后按交易所成交记录同步",
|
||||
)
|
||||
if result:
|
||||
return (
|
||||
return _finish(
|
||||
normalize_result_with_pnl(result, pnl),
|
||||
pnl,
|
||||
closed_at_str,
|
||||
"按交易所成交记录同步为止盈/止损平仓",
|
||||
)
|
||||
return (
|
||||
return _finish(
|
||||
"外部平仓",
|
||||
pnl,
|
||||
closed_at_str,
|
||||
@@ -6553,10 +6572,10 @@ def background_task():
|
||||
try:
|
||||
auto_transfer_once_per_day()
|
||||
conn = get_db()
|
||||
force_close_before_reset()
|
||||
reconcile_external_closes(conn)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
force_close_before_reset()
|
||||
check_fib_key_monitors()
|
||||
check_trigger_entry_key_monitors()
|
||||
_roll_cfg = app.extensions.get("strategy_roll_cfg")
|
||||
@@ -7092,6 +7111,7 @@ def render_main_page(page="trade", embed_mode=None):
|
||||
FORCE_CLOSE_ENABLED,
|
||||
FORCE_CLOSE_BJ_HOUR,
|
||||
now_ms=int(app_now().timestamp() * 1000),
|
||||
has_active_positions=bool(order_list),
|
||||
),
|
||||
**embed_context_extras("gate"),
|
||||
)
|
||||
@@ -7194,6 +7214,7 @@ def api_account_snapshot():
|
||||
FORCE_CLOSE_ENABLED,
|
||||
FORCE_CLOSE_BJ_HOUR,
|
||||
now_ms=int(now.timestamp() * 1000),
|
||||
has_active_positions=position_limit_count > 0,
|
||||
),
|
||||
})
|
||||
|
||||
@@ -7535,6 +7556,7 @@ def api_price_snapshot():
|
||||
**force_close_template_context(
|
||||
FORCE_CLOSE_ENABLED,
|
||||
FORCE_CLOSE_BJ_HOUR,
|
||||
has_active_positions=bool(order_prices),
|
||||
),
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user