fix(hub): live market PnL and Gate drag SL place

Parse Gate unrealised_pnl in agent; refresh hub market floating PnL from board and trends; clamp Gate TP/SL triggers before place.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-04 20:02:23 +08:00
parent 24270944e7
commit e6361a7fcc
7 changed files with 197 additions and 17 deletions
+57
View File
@@ -725,6 +725,62 @@ def _gate_td_mode_cross() -> bool:
return td in ("cross", "cross_margin")
def _gate_last_price(ex: Any, symbol: str) -> float | None:
ex.load_markets()
unified = ex.market(symbol)["symbol"]
try:
t = ex.fetch_ticker(unified)
except Exception:
return None
if not isinstance(t, dict):
return None
info = t.get("info") if isinstance(t.get("info"), dict) else {}
for key in ("last", "mark", "close", "index_price"):
v = t.get(key) if key in t else info.get(key)
try:
f = float(v)
if f > 0:
return f
except (TypeError, ValueError):
continue
return None
def _gate_clamp_tpsl_prices(
ex: Any,
symbol: str,
direction: str,
stop_loss: float,
take_profit: float,
) -> tuple[float, float]:
"""
Gate price_orders:空仓止损/多仓止盈 trigger>last;空仓止盈/多仓止损 trigger<last。
"""
last = _gate_last_price(ex, symbol)
if last is None or last <= 0:
return float(stop_loss), float(take_profit)
ex.load_markets()
unified = ex.market(symbol)["symbol"]
gap_pct = float(os.getenv("GATE_TPSL_LAST_PRICE_GAP_PCT", "0.05") or "0.05")
gap = max(0.0, gap_pct) / 100.0
if gap <= 0:
gap = 0.0005
sl = float(stop_loss)
tp = float(take_profit)
d = (direction or "long").strip().lower()
if d == "short":
if sl <= last:
sl = float(ex.price_to_precision(unified, last * (1 + gap)))
if tp >= last:
tp = float(ex.price_to_precision(unified, last * (1 - gap)))
else:
if sl >= last:
sl = float(ex.price_to_precision(unified, last * (1 - gap)))
if tp <= last:
tp = float(ex.price_to_precision(unified, last * (1 + gap)))
return sl, tp
def _gate_place_tp_sl(
ex: Any,
symbol: str,
@@ -794,6 +850,7 @@ def replace_position_tpsl(
td = (os.getenv("OKX_TD_MODE") or "cross").strip()
_okx_place_tp_sl(ex, symbol, direction, amt, sl, tp, pos_mode=pm, td_mode=td)
else:
sl, tp = _gate_clamp_tpsl_prices(ex, symbol, direction, sl, tp)
_gate_place_tp_sl(ex, symbol, direction, amt, sl, tp)
return {
"symbol": symbol,