fix(trading): close five risk gaps surfaced by pre-launch audit
1. hyperliquid.open_position now returns effective_leverage. HL clips the requested leverage to each asset's max (e.g. memes capped at 3×) and silently applied the lower value; we were discarding that. For System-2 this meant sys2_protective_stop_pct was computed against the REQUESTED leverage, so the "inside-liquidation" full-close rung was actually well inside an 8.5% stop while the real liquidation sat ~33% away — strategy intent broken. bot_engine now reads the effective value back, recomputes the protective stop + derisk ladder against it, and freezes the correct values into BotTrade.eff_* / .leverage. 2. circuit_breaker.clear_trip now clears BOTH systems by default. The sys2 column was never reachable from any reset path — a sys2 trip forced users to wait the full 24h lockout even after explicit human re-arm. 3. /api/user/.../manual-window and /auto-trade re-arm endpoints now clear sys1 AND sys2 CB on the same human ack. Symmetry with check_and_trip / is_tripped which already supported both systems. 4. telegram.py deep-link map: btc_bottom_reversal + funding_reversal alerts now point at /en/macro instead of the now-404 /en/btc. 5. (Already landed: _sys2_mode UnboundLocalError fix in bot_engine — restated here for the audit trail.) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -172,8 +172,13 @@ class HyperliquidTrader:
|
||||
coin = asset.upper()
|
||||
is_buy = side.lower() == "long"
|
||||
|
||||
# 1. Set leverage before opening
|
||||
await self.set_leverage(coin)
|
||||
# 1. Set leverage before opening. Capture HL's clipped value — for
|
||||
# illiquid / meme assets the requested leverage may exceed the
|
||||
# asset's max and HL silently clips. Caller MUST use this
|
||||
# `effective_leverage` for downstream risk math (protective stop,
|
||||
# liquidation distance) or stops will fire far short of the real
|
||||
# HL liquidation line.
|
||||
effective_leverage = await self.set_leverage(coin)
|
||||
|
||||
# 2. Compute coin size from USD notional
|
||||
mid = await self._mid_price(coin)
|
||||
@@ -232,9 +237,14 @@ class HyperliquidTrader:
|
||||
oid_src = filled_info or status.get("resting") or {}
|
||||
order_id = str(oid_src.get("oid", "")) if oid_src else ""
|
||||
|
||||
logger.info("Opened %s %s @ %.2f size=%.5f (order_id=%s)",
|
||||
side, coin, fill_price, total_sz, order_id)
|
||||
return {"order_id": order_id, "fill_price": fill_price, "size_coins": total_sz}
|
||||
logger.info("Opened %s %s @ %.2f size=%.5f (order_id=%s, lev=%dx)",
|
||||
side, coin, fill_price, total_sz, order_id, effective_leverage)
|
||||
return {
|
||||
"order_id": order_id,
|
||||
"fill_price": fill_price,
|
||||
"size_coins": total_sz,
|
||||
"effective_leverage": effective_leverage,
|
||||
}
|
||||
|
||||
async def close_position(self, asset: str) -> dict:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user