币本位买币改为按最大可开张数×权利金×可配缓冲,不全额兑换USDT
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -17,6 +17,7 @@ from lib.options.options_margin_mode_lib import (
|
||||
is_coin_margin_mode,
|
||||
margin_mode_from_inst_id,
|
||||
normalize_options_margin_mode,
|
||||
plan_coin_open_by_budget,
|
||||
premium_ccy_for_mode,
|
||||
)
|
||||
from lib.options.options_spot_bridge_lib import (
|
||||
@@ -56,8 +57,9 @@ def open_coin_option_buy_full(
|
||||
target_index: float | None = None,
|
||||
profit_exit_enabled: bool = False,
|
||||
profit_exit_mult: float = 1.0,
|
||||
target_sheets: int | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""先买满 USDT 预算对应的币,再按卖一尽量开满."""
|
||||
"""先按最大可开张数估权利金×现货缓冲买币,再开对应张数(不全额兑换预算)."""
|
||||
from lib.options.options_db import init_options_tables
|
||||
from lib.options.options_position_limit_lib import (
|
||||
compound_full_single_position_block_msg,
|
||||
@@ -111,16 +113,56 @@ def open_coin_option_buy_full(
|
||||
"can_open": False,
|
||||
}
|
||||
|
||||
# 1) 买币(用买入前后可用差作为本轮币量,避免叠加原有现货)
|
||||
ct_mult = float(q.get("ct_mult") or 0.01)
|
||||
min_sz = int(q.get("min_sz") or 1)
|
||||
idx = None
|
||||
try:
|
||||
idx = float(q.get("index_px") or q.get("idxPx") or 0)
|
||||
except (TypeError, ValueError):
|
||||
idx = 0.0
|
||||
if idx <= 0:
|
||||
try:
|
||||
from lib.exchange.okx_options_lib import fetch_index_price
|
||||
|
||||
idx = float(fetch_index_price(ex, f"{underlying}-USD") or 0)
|
||||
except Exception:
|
||||
idx = 0.0
|
||||
|
||||
plan = plan_coin_open_by_budget(
|
||||
quote_per_unit=float(ask),
|
||||
ct_mult=ct_mult,
|
||||
min_sz=min_sz,
|
||||
budget_usdt=budget_usdt,
|
||||
index_px=float(idx),
|
||||
ask_sz=ask_sz,
|
||||
target_sheets=target_sheets,
|
||||
)
|
||||
if not plan.get("ok"):
|
||||
return {
|
||||
"ok": False,
|
||||
"msg": plan.get("msg") or "无法规划买币张数",
|
||||
"plan": plan,
|
||||
"budget": budget_info,
|
||||
"can_open": False,
|
||||
}
|
||||
buy_usdt = float(plan["buy_usdt"])
|
||||
sheets = int(plan["sheets"])
|
||||
|
||||
# 1) 仅买「权利金×现货缓冲」所需 USDT,不全额兑换预算
|
||||
coin_before = fetch_trading_coin_available(ex, underlying) or 0.0
|
||||
buy = spot_market_buy_coin_with_usdt(ex, underlying=underlying, usdt_amount=budget_usdt)
|
||||
buy = spot_market_buy_coin_with_usdt(ex, underlying=underlying, usdt_amount=buy_usdt)
|
||||
if not buy.get("ok"):
|
||||
return {"ok": False, "msg": f"现货买入 {underlying} 失败: {buy.get('msg')}", "budget": budget_info}
|
||||
return {
|
||||
"ok": False,
|
||||
"msg": f"现货买入 {underlying} 失败: {buy.get('msg')}",
|
||||
"budget": budget_info,
|
||||
"plan": plan,
|
||||
}
|
||||
bridge_id = insert_bridge(
|
||||
conn,
|
||||
underlying=underlying,
|
||||
status=BRIDGE_BOUGHT,
|
||||
budget_usdt=budget_usdt,
|
||||
budget_usdt=buy_usdt,
|
||||
buy_ord_id=str(buy.get("ord_id") or ""),
|
||||
inst_id=inst_id,
|
||||
message="已买币,待开期权",
|
||||
@@ -143,6 +185,7 @@ def open_coin_option_buy_full(
|
||||
"msg": "买币后读不到可用余额,已尝试卖回 USDT",
|
||||
"rollback": rb,
|
||||
"budget": budget_info,
|
||||
"plan": plan,
|
||||
}
|
||||
coin_bought = max(0.0, float(coin_after) - float(coin_before or 0))
|
||||
if coin_bought <= 0:
|
||||
@@ -155,8 +198,6 @@ def open_coin_option_buy_full(
|
||||
return {"ok": False, "msg": "买币后可用增量无效", "rollback": rb, "budget": budget_info}
|
||||
update_bridge(conn, bridge_id, coin_bought=float(coin_bought))
|
||||
|
||||
ct_mult = float(q.get("ct_mult") or 0.01)
|
||||
min_sz = int(q.get("min_sz") or 1)
|
||||
sizing = calc_sheets_from_coin_balance(
|
||||
quote_per_unit=float(ask),
|
||||
ct_mult=ct_mult,
|
||||
@@ -172,9 +213,10 @@ def open_coin_option_buy_full(
|
||||
reason=sizing.get("msg") or "张数不足",
|
||||
coin_amount=float(coin_bought),
|
||||
)
|
||||
return {"ok": False, "msg": sizing.get("msg"), "sizing": sizing, "rollback": rb, "budget": budget_info}
|
||||
return {"ok": False, "msg": sizing.get("msg"), "sizing": sizing, "rollback": rb, "budget": budget_info, "plan": plan}
|
||||
|
||||
sheets = int(sizing["sheets"])
|
||||
# 实盘以买到的币为准,但不超过规划张数
|
||||
sheets = min(int(sizing["sheets"]), int(plan["sheets"]))
|
||||
capped, cap_msg = cap_option_buy_sheets_to_ask_depth(sheets, ask_sz, min_sz=min_sz)
|
||||
if capped is None:
|
||||
rb = rollback_bought_coin_to_usdt(
|
||||
@@ -190,6 +232,13 @@ def open_coin_option_buy_full(
|
||||
"coin_premium": round(sheets * float(ask) * ct_mult, 8),
|
||||
"ask_depth_capped": True,
|
||||
}
|
||||
else:
|
||||
sizing = {
|
||||
"ok": True,
|
||||
"sheets": sheets,
|
||||
"eth_amount": round(sheets * ct_mult, 8),
|
||||
"coin_premium": round(sheets * float(ask) * ct_mult, 8),
|
||||
}
|
||||
|
||||
tick_sz = q.get("tick_sz")
|
||||
order = cfg["place_option_limit_order"](
|
||||
@@ -292,7 +341,7 @@ def open_coin_option_buy_full(
|
||||
signal_note=signal_note,
|
||||
exchange_ord_id=ord_id,
|
||||
bridge_id=bridge_id,
|
||||
budget_usdt=budget_usdt,
|
||||
budget_usdt=buy_usdt,
|
||||
premium_ccy=premium_ccy,
|
||||
profit_exit_enabled=profit_exit_enabled,
|
||||
profit_exit_mult=profit_exit_mult,
|
||||
|
||||
Reference in New Issue
Block a user