模拟盘对齐币本位:钱包支持 ETH/BTC,现货桥与期权权利金走本地撮合。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+144
-8
@@ -192,10 +192,10 @@ def _patch_okx_options_lib(app_module: Any) -> None:
|
||||
if _GET_DB is not None and is_sim_mode(_GET_DB):
|
||||
w = broker().balances_header()
|
||||
return (
|
||||
round(float(w["trading_usdc"]), 2),
|
||||
round(float(w["funding_usdc"]), 2),
|
||||
round(float(w["funding_usdt"]), 2),
|
||||
round(float(w["trading_usdt"]), 2),
|
||||
round(float(w.get("trading_usdc") or 0), 2),
|
||||
round(float(w.get("funding_usdc") or 0), 2),
|
||||
round(float(w.get("funding_usdt") or 0), 2),
|
||||
round(float(w.get("trading_usdt") or 0), 2),
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -207,20 +207,32 @@ def _patch_okx_options_lib(app_module: Any) -> None:
|
||||
try:
|
||||
if _GET_DB is not None and is_sim_mode(_GET_DB):
|
||||
w = broker().balances_header()
|
||||
fu = float(w["funding_usdt"])
|
||||
fc = float(w["funding_usdc"])
|
||||
tu = float(w["trading_usdt"])
|
||||
tc = float(w["trading_usdc"])
|
||||
fu = float(w.get("funding_usdt") or 0)
|
||||
fc = float(w.get("funding_usdc") or 0)
|
||||
tu = float(w.get("trading_usdt") or 0)
|
||||
tc = float(w.get("trading_usdc") or 0)
|
||||
fe = float(w.get("funding_eth") or 0)
|
||||
te = float(w.get("trading_eth") or 0)
|
||||
fb = float(w.get("funding_btc") or 0)
|
||||
tb = float(w.get("trading_btc") or 0)
|
||||
return {
|
||||
"scope": "main",
|
||||
"funding_usdt": fu,
|
||||
"funding_usdc": fc,
|
||||
"trading_usdt": tu,
|
||||
"trading_usdc": tc,
|
||||
"funding_eth": fe,
|
||||
"trading_eth": te,
|
||||
"funding_btc": fb,
|
||||
"trading_btc": tb,
|
||||
"funding_usdt_avail": fu,
|
||||
"funding_usdc_avail": fc,
|
||||
"trading_usdt_avail": tu,
|
||||
"trading_usdc_avail": tc,
|
||||
"funding_eth_avail": fe,
|
||||
"trading_eth_avail": te,
|
||||
"funding_btc_avail": fb,
|
||||
"trading_btc_avail": tb,
|
||||
}
|
||||
except Exception:
|
||||
pass
|
||||
@@ -355,6 +367,130 @@ def _patch_okx_options_lib(app_module: Any) -> None:
|
||||
opt_lib.fetch_option_positions = fetch_option_positions
|
||||
opt_lib._sim_hooks_applied = True
|
||||
|
||||
_patch_spot_bridge_lib()
|
||||
|
||||
|
||||
def _patch_spot_bridge_lib() -> None:
|
||||
"""币本位现货桥:模拟盘走本地 USDT↔ETH/BTC,勿打实盘 private_post_trade_order."""
|
||||
import lib.options.options_spot_bridge_lib as bridge_lib
|
||||
|
||||
if getattr(bridge_lib, "_sim_hooks_applied", False):
|
||||
return
|
||||
|
||||
_orig_buy = bridge_lib.spot_market_buy_coin_with_usdt
|
||||
_orig_sell = bridge_lib.spot_market_sell_coin_to_usdt
|
||||
_orig_avail = bridge_lib.fetch_trading_coin_available
|
||||
|
||||
def fetch_trading_coin_available(ex, ccy: str):
|
||||
try:
|
||||
if _GET_DB is not None and is_sim_mode(_GET_DB):
|
||||
ccy_u = (ccy or "").strip().upper()
|
||||
if ccy_u not in ("ETH", "BTC"):
|
||||
return None
|
||||
w = broker().balances_header()
|
||||
return float(w.get(f"trading_{ccy_u.lower()}") or 0)
|
||||
except Exception:
|
||||
pass
|
||||
return _orig_avail(ex, ccy)
|
||||
|
||||
def spot_market_buy_coin_with_usdt(ex, *, underlying: str, usdt_amount: float):
|
||||
try:
|
||||
if _GET_DB is not None and is_sim_mode(_GET_DB):
|
||||
pub = ex
|
||||
if pub is None and _APP_MODULE is not None:
|
||||
pub = getattr(_APP_MODULE, "exchange", None) or getattr(
|
||||
_APP_MODULE, "exchange_options", None
|
||||
)
|
||||
if pub is None:
|
||||
return {"ok": False, "msg": "sim: 无公开行情 exchange"}
|
||||
result = broker().convert_usdt_coin(
|
||||
pub,
|
||||
underlying=underlying,
|
||||
direction="usdt_to_coin",
|
||||
amount=float(usdt_amount),
|
||||
account="trading",
|
||||
)
|
||||
if not result.get("ok"):
|
||||
return {
|
||||
"ok": False,
|
||||
"msg": result.get("detail") or result.get("msg") or "买币失败",
|
||||
}
|
||||
try:
|
||||
from lib.instance.instance_live_push_lib import notify_instance_balance_changed
|
||||
|
||||
notify_instance_balance_changed()
|
||||
except Exception:
|
||||
pass
|
||||
return {
|
||||
"ok": True,
|
||||
"inst_id": result.get("inst_id") or "",
|
||||
"ord_id": f"sim-spot-buy-{result.get('fill_px') or 0}",
|
||||
"sim": True,
|
||||
"coin_bought": result.get("coin_bought"),
|
||||
"data": {"sCode": "0", "sMsg": "sim filled"},
|
||||
**{k: result[k] for k in ("fill_px", "usdt_spent", "underlying") if k in result},
|
||||
}
|
||||
except Exception as e:
|
||||
return {"ok": False, "msg": str(e)}
|
||||
return _orig_buy(ex, underlying=underlying, usdt_amount=usdt_amount)
|
||||
|
||||
def spot_market_sell_coin_to_usdt(ex, *, underlying: str, coin_amount: float | None = None):
|
||||
try:
|
||||
if _GET_DB is not None and is_sim_mode(_GET_DB):
|
||||
coin = (underlying or "ETH").strip().upper() or "ETH"
|
||||
amt = coin_amount
|
||||
if amt is None or float(amt) <= 0:
|
||||
amt = fetch_trading_coin_available(ex, coin)
|
||||
if amt is None or float(amt) <= 0:
|
||||
return {"ok": False, "msg": f"交易账户无可用 {coin}"}
|
||||
sell_sz = float(amt)
|
||||
if sell_sz > 1e-8:
|
||||
sell_sz = max(0.0, sell_sz * 0.999)
|
||||
if sell_sz <= 0:
|
||||
return {"ok": False, "msg": f"{coin} 可卖数量过小"}
|
||||
pub = ex
|
||||
if pub is None and _APP_MODULE is not None:
|
||||
pub = getattr(_APP_MODULE, "exchange", None) or getattr(
|
||||
_APP_MODULE, "exchange_options", None
|
||||
)
|
||||
if pub is None:
|
||||
return {"ok": False, "msg": "sim: 无公开行情 exchange"}
|
||||
result = broker().convert_usdt_coin(
|
||||
pub,
|
||||
underlying=coin,
|
||||
direction="coin_to_usdt",
|
||||
amount=float(sell_sz),
|
||||
account="trading",
|
||||
)
|
||||
if not result.get("ok"):
|
||||
return {
|
||||
"ok": False,
|
||||
"msg": result.get("detail") or result.get("msg") or "卖币失败",
|
||||
}
|
||||
try:
|
||||
from lib.instance.instance_live_push_lib import notify_instance_balance_changed
|
||||
|
||||
notify_instance_balance_changed()
|
||||
except Exception:
|
||||
pass
|
||||
return {
|
||||
"ok": True,
|
||||
"inst_id": result.get("inst_id") or "",
|
||||
"ord_id": f"sim-spot-sell-{result.get('fill_px') or 0}",
|
||||
"coin_sold": float(sell_sz),
|
||||
"sim": True,
|
||||
"usdt_recovered": result.get("usdt_recovered"),
|
||||
"data": {"sCode": "0", "sMsg": "sim filled"},
|
||||
}
|
||||
except Exception as e:
|
||||
return {"ok": False, "msg": str(e)}
|
||||
return _orig_sell(ex, underlying=underlying, coin_amount=coin_amount)
|
||||
|
||||
bridge_lib.fetch_trading_coin_available = fetch_trading_coin_available
|
||||
bridge_lib.spot_market_buy_coin_with_usdt = spot_market_buy_coin_with_usdt
|
||||
bridge_lib.spot_market_sell_coin_to_usdt = spot_market_sell_coin_to_usdt
|
||||
bridge_lib._sim_hooks_applied = True
|
||||
|
||||
|
||||
def wrap_option_place_fns(get_db: Callable, live_place_limit, live_place_market):
|
||||
"""返回按模式分流的 place_option_limit/market."""
|
||||
|
||||
Reference in New Issue
Block a user