Harden residual mid-close: IOC partial fills, exchange reconcile, atomic book.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -228,9 +228,11 @@ class BinanceTradeClient:
|
||||
if reduce_only:
|
||||
params["reduceOnly"] = "true"
|
||||
data = self._signed(self._eapi, "POST", "/eapi/v1/order", params)
|
||||
return self._fill_from_eapi(symbol, data)
|
||||
return self._fill_from_eapi(symbol, data, allow_partial=True)
|
||||
|
||||
def _fill_from_eapi(self, symbol: str, data: dict[str, Any]) -> LiveFill:
|
||||
def _fill_from_eapi(
|
||||
self, symbol: str, data: dict[str, Any], *, allow_partial: bool = False
|
||||
) -> LiveFill:
|
||||
ord_id = str(data.get("orderId") or data.get("id") or "")
|
||||
avg = safe_float(data.get("avgPrice")) or safe_float(data.get("price"))
|
||||
sz = safe_float(data.get("executedQty")) or safe_float(data.get("quantity"))
|
||||
@@ -251,16 +253,25 @@ class BinanceTradeClient:
|
||||
if avg and avg > 0 and st == "FILLED":
|
||||
break
|
||||
if st in ("CANCELED", "REJECTED", "EXPIRED"):
|
||||
if allow_partial and sz and sz > 1e-12 and avg and avg > 0:
|
||||
break
|
||||
raise RuntimeError(f"币安期权订单失败 status={st} {q}")
|
||||
if st == "PARTIALLY_FILLED":
|
||||
continue
|
||||
if not avg or avg <= 0:
|
||||
raise RuntimeError(f"币安期权无成交均价 orderId={ord_id} last={data}")
|
||||
st_final = str(data.get("status") or "").upper()
|
||||
executed = safe_float(data.get("executedQty")) or float(sz or 0)
|
||||
if st_final and st_final != "FILLED":
|
||||
raise RuntimeError(
|
||||
f"币安期权未完全成交 status={st_final} orderId={ord_id} last={data}"
|
||||
)
|
||||
if not (
|
||||
allow_partial
|
||||
and executed > 1e-12
|
||||
and st_final in ("CANCELED", "EXPIRED", "PARTIALLY_FILLED")
|
||||
):
|
||||
raise RuntimeError(
|
||||
f"币安期权未完全成交 status={st_final} orderId={ord_id} last={data}"
|
||||
)
|
||||
sz = executed
|
||||
from .money import abs_fee_usdt
|
||||
|
||||
fee = abs(safe_float(data.get("fee")) or 0.0)
|
||||
|
||||
Reference in New Issue
Block a user