feat期权盈亏按交易账户快照结算:一次一仓、持仓禁划转、卖回后冻结。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-09 00:29:47 +08:00
parent e0e2a94322
commit 260bfd1f29
12 changed files with 659 additions and 157 deletions
+42 -12
View File
@@ -216,6 +216,16 @@ def open_coin_option_buy_full(
conn.commit()
except Exception:
pass
# 开仓前有可卖标的币 → 拒开(规格:先卖回)
from lib.options.options_account_pnl_lib import (
fetch_trading_usdt,
sellable_coin_blocks_open_msg,
)
coin_block = sellable_coin_blocks_open_msg(ex, underlying)
if coin_block:
return {"ok": False, "msg": coin_block, "can_open": False}
trading_usdt_before = fetch_trading_usdt(cfg, ex)
# 1) 仅买「权利金×现货缓冲」所需 USDT,不全额兑换预算
coin_before = _spot_bridge.fetch_trading_coin_available(ex, underlying) or 0.0
buy = _spot_bridge.spot_market_buy_coin_with_usdt(ex, underlying=underlying, usdt_amount=buy_usdt)
@@ -514,6 +524,7 @@ def open_coin_option_buy_full(
premium_ccy=premium_ccy,
open_fee=open_fee,
open_index_px=idx_open,
trading_usdt_before=trading_usdt_before,
profit_exit_enabled=profit_exit_enabled,
profit_exit_mult=profit_exit_mult,
)
@@ -594,15 +605,20 @@ def _insert_coin_trade(conn: Any, **kwargs: Any) -> int:
open_index_px = None
except (TypeError, ValueError):
open_index_px = None
tusdt_before = kwargs.get("trading_usdt_before")
try:
tusdt_before = float(tusdt_before) if tusdt_before is not None else None
except (TypeError, ValueError):
tusdt_before = None
cur = conn.execute(
"""
INSERT INTO options_trades(
inst_id, underlying, opt_type, strike, exp_time, sheets, eth_amount,
open_quote, premium_paid, status, signal_note, exchange_ord_id,
margin_mode, premium_ccy, bridge_id, budget_usdt,
open_fee, fee_ccy, open_index_px,
open_fee, fee_ccy, open_index_px, trading_usdt_before, pnl_settled,
profit_exit_enabled, profit_exit_mult, profit_exit_state, created_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'open', ?, ?, 'coin', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'open', ?, ?, 'coin', ?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?)
""",
(
kwargs["inst_id"],
@@ -622,6 +638,7 @@ def _insert_coin_trade(conn: Any, **kwargs: Any) -> int:
open_fee,
fee_ccy,
open_index_px,
tusdt_before,
pe,
pe_mult,
pe_state,
@@ -668,18 +685,18 @@ def maybe_sell_spot_after_close(
underlying=underlying,
inst_id=inst_id,
)
# 模拟盘:卖回后按桥上真实 USDT 净额回写已实现盈亏
# 卖回成功:交易账户 after − 开仓 before → 冻结本单盈亏
try:
from lib.sim.mode_lib import is_sim_mode
from lib.options.options_stats_lib import sync_sim_cash_realized_pnl_usdt
from lib.options.options_account_pnl_lib import try_settle_after_sellback
if is_sim_mode(cfg["get_db"]):
conn = cfg["get_db"]()
try:
sync_sim_cash_realized_pnl_usdt(conn, ex)
conn.commit()
finally:
conn.close()
if (result or {}).get("ok"):
bid = (result or {}).get("bridge_id")
try_settle_after_sellback(
cfg["get_db"],
ex,
bridge_id=int(bid) if bid is not None else None,
cfg=cfg,
)
except Exception:
pass
return result
@@ -749,6 +766,19 @@ def sweep_spot_after_options_flat(
underlying=uly,
inst_id=None,
)
if (out or {}).get("ok"):
try:
from lib.options.options_account_pnl_lib import try_settle_after_sellback
bid = (out or {}).get("bridge_id")
try_settle_after_sellback(
cfg["get_db"],
exchange,
bridge_id=int(bid) if bid is not None else None,
cfg=cfg,
)
except Exception:
pass
sold.append({"underlying": uly, **(out or {})})
except Exception as e:
sold.append({"underlying": uly, "ok": False, "msg": str(e)})