Add HEDGE_PO_MODE instance modes with shared sim/live path.
Lock one mode per instance/subaccount, cross-asset BTC option/ETH perp sizing, combo-U exit, and ship docs/tests/audit. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -141,8 +141,14 @@ def size_from_premium(
|
||||
ratio: float,
|
||||
contract_size: float,
|
||||
exec_factor: float = PREMIUM_EXEC_FACTOR,
|
||||
option_index: Optional[float] = None,
|
||||
perp_index: Optional[float] = None,
|
||||
) -> dict[str, Any]:
|
||||
"""权利金×0.95 → ETH 两位小数 → 期权张 → 永续跟比例."""
|
||||
"""权利金×0.95 → 币两位小数 → 期权张 → 永续跟比例.
|
||||
|
||||
同币:永续币 = 期权币 / ratio.
|
||||
跨币(传入 option_index 与 perp_index):永续名义U = 期权名义U × (1/ratio).
|
||||
"""
|
||||
budget = float(premium_budget or 0)
|
||||
a = float(ask or 0)
|
||||
ct = float(ct_mult or 0.01)
|
||||
@@ -155,23 +161,25 @@ def size_from_premium(
|
||||
"msg": "定仓参数无效",
|
||||
"usable_premium": round(usable, 4),
|
||||
"eth_qty": 0.0,
|
||||
"coin_qty": 0.0,
|
||||
"sheets": 0.0,
|
||||
"perp_eth": 0.0,
|
||||
"contracts": 0.0,
|
||||
}
|
||||
# ask 为每 1 币权利金;ETH 数量 = usable / ask
|
||||
eth_qty = floor2(usable / a)
|
||||
if eth_qty <= 0:
|
||||
# ask 为每 1 币权利金;币数量 = usable / ask
|
||||
coin_qty = floor2(usable / a)
|
||||
if coin_qty <= 0:
|
||||
return {
|
||||
"ok": False,
|
||||
"msg": "权利金不足以买入 0.01 ETH 名义期权",
|
||||
"msg": "权利金不足以买入 0.01 币名义期权",
|
||||
"usable_premium": round(usable, 4),
|
||||
"eth_qty": 0.0,
|
||||
"coin_qty": 0.0,
|
||||
"sheets": 0.0,
|
||||
"perp_eth": 0.0,
|
||||
"contracts": 0.0,
|
||||
}
|
||||
sheets = eth_qty / ct
|
||||
sheets = coin_qty / ct
|
||||
# 张数向下取整到整数张(OKX 期权常见整张)
|
||||
sheets_i = float(math.floor(sheets + 1e-12))
|
||||
if sheets_i <= 0:
|
||||
@@ -179,27 +187,132 @@ def size_from_premium(
|
||||
"ok": False,
|
||||
"msg": "换算期权张数不足 1 张",
|
||||
"usable_premium": round(usable, 4),
|
||||
"eth_qty": eth_qty,
|
||||
"eth_qty": coin_qty,
|
||||
"coin_qty": coin_qty,
|
||||
"sheets": 0.0,
|
||||
"perp_eth": 0.0,
|
||||
"contracts": 0.0,
|
||||
}
|
||||
# 用整张回写 ETH,保持与下单一致
|
||||
eth_qty = round(sheets_i * ct, 2)
|
||||
perp_eth = eth_qty / r
|
||||
# 用整张回写币量,保持与下单一致
|
||||
coin_qty = round(sheets_i * ct, 2)
|
||||
oi = _sf(option_index)
|
||||
pi = _sf(perp_index)
|
||||
cross = oi is not None and pi is not None and oi > 0 and pi > 0 and abs(oi - pi) > 1e-6
|
||||
if cross or (oi is not None and pi is not None and oi > 0 and pi > 0):
|
||||
from lib.hedge_plan.hedge_po_mode_lib import size_cross_notional
|
||||
|
||||
cross_sz = size_cross_notional(
|
||||
option_coin_qty=coin_qty,
|
||||
option_index=float(oi),
|
||||
perp_index=float(pi),
|
||||
contract_size=cs,
|
||||
notional_k=(1.0 / r) if r > 0 else None,
|
||||
)
|
||||
if not cross_sz.get("ok"):
|
||||
return {
|
||||
"ok": False,
|
||||
"msg": cross_sz.get("msg") or "跨币定仓失败",
|
||||
"usable_premium": round(usable, 4),
|
||||
"eth_qty": coin_qty,
|
||||
"coin_qty": coin_qty,
|
||||
"sheets": sheets_i,
|
||||
"perp_eth": 0.0,
|
||||
"contracts": 0.0,
|
||||
}
|
||||
perp_coin = float(cross_sz["perp_coin"])
|
||||
contracts = float(cross_sz["contracts"])
|
||||
premium_est = a * sheets_i * ct
|
||||
return {
|
||||
"ok": True,
|
||||
"msg": "",
|
||||
"usable_premium": round(usable, 4),
|
||||
"eth_qty": coin_qty,
|
||||
"coin_qty": coin_qty,
|
||||
"sheets": sheets_i,
|
||||
"perp_eth": round(perp_coin, 6),
|
||||
"contracts": contracts,
|
||||
"premium_est": round(premium_est, 4),
|
||||
"ratio": r,
|
||||
"exec_factor": float(exec_factor or PREMIUM_EXEC_FACTOR),
|
||||
"option_notional_usdt": cross_sz.get("option_notional_usdt"),
|
||||
"perp_notional_usdt": cross_sz.get("perp_notional_usdt"),
|
||||
"notional_k": cross_sz.get("notional_k"),
|
||||
"cross_asset": bool(cross),
|
||||
}
|
||||
perp_eth = coin_qty / r
|
||||
contracts = perp_eth / cs
|
||||
premium_est = a * sheets_i * ct
|
||||
return {
|
||||
"ok": True,
|
||||
"msg": "",
|
||||
"usable_premium": round(usable, 4),
|
||||
"eth_qty": eth_qty,
|
||||
"eth_qty": coin_qty,
|
||||
"coin_qty": coin_qty,
|
||||
"sheets": sheets_i,
|
||||
"perp_eth": round(perp_eth, 6),
|
||||
"contracts": contracts,
|
||||
"premium_est": round(premium_est, 4),
|
||||
"ratio": r,
|
||||
"exec_factor": float(exec_factor or PREMIUM_EXEC_FACTOR),
|
||||
"cross_asset": False,
|
||||
}
|
||||
|
||||
|
||||
def contracts_from_option_sheets(
|
||||
*,
|
||||
sheets: float,
|
||||
ct_mult: float,
|
||||
ratio: float,
|
||||
contract_size: float,
|
||||
option_index: Optional[float] = None,
|
||||
perp_index: Optional[float] = None,
|
||||
) -> dict[str, Any]:
|
||||
"""手动张数 → 永续张数(同币或跨币名义)."""
|
||||
sheets_i = float(int(float(sheets or 0)))
|
||||
ct = float(ct_mult or 0.01)
|
||||
r = float(ratio or 0)
|
||||
cs = float(contract_size or 0.01)
|
||||
if sheets_i <= 0 or ct <= 0 or r <= 0 or cs <= 0:
|
||||
return {"ok": False, "msg": "定仓参数无效", "coin_qty": 0.0, "contracts": 0.0}
|
||||
coin_qty = round(sheets_i * ct, 2)
|
||||
oi = _sf(option_index)
|
||||
pi = _sf(perp_index)
|
||||
if oi is not None and pi is not None and oi > 0 and pi > 0:
|
||||
from lib.hedge_plan.hedge_po_mode_lib import size_cross_notional
|
||||
|
||||
cross_sz = size_cross_notional(
|
||||
option_coin_qty=coin_qty,
|
||||
option_index=float(oi),
|
||||
perp_index=float(pi),
|
||||
contract_size=cs,
|
||||
notional_k=(1.0 / r) if r > 0 else None,
|
||||
)
|
||||
if not cross_sz.get("ok"):
|
||||
return {"ok": False, "msg": cross_sz.get("msg") or "跨币定仓失败", "coin_qty": coin_qty}
|
||||
return {
|
||||
"ok": True,
|
||||
"msg": "",
|
||||
"sheets": sheets_i,
|
||||
"coin_qty": coin_qty,
|
||||
"eth_qty": coin_qty,
|
||||
"contracts": float(cross_sz["contracts"]),
|
||||
"perp_coin": float(cross_sz["perp_coin"]),
|
||||
"option_notional_usdt": cross_sz.get("option_notional_usdt"),
|
||||
"perp_notional_usdt": cross_sz.get("perp_notional_usdt"),
|
||||
"ratio": r,
|
||||
"cross_asset": abs(float(oi) - float(pi)) > 1e-6,
|
||||
}
|
||||
perp_coin = coin_qty / r
|
||||
return {
|
||||
"ok": True,
|
||||
"msg": "",
|
||||
"sheets": sheets_i,
|
||||
"coin_qty": coin_qty,
|
||||
"eth_qty": coin_qty,
|
||||
"contracts": perp_coin / cs,
|
||||
"perp_coin": perp_coin,
|
||||
"ratio": r,
|
||||
"cross_asset": False,
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user