Require real ask depth for options and hedge opens.
Block mark-as-ask opens, show reference mark when no depth, cap sheets to ask size; leave close paths unchanged. Document in docs/更新文档.md. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -17,7 +17,12 @@ from lib.options.options_pricing_lib import (
|
||||
min_sz_from_meta,
|
||||
premium_per_sheet,
|
||||
)
|
||||
from lib.exchange.okx_options_lib import _safe_float, td_mode_for_option_buy
|
||||
from lib.exchange.okx_options_lib import (
|
||||
_safe_float,
|
||||
cap_option_buy_sheets_to_ask_depth,
|
||||
option_buy_liquidity_ok,
|
||||
td_mode_for_option_buy,
|
||||
)
|
||||
|
||||
|
||||
def _env_bool(key: str, default: bool = False) -> bool:
|
||||
@@ -419,8 +424,30 @@ def register_options_routes(app: Flask, cfg: dict[str, Any]) -> None:
|
||||
eth_amount = float(request.args.get("eth_amount"))
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
if ask is None or ask <= 0:
|
||||
return jsonify({**q, "ok": False, "msg": "暂无卖一价"})
|
||||
ask = q.get("ask")
|
||||
ask_sz = q.get("ask_sz")
|
||||
can_open, block_msg = option_buy_liquidity_ok(ask, ask_sz)
|
||||
if not can_open:
|
||||
# 合约可报价,但不可开仓:返回参考标记价供展示
|
||||
return jsonify(
|
||||
{
|
||||
**q,
|
||||
"ok": True,
|
||||
"can_open": False,
|
||||
"msg": block_msg or q.get("open_block_msg") or "暂无卖一深度,无法买入",
|
||||
"quote_per_unit": None,
|
||||
"premium_per_sheet": None,
|
||||
"sizing": {
|
||||
"ok": False,
|
||||
"msg": block_msg or "暂无卖一深度,无法买入",
|
||||
"sheets": 0,
|
||||
"eth_amount": 0.0,
|
||||
"total_premium": 0.0,
|
||||
},
|
||||
"available_usdc": available_usdc,
|
||||
"budget_full_usdc": budget if mode == "budget_full" else None,
|
||||
}
|
||||
)
|
||||
sizing = calc_order_size(
|
||||
quote_per_unit=float(ask),
|
||||
ct_mult=float(ct_mult),
|
||||
@@ -431,6 +458,32 @@ def register_options_routes(app: Flask, cfg: dict[str, Any]) -> None:
|
||||
sheets=sheet_count if mode == "sheets" else None,
|
||||
budget_cap=budget_cap if mode in ("budget_full", "sheets", "eth_amount") else None,
|
||||
)
|
||||
if sizing.get("ok"):
|
||||
capped, cap_msg = cap_option_buy_sheets_to_ask_depth(
|
||||
int(sizing.get("sheets") or 0),
|
||||
ask_sz,
|
||||
min_sz=int(min_sz),
|
||||
)
|
||||
if capped is None:
|
||||
sizing = {
|
||||
"ok": False,
|
||||
"msg": cap_msg,
|
||||
"sheets": 0,
|
||||
"eth_amount": 0.0,
|
||||
"total_premium": 0.0,
|
||||
}
|
||||
elif capped < int(sizing.get("sheets") or 0):
|
||||
sizing = calc_order_size(
|
||||
quote_per_unit=float(ask),
|
||||
ct_mult=float(ct_mult),
|
||||
min_sz=int(min_sz),
|
||||
sheets=capped,
|
||||
budget_cap=budget_cap if mode in ("budget_full", "sheets", "eth_amount") else None,
|
||||
)
|
||||
if sizing.get("ok"):
|
||||
sizing["ask_depth_capped"] = True
|
||||
sizing["ask_sz"] = ask_sz
|
||||
sizing["msg"] = f"已按卖一深度限制为 {capped} 张"
|
||||
q = _attach_close_preview(
|
||||
cfg,
|
||||
ex,
|
||||
@@ -441,6 +494,7 @@ def register_options_routes(app: Flask, cfg: dict[str, Any]) -> None:
|
||||
return jsonify(
|
||||
{
|
||||
**q,
|
||||
"can_open": True,
|
||||
"quote_per_unit": ask,
|
||||
"premium_per_sheet": premium_per_sheet(float(ask), float(ct_mult)),
|
||||
"sizing": sizing,
|
||||
@@ -474,8 +528,18 @@ def register_options_routes(app: Flask, cfg: dict[str, Any]) -> None:
|
||||
if not q.get("ok"):
|
||||
return jsonify(q)
|
||||
ask = q.get("ask")
|
||||
if ask is None or ask <= 0:
|
||||
return jsonify({"ok": False, "msg": "暂无卖一价,无法买入"})
|
||||
ask_sz = q.get("ask_sz")
|
||||
can_open, block_msg = option_buy_liquidity_ok(ask, ask_sz)
|
||||
if not can_open:
|
||||
return jsonify(
|
||||
{
|
||||
"ok": False,
|
||||
"msg": block_msg or q.get("open_block_msg") or "暂无卖一深度,无法买入",
|
||||
"can_open": False,
|
||||
"mark": q.get("mark"),
|
||||
"ref_ask": q.get("ref_ask"),
|
||||
}
|
||||
)
|
||||
ct_mult = float(q.get("ct_mult") or 0.01)
|
||||
min_sz = int(q.get("min_sz") or 1)
|
||||
eth_amount = None
|
||||
@@ -510,6 +574,20 @@ def register_options_routes(app: Flask, cfg: dict[str, Any]) -> None:
|
||||
if not sizing.get("ok"):
|
||||
return jsonify({"ok": False, "msg": sizing.get("msg") or "张数计算失败", "sizing": sizing})
|
||||
sheets = int(sizing["sheets"])
|
||||
capped, cap_msg = cap_option_buy_sheets_to_ask_depth(sheets, ask_sz, min_sz=min_sz)
|
||||
if capped is None:
|
||||
return jsonify({"ok": False, "msg": cap_msg or "卖一深度不足,无法买入"})
|
||||
if capped < sheets:
|
||||
sizing = calc_order_size(
|
||||
quote_per_unit=float(ask),
|
||||
ct_mult=ct_mult,
|
||||
min_sz=min_sz,
|
||||
sheets=capped,
|
||||
budget_cap=budget_cap if mode in ("budget_full", "sheets", "eth_amount") else None,
|
||||
)
|
||||
if not sizing.get("ok"):
|
||||
return jsonify({"ok": False, "msg": sizing.get("msg") or "张数计算失败", "sizing": sizing})
|
||||
sheets = int(sizing["sheets"])
|
||||
tick_sz = q.get("tick_sz")
|
||||
order = cfg["place_option_limit_order"](
|
||||
ex,
|
||||
|
||||
Reference in New Issue
Block a user