vault 開発 · keeper の構成 · 5/7
ポジションの管理
ポジションを読む
売買を判断する前に、keeper は今の状態を知る必要があります。以下の例の exchange は、vault_address=vault_address を指定して作った Exchange です。そのため、どの操作も vault のために署名されます。SDK の注文の関数は、vault_address の引数を取りません。まずテストネットで動かしてください。
from hyperliquid.exchange import Exchange
from hyperliquid.info import Info
def get_positions(info: Info, vault_address: str) -> dict:
"""Get all open positions for the vault."""
state = info.user_state(vault_address)
positions = {}
for ap in state["assetPositions"]:
p = ap["position"]
coin = p["coin"]
positions[coin] = {
"size": float(p["szi"]), # Positive = long, negative = short
"entry_price": float(p["entryPx"]),
"mark_price": float(p["positionValue"]) / abs(float(p["szi"])) if float(p["szi"]) != 0 else 0,
"unrealized_pnl": float(p["unrealizedPnl"]),
"leverage": float(p.get("leverage", {}).get("value", 1)),
"liquidation_px": float(p.get("liquidationPx", 0) or 0),
}
return positions
ポジションを建てる
def open_position(exchange: Exchange, vault_address: str,
coin: str, side: str, size: float,
leverage: int = 10) -> dict:
"""Open a new position for the vault."""
# Set leverage first
exchange.update_leverage(leverage, coin, is_cross=True)
# Place market order (an aggressive IOC limit order with 5% default slippage)
is_buy = side == "long"
result = exchange.market_open(coin, is_buy, size)
return result
ポジションを閉じる
def close_position(exchange: Exchange, vault_address: str,
coin: str, size: float) -> dict:
"""Close an existing position."""
# market_close reads the vault's position, picks the closing side,
# and sends a reduce-only IOC order.
result = exchange.market_close(coin, sz=abs(size))
return result
ポジションの大きさを変える
ポジションの一部を閉じたり、買い増し・売り増ししたりすることもあります。
def adjust_position(exchange: Exchange, info: Info,
vault_address: str, coin: str,
target_size: float) -> dict | None:
"""Adjust position to target size."""
positions = get_positions(info, vault_address)
current = positions.get(coin, {}).get("size", 0.0)
diff = target_size - current
if abs(diff) < 0.001: # Already at target (within tolerance)
return None
is_buy = diff > 0
result = exchange.market_open(coin, is_buy, abs(diff))
return result
損切りの管理
def set_stop_loss(exchange: Exchange, vault_address: str,
coin: str, size: float, stop_price: float) -> dict:
"""Set a stop-loss order for an open position."""
is_buy = size < 0 # Stop for shorts = buy, for longs = sell
result = exchange.order(
coin,
is_buy,
abs(size),
stop_price,
{"trigger": {
"triggerPx": stop_price,
"isMarket": True,
"tpsl": "sl",
}},
reduce_only=True,
)
return result
ポジション管理の大事な決まり
- 自分のポジションを常に知っておく — 書き込む前に読みます
- reduce_only を使う — 閉じる注文では、
market_closeを使うか reduce_only=True を指定します。うっかり反対側のポジションになるのを防げます - 建てる前に証拠金を確かめる — 自分のリスクの上限を超えないようにします
- 一部だけの約定に備える — 流動性が薄いと、成行の注文が一部しか約定しないことがあります
- すべてを記録する — 注文、約定、エラーはすべてログに残し、原因を調べられるようにします