补齐币本位期权开平仓微信推送:单位用ETH/BTC,手动/目标/翻倍平仓与翻倍提醒均必达。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-20 17:57:58 +08:00
parent a7d0c2f875
commit 440778e9e6
6 changed files with 122 additions and 44 deletions
+51 -6
View File
@@ -23,6 +23,30 @@ def _opt_type_label(opt_type: Any) -> str:
return t or ""
def resolve_premium_ccy(
raw: Any = None,
*,
inst_id: str = "",
underlying: str = "",
) -> str:
"""权利金计价币种:币本位 ETH/BTC,U 本位 USDC."""
s = str(raw or "").strip().upper()
if s:
return s
inst = (inst_id or "").strip()
u = (underlying or "").strip().upper()
if not u and inst:
u = inst.split("-")[0].upper() if "-" in inst else "ETH"
try:
from lib.options.options_margin_mode_lib import margin_mode_from_inst_id, premium_ccy_for_mode
if inst:
return premium_ccy_for_mode(margin_mode_from_inst_id(inst), u or "ETH")
except Exception:
pass
return u if u in ("ETH", "BTC") else "USDC"
def ensure_options_notify_columns(conn: sqlite3.Connection) -> None:
for ddl in (
"ALTER TABLE options_trades ADD COLUMN wechat_open_sent INTEGER DEFAULT 0",
@@ -57,7 +81,9 @@ def build_options_open_message(
target_index: Any = None,
signal_note: str = "",
trade_id: Any = None,
premium_ccy: Any = None,
) -> str:
ccy = resolve_premium_ccy(premium_ccy, inst_id=inst_id, underlying=underlying)
lines = [
"【OKX期权·开仓】",
f"账户:{account_label or 'OKX期权'}",
@@ -69,8 +95,8 @@ def build_options_open_message(
f"合约:{inst_id}",
f"标的:{(underlying or '')} · {_opt_type_label(opt_type)}",
f"张数:{sheets if sheets is not None else ''}",
f"开仓报价:{_fmt(open_quote)} USDC",
f"权利金:{_fmt(premium_paid)} USDC",
f"开仓报价:{_fmt(open_quote)} {ccy}",
f"权利金:{_fmt(premium_paid)} {ccy}",
]
)
if target_index is not None and str(target_index).strip() != "":
@@ -98,7 +124,9 @@ def build_options_close_message(
target_index: Any = None,
trigger_idx: Any = None,
trade_id: Any = None,
premium_ccy: Any = None,
) -> str:
ccy = resolve_premium_ccy(premium_ccy, inst_id=inst_id, underlying=underlying)
lines = [
"【OKX期权·平仓】",
f"账户:{account_label or 'OKX期权'}",
@@ -111,9 +139,9 @@ def build_options_close_message(
f"标的:{(underlying or '')} · {_opt_type_label(opt_type)}",
f"原因:{(reason or '平仓').strip()}",
f"张数:{sheets if sheets is not None else ''}",
f"平仓报价:{_fmt(close_quote)} USDC",
f"已付/收回:{_fmt(premium_paid)} / {_fmt(premium_received)} USDC",
f"实现盈亏:{_fmt(realized_pnl, 4)} USDC",
f"平仓报价:{_fmt(close_quote)} {ccy}",
f"已付/收回:{_fmt(premium_paid)} / {_fmt(premium_received)} {ccy}",
f"实现盈亏:{_fmt(realized_pnl, 4)} {ccy}",
]
)
if target_index is not None and str(target_index).strip() != "":
@@ -142,15 +170,23 @@ def notify_options_open(
open_quote: Any = None,
target_index: Any = None,
signal_note: str = "",
premium_ccy: Any = None,
) -> bool:
ensure_options_notify_columns(conn) if conn is not None else None
row_ccy = premium_ccy
if conn is not None and trade_id is not None:
row = conn.execute(
"SELECT wechat_open_sent FROM options_trades WHERE id=?",
"SELECT wechat_open_sent, premium_ccy, underlying FROM options_trades WHERE id=?",
(int(trade_id),),
).fetchone()
if row and int(row["wechat_open_sent"] or 0):
return False
if row is not None:
if not row_ccy:
row_ccy = row["premium_ccy"] if "premium_ccy" in row.keys() else None
if not underlying:
underlying = str(row["underlying"] or "") if "underlying" in row.keys() else underlying
ccy = resolve_premium_ccy(row_ccy, inst_id=inst_id, underlying=underlying)
msg = build_options_open_message(
account_label=str(cfg.get("account_label") or "OKX期权"),
inst_id=inst_id,
@@ -162,6 +198,7 @@ def notify_options_open(
target_index=target_index,
signal_note=signal_note,
trade_id=trade_id,
premium_ccy=ccy,
)
ok = notify_options_send(cfg, msg)
if ok and conn is not None and trade_id is not None:
@@ -198,6 +235,7 @@ def notify_options_close(
target_index: Any = None,
trigger_idx: Any = None,
force: bool = False,
premium_ccy: Any = None,
) -> bool:
"""平仓必发.默认按 trade_id / 同合约未标记行幂等."""
if conn is not None:
@@ -245,6 +283,11 @@ def notify_options_close(
pending = [r for r in rows if not int(r.get("wechat_close_sent") or 0)]
if not pending and not force:
return False
ccy = resolve_premium_ccy(
premium_ccy or head.get("premium_ccy"),
inst_id=inst_id or str(head.get("inst_id") or ""),
underlying=underlying or str(head.get("underlying") or ""),
)
msg = build_options_close_message(
account_label=str(cfg.get("account_label") or "OKX期权"),
inst_id=inst_id or str(head.get("inst_id") or ""),
@@ -259,6 +302,7 @@ def notify_options_close(
target_index=target_index,
trigger_idx=trigger_idx,
trade_id=head.get("id") if len(rows) == 1 else None,
premium_ccy=ccy,
)
ok = notify_options_send(cfg, msg)
if ok and conn is not None:
@@ -288,6 +332,7 @@ def notify_options_close(
target_index=target_index,
trigger_idx=trigger_idx,
trade_id=trade_id,
premium_ccy=resolve_premium_ccy(premium_ccy, inst_id=inst_id, underlying=underlying),
)
return notify_options_send(cfg, msg)