Guide

Deep Dive: Running a Market Making Agent on Perpetual Futures

March 6, 2026 Purple Flea Team 10 min read

Introduction

Market makers earn by providing liquidity — posting both buy and sell limit orders simultaneously and capturing the bid-ask spread when both sides fill. On Hyperliquid's perpetual futures market, professional market makers also earn maker rebates of -0.025% of trade value: rather than paying a fee, they receive a credit each time a limit order they posted gets filled. This passive rebate income on top of spread capture makes market making one of the most systematic and scalable strategies available to AI agents.

This guide builds a professional-grade market making agent from first principles — covering spread sizing, inventory management, delta hedging, and a complete Python implementation using Purple Flea's trading API.

The Economics of Market Making

Understanding the P&L components of market making is essential before writing a single line of code:

In a perfectly balanced world where every buy order is matched by an equal sell order at a slightly different price, inventory never accumulates and you capture pure spread. In reality, fills are asymmetric — you might fill 10 buys and 3 sells in a row. Managing this inventory imbalance before it becomes a directional loss is the primary skill of a market maker.

Spread Sizing: The Core Decision

Getting the spread right is the most important decision in market making. Too narrow and you get adversely selected — informed traders (or other algorithms) pick off your quotes before you can update them, leaving you holding inventory at bad prices. Too wide and your orders never get filled.

The Fundamental Framework

spread_bps = base_spread + vol_premium + inventory_premium

During a quiet low-volatility market, your spread might be 5 bps. During high volatility when BTC moves 2% per hour, it would widen to 15–20 bps automatically. This dynamic sizing protects against being picked off during volatile conditions.

Inventory Management

The goal of inventory management is to stay as close to delta-neutral as possible — meaning you have equal exposure to both long and short positions, netting close to zero directional risk.

After asymmetric fills, your inventory accumulates in one direction. Left unchecked, a long inventory position in a falling market produces losses that can dwarf the spread income. The response is inventory leaning: when you are long, adjust your quotes to offer a better ask price (to attract sellers) and a worse bid price (to discourage more buyers). This naturally rebalances the inventory via market forces.

When leaning is not fast enough, you hedge with a market order — accepting the taker fee as the cost of eliminating inventory risk.

Full Market Maker Implementation

import requests
import time
import math

PF_BASE = "https://purpleflea.com/api"
PF_KEY = "your-api-key"
HEADERS = {"Authorization": f"Bearer {PF_KEY}", "Content-Type": "application/json"}

class PerpMarketMaker:
    def __init__(self, symbol: str, base_spread_bps: float = 5.0):
        self.symbol = symbol
        self.base_spread_bps = base_spread_bps
        self.inventory = 0.0      # Current directional exposure in USD
        self.max_inventory = 1000  # $1000 max
        self.quote_size = 100      # $100 per side

    def get_mid_price(self) -> float:
        r = requests.get(f"{PF_BASE}/v1/markets/{self.symbol}/price", headers=HEADERS)
        return r.json()["mid"]

    def get_realized_vol_1h(self) -> float:
        r = requests.get(f"{PF_BASE}/v1/markets/{self.symbol}/volatility",
            params={"period": "1h"}, headers=HEADERS)
        return r.json()["realized_vol"]  # As a decimal, e.g. 0.015 = 1.5%

    def get_spread(self) -> float:
        """Dynamic spread: base + vol premium + inventory premium"""
        vol = self.get_realized_vol_1h()
        vol_premium = vol * 100 * 0.5       # 50% of hourly vol in bps
        inv_ratio = abs(self.inventory) / self.max_inventory
        inventory_premium = inv_ratio * 5    # Up to 5 extra bps at max inventory
        total = self.base_spread_bps + vol_premium + inventory_premium
        return min(total, 50.0)  # Hard cap at 50 bps

    def refresh_quotes(self):
        mid = self.get_mid_price()
        spread = self.get_spread()
        half = mid * (spread / 10000) / 2

        # Lean quotes based on inventory to encourage rebalancing
        # Positive inventory (long) → lean prices down to attract sellers
        inventory_lean = -(self.inventory / self.max_inventory) * half * 0.3

        bid = mid - half + inventory_lean
        ask = mid + half + inventory_lean

        # Cancel all existing orders, then post fresh quotes
        requests.delete(f"{PF_BASE}/v1/mm/cancel-all",
            json={"symbol": self.symbol}, headers=HEADERS)

        requests.post(f"{PF_BASE}/v1/mm/quote",
            json={
                "symbol": self.symbol,
                "bid": round(bid, 2),
                "ask": round(ask, 2),
                "size": self.quote_size
            }, headers=HEADERS)

        print(f"[{self.symbol}] mid={mid:.2f} spread={spread:.1f}bps bid={bid:.2f} ask={ask:.2f} inv=${self.inventory:.0f}")

    def update_inventory(self):
        """Fetch current net position from exchange"""
        r = requests.get(f"{PF_BASE}/v1/positions/{self.symbol}", headers=HEADERS)
        pos = r.json()
        self.inventory = pos.get("net_usd", 0.0)

    def hedge_inventory(self):
        """Reduce inventory with a market order when it exceeds threshold"""
        if abs(self.inventory) < self.max_inventory * 0.8:
            return
        hedge_side = "short" if self.inventory > 0 else "long"
        hedge_size = abs(self.inventory) * 0.5  # Hedge 50% of excess
        requests.post(f"{PF_BASE}/v1/trade",
            json={"symbol": self.symbol, "side": hedge_side, "size_usd": hedge_size, "leverage": 1},
            headers=HEADERS)
        print(f"Hedged ${hedge_size:.0f} {hedge_side} to reduce inventory")

    def run(self):
        print(f"Market maker starting on {self.symbol}")
        while True:
            try:
                self.refresh_quotes()
                self.update_inventory()
                self.hedge_inventory()
            except Exception as e:
                print(f"Error: {e}")
            time.sleep(3)  # Refresh every 3 seconds

if __name__ == "__main__":
    mm = PerpMarketMaker("BTC-PERP", base_spread_bps=5.0)
    mm.run()

Delta Hedging

Delta hedging is the process of actively offsetting inventory risk using market orders when leaning alone is not sufficient to restore neutrality quickly enough.

The key decisions are:

Hypothetical Backtest Results

To calibrate expectations, here is a hypothetical scenario for a $10,000 capital base running on BTC-PERP with a 5 bps spread, operating 8 hours per day:

$50K Daily volume
$37.50 Daily gross income (spread + rebates)
~100% Projected annual APY on capital

Breaking down the daily income: spread income of ~$25 (0.05% on $50K volume) plus rebate income of ~$12.50 (0.025% on $50K) equals $37.50 gross. After inventory losses of approximately $10 on active trading days, the net is roughly $27.50 per day. Annualized across 365 days with an average of 8 active hours, that approaches $10,000 — a 100% APY on the deployed capital. These numbers are illustrative; actual results depend heavily on fill rates, volatility regime, and competition from other market makers.

Risk Controls Checklist

Adverse selection is the hidden cost. If your fill rate is suspiciously high — say 90%+ of your quotes filling immediately — it likely means informed traders are picking off your stale prices rather than genuine two-sided flow. Widen your spread and add a small random delay to quote timing to reduce predictability.

Conclusion

Market making is one of the few strategies where an AI agent's advantages — speed, consistency, 24/7 operation, and zero emotional bias — directly translate to better execution than human traders. A well-configured market making agent running on perpetual futures can generate substantial yield on deployed capital while providing a genuine service to the market.

The key to success is disciplined spread sizing, aggressive inventory management, and a robust risk framework that prevents any single adverse event from undoing weeks of accumulated gains.

Get started with the market maker API, trading API, and orderbook API. Register your agent at purpleflea.com/register.