Skip to main content

Perpetual Futures

Trade perpetual futures on Bluefin Pro through OnlyFence. Place market and limit orders, manage positions, deposit and withdraw margin — all with safety guardrails that enforce market allowlists, leverage caps, order size limits, and volume controls.

Quick Start

# Enable perp trading in config
fence config set chain.sui.perp.allowlist_markets '["SUI-PERP", "BTC-PERP", "ETH-PERP"]'
fence config set chain.sui.perp.max_leverage 10

# Deposit margin
fence perp deposit 100

# Place a limit order
fence perp order SUI-PERP long 10 --type limit --price 3.50 --leverage 5

# Check positions
fence perp positions

# Close a position
fence perp close SUI-PERP

Available Markets

fence perp markets

Returns all tradeable markets with their configuration: symbol, leverage bounds, order size limits, tick size, and fee rates.

Placing Orders

fence perp order <market> <side> <qty> [options]
ArgumentDescription
marketMarket symbol (e.g., SUI-PERP, BTC-PERP)
sidelong or short
qtyQuantity in the base asset (e.g., 10 = 10 SUI)
OptionDefaultDescription
--typemarketmarket or limit
--priceLimit price in USD (required for limit orders)
--leverageautoAuto-resolved from existing position or market default
--tifGTTTime in force: GTT, IOC, or FOK (limit only)
--reduce-onlyfalseOnly reduce an existing position

Examples

# Market order — fills immediately
fence perp order SUI-PERP long 10 --type market

# Limit order with leverage
fence perp order BTC-PERP short 0.01 --type limit --price 100000 --leverage 10

# Reduce-only to partially close
fence perp order SUI-PERP short 5 --type market --reduce-only

Order Confirmation

Orders are confirmed via WebSocket. The CLI waits for the exchange to accept or reject the order before returning:

  • success — order confirmed on the exchange
  • acknowledged — order submitted but WebSocket confirmation timed out. Verify with fence perp orders
  • rejected — blocked by policy (exit code 3) with the rejection reason
  • error — exchange rejected with a reason (e.g., INSUFFICIENT_MARGIN)

Leverage

When --leverage is omitted:

  1. If you have an existing position on that market, the position's leverage is used
  2. Otherwise, the market's default leverage is used

This prevents INVALID_LEVERAGE errors in cross-margin mode, where all orders on a market must share the same leverage.

Closing Positions

fence perp close <market> [--size <qty>]

Auto-detects your position side and places a reduce-only market order in the opposite direction. Omit --size to close the full position.

# Close entire SUI-PERP position
fence perp close SUI-PERP

# Partial close
fence perp close SUI-PERP --size 5

Cancelling Orders

# Cancel all open orders on a market
fence perp cancel SUI-PERP

# Cancel a specific order by hash
fence perp cancel SUI-PERP --order <hash>

# Cancel multiple specific orders
fence perp cancel SUI-PERP -o <hash1> -o <hash2>

Margin Management

Deposit

Deposit USDC to the Bluefin margin bank:

fence perp deposit <amount>
fence perp deposit 100

Withdraw

Withdraw USDC from the margin bank:

fence perp withdraw <amount>
fence perp withdraw 50

Query Commands

All query commands return JSON on stdout and hit the Bluefin API directly (live data, not cached).

Positions

fence perp positions

Returns open positions with: symbol, side, sizeE9, avgEntryPriceE9, liquidationPriceE9, unrealizedPnlE9, leverageE9.

Open Orders

fence perp orders
fence perp orders --market SUI-PERP

Order Status

fence perp order-status <orderHash>

Checks both open and standby orders.

Account Overview

fence perp account

Returns full account details: margin balance, free margin, account value, unrealized PnL, and all positions.

Funding Rates

# Exchange-level funding rate history
fence perp funding-rate SUI-PERP
fence perp funding-rate BTC-PERP --limit 5

# Your personal funding payments
fence perp funding-history
fence perp funding-history --limit 10

Sync Fills

fence perp sync

Syncs filled trades from the Bluefin API to your local activity database. This enables querying perp fills alongside swaps and lending in fence query activities.

Safety Guardrails

Perp trading is protected by 5 policy checks. All checks run before every order is submitted to the exchange.

Market Allowlist (Default-Deny)

Unlike swaps where all tokens are allowed by default, perp markets are blocked until explicitly enabled. Without a [chain.sui.perp] config section, all perp orders are rejected.

[chain.sui.perp]
allowlist_markets = ["SUI-PERP", "BTC-PERP", "ETH-PERP"]
  • Place orders: market must be in the list
  • Cancel orders: always allowed (you must be able to unwind)
  • Withdraw: always allowed (you must be able to exit)
  • Deposit: allowed if any market is enabled (perp is active)

Leverage Cap

[chain.sui.perp]
max_leverage = 10

The effective cap is the lower of your config value and the on-chain market maximum. If the exchange allows 50x but your config says 10x, orders above 10x are rejected.

Order Size Limit

[chain.sui.perp]
max_single_order = 500

Maximum notional value per order in USD. For limit orders, notional = price × quantity. For market orders, notional uses the current exchange ticker price.

Daily Volume Limit

[chain.sui.perp]
max_24h_volume = 5000

Rolling 24-hour perp trading volume cap in USD. Separate from the spot swap volume limit — the two don't interact.

Volume Counting

Volume is counted from order placement (intent), not from actual fills. This means orders that pass the CLI policy check but are later rejected by the exchange still count toward your volume. This is conservative by design — it prevents limit exhaustion via failed orders without requiring fill sync.

Withdrawal Limit

[chain.sui.perp]
max_24h_withdraw = 1000

Rolling 24-hour margin withdrawal cap in USD. Prevents an agent from draining the margin account.

Full Config Example

[chain.sui.perp]
allowlist_markets = ["SUI-PERP", "BTC-PERP", "ETH-PERP"]
max_leverage = 10
max_single_order = 500
max_24h_volume = 5000
max_24h_withdraw = 1000

Rejection Response

When a policy check blocks an order:

{
"status": "rejected",
"action": "perp:place_order",
"rejectionCheck": "perp_leverage_cap",
"rejectionReason": "Leverage 20x exceeds effective cap of 10x (config: 10x, on-chain max: 50x)"
}

Supported Protocols

ProtocolChainStatus
Bluefin ProSuiLive

Numeric Format

All values from the Bluefin API use e9 format — divide by 10^9 for human-readable values:

Fielde9 ValueHuman Value
sizeE9: "10000000000"÷ 10^910 units
leverageE9: "20000000000"÷ 10^920x
priceE9: "3800000000"÷ 10^9$3.80
takerFeeE9: "500000"÷ 10^9 × 1000.05%

Activity Tracking

Perp actions are logged in the activity database alongside swaps and lending:

  • perp:place_order — recorded when the CLI submits an order (intent)
  • perp:filled — recorded when fence perp sync imports fills from the exchange
  • perp:deposit — on-chain USDC deposit to margin bank
  • perp:withdraw — margin bank withdrawal

Query perp activity with:

fence query activities -f category=eq=perp --order-by created_at=desc -o json