
Ship a Prediction Market Bot on Hyperliquid in 100 Lines
By CMM Team - 14-Jul-2026
Ship a Prediction Market Bot on Hyperliquid in 100 Lines
Most prediction market tutorials stop at "install the SDK and place an order." That's the easy part. The hard part is knowing which markets to trade and when the price is wrong. Hyperliquid's HIP-4 outcome markets run on the same matching engine as perps and spot, which means you can layer cohort positioning data on top of binary outcome trades to catch mispricings that pure prediction market traders can't see.
This guide walks you through building a Python bot that discovers HIP-4 markets, reads order books, checks what smart money is doing on the underlying asset, and places trades when the signals align. The whole thing fits in about 100 lines of working code.
How HIP-4 Outcome Markets Actually Work
HIP-4 launched on Hyperliquid mainnet on May 2, 2026. Each market poses a binary question: will BTC exceed a target price by a specific expiry? Traders buy YES or NO positions using USDC as collateral. At expiry, the winning side settles to 1 USDC per unit and the losing side settles to 0.
The price of a YES token at any moment represents the market's implied probability of the event occurring. If YES trades at $0.65, the market is pricing a 65% chance the event happens. The complementary NO token should trade near $0.35, because the two sides share a merged order book where a YES buy at price p mirrors a NO sell at 1-p.
Three things make HIP-4 different from Polymarket. First, settlement is deterministic: Hyperliquid's validator set resolves each contract against a pre-specified objective data source, with no dispute window and no token vote. Second, there's no leverage and no liquidation risk. Positions are fully collateralized at open. Third, fees are currently zero for opening positions, though builder codes still apply on fills.
The Encoding System You Need to Get Right
HIP-4 uses a three-format encoding system that trips up every builder the first time. Each outcome has an ID, and each side (YES = 0, NO = 1) produces a numeric encoding using the formula: encoding = 10 * outcome_id + side.
But the format you use depends on the context. For order placement and order book queries, you prefix with #, so outcome 2 YES becomes #20. For balance lookups, you prefix with +, so the same position becomes +20. For internal SDK asset IDs, you add the encoding to 100,000,000.
These formats are not interchangeable. Using #20 for a balance lookup or +20 for an order will silently fail with no error message. Here are the helper functions:
def encode_coin(outcome_id: int, side: int) -> str:
"""Order placement and book queries."""
return f"#{10 * outcome_id + side}"
def encode_balance_coin(outcome_id: int, side: int) -> str:
"""Balance lookups only."""
return f"+{10 * outcome_id + side}"
def encode_asset_id(outcome_id: int, side: int) -> int:
"""SDK internal mapping."""
return 100_000_000 + 10 * outcome_id + side
SDK patch required: The official hyperliquid-python-sdk does not natively support HIP-4. Its coin_to_asset map is built from spot_meta only, so outcome encodings starting at 100,000,000 are unknown to the resolver. You need to fetch outcomeMeta and inject the mappings manually. The code below handles this.
Discovering Active Markets
The first thing your bot needs to do is find which markets exist. The outcomeMeta endpoint returns every active and settled outcome, including the outcome ID, a pipe-separated description (class, underlying asset, expiry date, target price), and side specifications.
import httpx
BASE_URL = "https://api.hyperliquid.xyz"
def fetch_outcome_meta():
r = httpx.post(
f"{BASE_URL}/info",
json={"type": "outcomeMeta"},
timeout=10.0,
)
return r.json()
def parse_active_markets(meta):
markets = []
for o in meta.get("outcomes", []):
desc = o.get("description", "")
parts = desc.split("|")
if len(parts) >= 4:
markets.append({
"outcome_id": o["outcome"],
"underlying": parts[1].strip(),
"expiry": parts[2].strip(),
"target": parts[3].strip(),
})
return markets
This gives you a list of every outcome market on the platform. Filter by expiry to focus on markets that haven't settled yet. The recurring daily BTC market, for example, settles at 06:00 UTC each day against the BTC mark price.
Reading the Order Book and Implied Probability
Each outcome side has its own order book. You query it the same way you'd query a spot book, just with the #N coin format:
def fetch_book(coin: str):
r = httpx.post(
f"{BASE_URL}/info",
json={"type": "l2Book", "coin": coin},
timeout=10.0,
)
levels = r.json().get("levels", [[], []])
bids = [(float(p), float(s)) for p, s in levels[0]]
asks = [(float(p), float(s)) for p, s in levels[1]]
return bids, asks
def get_mid_price(coin: str) -> float:
bids, asks = fetch_book(coin)
if bids and asks:
return (bids[0][0] + asks[0][0]) / 2
return 0.0
# Example: outcome 2
yes_mid = get_mid_price("#20")
no_mid = get_mid_price("#21")
print(f"YES: {yes_mid:.4f}, NO: {no_mid:.4f}, sum: {yes_mid + no_mid:.4f}")
In a fair market, YES mid + NO mid should equal approximately 1.0. Any sustained deviation is either a fee artifact or a mispricing worth investigating. The spread between the two sides is your first signal.
Layering Cohort Signals on Top of Outcome Prices
This is where prediction market bots get interesting. A pure prediction market trader looks at the order book and maybe some external news. A builder with access to cohort data can see something else: what the most profitable wallets on Hyperliquid are actually doing on the underlying asset.
Imagine a BTC outcome market pricing a 55% chance that BTC exceeds a target price by expiry. That's the market's best guess. But our cohort data shows that Money Printer wallets (those with over $1M in all-time profit) are heavily net long on BTC perps, while Giga-Rekt wallets (those with over $1M in all-time losses) are net short. When the traders with the best track records disagree with the prediction market's implied probability, that divergence is a signal worth acting on.
import requests
HT_BASE = "https://ht-api.coinmarketman.com/api/external"
HT_TOKEN = "your_hypertracker_jwt"
def get_cohort_bias(coin: str = "BTC"):
"""Fetch Money Printer and Giga-Rekt positioning."""
headers = {"Authorization": f"Bearer {HT_TOKEN}"}
r = requests.get(
f"{HT_BASE}/cohort/metrics",
params={"coin": coin},
headers=headers,
)
data = r.json()
# Extract cohort-level long/short ratio
money_printer = next(
(c for c in data if c.get("cohortId") == 8), None
)
giga_rekt = next(
(c for c in data if c.get("cohortId") == 15), None
)
return money_printer, giga_rekt
The cohort IDs come from HyperTracker's 16-segment classification system: 8 segments by perp equity size (Shrimp through Leviathan) and 8 by all-time PnL (Money Printer through Giga-Rekt). Money Printer is cohort 8 and Giga-Rekt is cohort 15. When you see Money Printers loading up on one side while the outcome market is priced on the other, that's the gap your bot exploits.
Placing Orders on HIP-4 Markets
Order placement follows the same pattern as spot trading, with a few HIP-4 specific constraints. Sizes must be integers (no fractional units). The minimum notional is $10 USDC, meaning size * price >= 10. Prices range from 0.001 to 0.999.
from hyperliquid.exchange import Exchange
from eth_account import Account
def place_outcome_order(exchange, outcome_id, side, is_buy, price, size):
coin = encode_coin(outcome_id, side)
result = exchange.order(
coin,
is_buy=is_buy,
sz=size,
limit_px=price,
order_type={"limit": {"tif": "Gtc"}},
)
return result
# Example: buy 25 YES on outcome 2 at $0.45
# Cost: 25 * 0.45 = $11.25 (above $10 min)
# If YES wins: receive 25 * $1 = $25, profit = $13.75
result = place_outcome_order(exchange, 2, 0, True, 0.45, 25)
Remember: HIP-4 positions are fully collateralized. There is no leverage and no liquidation. Your maximum loss on any trade is exactly what you paid to open it. This makes prediction market bots simpler to reason about than perp bots, because you never need to worry about margin maintenance or forced closes.
Putting It All Together: The Full Bot
Here's the complete loop. The bot discovers active markets, reads order books, checks cohort positioning on the underlying asset, and places a trade when the prediction market's implied probability diverges from what the most profitable traders are actually doing.
import time
def run_bot(exchange, info):
"""Main loop: discover, price, signal, execute."""
meta = fetch_outcome_meta()
markets = parse_active_markets(meta)
for market in markets:
oid = market["outcome_id"]
underlying = market["underlying"]
# Step 1: Get implied probability
yes_mid = get_mid_price(encode_coin(oid, 0))
no_mid = get_mid_price(encode_coin(oid, 1))
if yes_mid == 0 or no_mid == 0:
continue
# Step 2: Get cohort positioning
mp, gr = get_cohort_bias(underlying)
if not mp or not gr:
continue
# Step 3: Simple divergence check
# Thresholds below are illustrative -- calibrate via backtesting
mp_long_pct = mp.get("longPct", 50)
if mp_long_pct > 70 and yes_mid < 0.50: # example values
# Example sizing to meet $10 minimum notional
size = max(10, int(10 / yes_mid) + 1)
print(f"Signal: {underlying} MP {mp_long_pct}% long, "
f"YES at {yes_mid:.2f}. Buying YES.")
place_outcome_order(exchange, oid, 0, True, yes_mid, size)
time.sleep(300) # 5-minute cycle
# Patch SDK and run
info, exchange = make_clients(PRIVATE_KEY, ADDRESS, BASE_URL)
while True:
run_bot(exchange, info)
The divergence threshold and sizing logic here are illustrative. In production, you'd calibrate these based on backtesting and your own risk tolerance. The point is the architecture: prediction market pricing + cohort positioning = a signal layer that standalone prediction market traders don't have access to.
Edge Cases and Gotchas
SDK Patching is Mandatory
The official hyperliquid-python-sdk doesn't know about HIP-4 assets. You need to fetch outcomeMeta at startup and inject every outcome's encoding into the SDK's coin_to_asset and name_to_coin maps. Without this patch, the SDK will reject your orders with an opaque error about unknown coins.
def make_clients(private_key, address, base_url):
account = Account.from_key(private_key)
info = Info(base_url, skip_ws=True)
exchange = Exchange(account, base_url, account_address=address)
meta = fetch_outcome_meta()
for o in meta.get("outcomes", []):
for side in (0, 1):
coin = encode_coin(o["outcome"], side)
asset_id = encode_asset_id(o["outcome"], side)
info.coin_to_asset[coin] = asset_id
info.name_to_coin[coin] = coin
exchange.info.coin_to_asset[coin] = asset_id
exchange.info.name_to_coin[coin] = coin
return info, exchange
Integer Sizing Only
Unlike perp positions where you can trade fractional coin sizes, HIP-4 requires integer units. If your computed size comes out to 22.7, round up to 23. Always verify the minimum notional: size * price >= 10 USDC.
Settlement is Automatic
You don't need to call a redemption function. At expiry, USDC credits land in your account automatically based on which side won. No gas fees, no claim transaction.
Builder Codes Work Here Too
If you're building a front end on top of HIP-4, builder codes earn fees on sell orders the same way they do for spot trading. This means every prediction market platform built on Hyperliquid can monetize through builder codes without charging users directly.
Add Cohort Intelligence to Your Prediction Market Bot
HyperTracker's API gives you the cohort positioning data that turns generic prediction market bots into smart money-aware systems. 16 behavioral segments, refreshed every 5 minutes, accessible in one API call.
Start Building with HyperTracker
The prediction market landscape is still early. HIP-4 shares the same matching engine, account model, and API surface as Hyperliquid's perps and spot markets, which means everything you already know about building on Hyperliquid transfers directly. The only new concepts are the encoding scheme, integer sizing, and the fact that your positions can't be liquidated. For builders already working with cohort data, prediction markets are just another instrument to layer signals onto. The edge isn't in the prediction market itself. It's in knowing what smart money is doing on the underlying before the outcome market prices it in.