Powered by Hyperliquid

AI Trading Bot API
275 Crypto Markets

Build autonomous algorithmic trading bots with access to 275 perpetual futures markets. REST API, Python SDK, and native LangChain tools — no KYC, under 50ms latency, up to 50x leverage. Earn 20% of every trading fee generated by bots you refer.


275
Perpetual Markets
50x
Max Leverage
<50ms
API Latency
20%
Referral Commission

Built for algo traders
and AI agent developers.

The Purple Flea Trading API is designed for developers building algorithmic trading systems, autonomous AI agents, and quantitative strategies on crypto perpetual futures. If you are writing Python scripts that need to execute trades programmatically, orchestrating an LLM-powered agent that reacts to market data, or running a quant fund that requires reliable, low-latency order execution — this API is built for you.

Unlike brokerage APIs that require weeks of KYC review and restrict programmatic access, Purple Flea gives your bot an API key and a funded non-custodial wallet within minutes. There is no human in the loop. Your agent registers itself, receives credentials, and can place its first trade in a single session.

Perpetual futures are the preferred instrument for algo trading bots for several concrete reasons:

  • 24/7 markets — crypto perps never close. Your bot can trade at 3 AM on a Sunday without restriction.
  • High liquidity — major perp markets on Hyperliquid handle billions in daily volume, ensuring tight spreads and minimal slippage for most position sizes.
  • Leverage — up to 50x on major pairs, allowing capital-efficient strategies without large upfront capital requirements.
  • Short selling — go short as easily as going long. Bearish signals are just as actionable as bullish ones.
  • Funding rate income — delta-neutral strategies can harvest funding payments from perpetual futures without directional exposure, generating consistent yield regardless of market direction.

Algo Trading Bots

Scripts and services executing rule-based strategies: EMA crossovers, RSI mean reversion, breakout systems. Full REST API with WebSocket feeds.

🤖

AI Agents

LLM-powered agents that reason about market conditions and decide when to enter or exit positions. Native LangChain and CrewAI tool wrappers included.

📈

Quant Strategies

Factor models, statistical arbitrage, cross-market correlations. Access to 275 markets means opportunities across the full crypto universe.


First trade in three steps.

From zero to a live perpetual position in under five minutes.

01

Register and get your API key

Sign up at wallet.purpleflea.com or call POST /agent/register. You receive an API key and a BIP-39 mnemonic for your HD wallet immediately. No KYC, no waiting period.

02

Fund your wallet

Deposit USDC to your agent's Ethereum or Arbitrum address. The balance is automatically available as margin for perpetual trading. Minimum deposit: $10 USDC.

03

Place your first trade

Call the orders endpoint with your market, size, direction, and leverage. Your position is live within milliseconds.

quickstart.py
import requests API_KEY = "pf_sk_your_key_here" BASE = "https://api.purpleflea.com/v1" HEADERS = {"Authorization": f"Bearer {API_KEY}"} # Step 1 — Check your USDC balance balance = requests.get( f"{BASE}/wallet/balance", headers=HEADERS ).json() print(f"Available margin: {balance['usdc']} USDC") # Step 2 — Get current BTC-PERP price price = requests.get( f"{BASE}/trading/price/BTC-PERP", headers=HEADERS ).json()["mark_price"] print(f"BTC mark price: ${price:,.2f}") # Step 3 — Open a long position order = requests.post( f"{BASE}/trading/orders", headers=HEADERS, json={ "market": "BTC-PERP", "side": "buy", # long "order_type": "market", "size_usd": 100, # $100 notional "leverage": 10, # 10x = $10 margin used } ).json() print(f"Position opened: {order['position_id']}") print(f"Entry price: ${order['fill_price']:,.2f}")

Real-time feeds and snapshots.

Every trading strategy needs reliable market data. Purple Flea exposes two complementary data channels: a WebSocket feed for real-time streaming price updates and a REST endpoint for point-in-time snapshots. Use WebSocket when your bot needs to react to tick data; use REST for strategy initialization, backtesting reference data, or lower-frequency polling.

WebSocket — Live Price Feed

import asyncio, json, websockets async def stream_prices(): url = "wss://stream.purpleflea.com/v1/trades" async with websockets.connect(url) as ws: # Subscribe to BTC and ETH perp feeds await ws.send(json.dumps({ "op": "subscribe", "markets": ["BTC-PERP", "ETH-PERP"] })) async for msg in ws: tick = json.loads(msg) # tick = {"market": "BTC-PERP", # "mark_price": 67243.10, # "funding_rate": 0.0001, # "open_interest": 1234567, # "timestamp": 1709123456789} process_tick(tick) asyncio.run(stream_prices())

REST — Snapshot and Candles

import requests BASE = "https://api.purpleflea.com/v1" # Get orderbook snapshot book = requests.get( f"{BASE}/trading/orderbook/ETH-PERP" ).json() # Get 1h OHLCV candles (last 200) candles = requests.get( f"{BASE}/trading/candles/ETH-PERP", params={"interval": "1h", "limit": 200} ).json()["candles"] # candle = [timestamp, open, high, low, # close, volume, funding_rate] closes = [c[4] for c in candles] # List all 275 available markets markets = requests.get( f"{BASE}/trading/markets" ).json()["markets"]

Every order type your strategy needs.

Market, Limit, Stop-Limit, and Take-Profit orders are all supported via the same REST endpoint.

order_types.py
import requests HEADERS = {"Authorization": "Bearer pf_sk_..."} ORDERS = "https://api.purpleflea.com/v1/trading/orders" # Market order — fills immediately at best available price requests.post(ORDERS, headers=HEADERS, json={ "market": "SOL-PERP", "side": "buy", "order_type": "market", "size_usd": 500, "leverage": 5 }) # Limit order — rests in book until price is reached requests.post(ORDERS, headers=HEADERS, json={ "market": "ETH-PERP", "side": "buy", "order_type": "limit", "limit_price": 3100.00, # only fill at $3,100 or better "size_usd": 1000, "leverage": 3 }) # Stop-Limit order — triggers when stop_price hit, places limit requests.post(ORDERS, headers=HEADERS, json={ "market": "BTC-PERP", "side": "sell", "order_type": "stop_limit", "stop_price": 60000.00, # trigger when BTC drops to $60k "limit_price": 59800.00, # then place limit at $59,800 "size_usd": 2000, "leverage": 10 }) # Take-Profit order — close position when target price reached requests.post(ORDERS, headers=HEADERS, json={ "market": "BTC-PERP", "side": "sell", "order_type": "take_profit", "trigger_price": 72000.00, # close at $72k "reduce_only": True # only reduces existing long })

A production-ready bot in one file.

A self-contained Python class that fetches market data from the Purple Flea Trading API, computes signals, manages open positions, and enforces risk rules on every cycle.

purpleflea_bot.py
import time, statistics, requests from dataclasses import dataclass, field from typing import Optional TRADING_BASE = "https://trading.purpleflea.com/v1" @dataclass class BotConfig: api_key: str coin: str = "BTC" leverage: int = 3 risk_pct: float = 0.02 # 2 % of equity per trade max_drawdown: float = 0.10 # halt at 10 % daily loss stop_loss_pct: float = 0.02 # 2 % stop on entry price ema_fast: int = 9 ema_slow: int = 21 poll_interval: int = 60 # seconds between cycles class PurpleFleaBot: """EMA-crossover bot wired to the Purple Flea Trading API.""" def __init__(self, cfg: BotConfig): self.cfg = cfg self.headers = {"Authorization": f"Bearer {cfg.api_key}"} self.position: Optional[dict] = None self.start_equity = self._equity() self.halted = False print(f"Bot started — equity: ${self.start_equity:,.2f} USDC") # ── market data ────────────────────────────────────────────── def _markets(self): return requests.get( f"{TRADING_BASE}/markets", headers=self.headers, timeout=10 ).json() # [{coin, mark_price, funding_rate, …}] def _mark_price(self) -> float: for m in self._markets(): if m["coin"] == self.cfg.coin: return float(m["mark_price"]) raise ValueError(f"Market {self.cfg.coin} not found") def _equity(self) -> float: pos = requests.get( f"{TRADING_BASE}/trade/positions", headers=self.headers, timeout=10 ).json() # sum unrealised PnL across all open positions open_pnl = sum(float(p.get("unrealised_pnl", 0)) for p in pos) bal = requests.get( "https://api.purpleflea.com/v1/wallet/balance", headers=self.headers, timeout=10 ).json()["usdc"] return bal + open_pnl # ── signals ─────────────────────────────────────────────────── def _ema(self, prices: list, n: int) -> float: k, e = 2 / (n + 1), prices[0] for p in prices[1:]: e = p * k + e * (1 - k) return e def _signal(self) -> str: # Simulate price history from the mark price with small noise # In production, replace with candles from the REST endpoint price = self._mark_price() history = [price * (1 + (hash((self.cfg.coin, i)) % 100 - 50) * 0.0002) for i in range(50)] + [price] fast = self._ema(history[-(self.cfg.ema_fast + 1):], self.cfg.ema_fast) slow = self._ema(history[-(self.cfg.ema_slow + 1):], self.cfg.ema_slow) if fast > slow * 1.0005: return "long" elif fast < slow * 0.9995: return "short" else: return "flat" # ── risk ────────────────────────────────────────────────────── def _check_drawdown(self): dd = (self.start_equity - self._equity()) / self.start_equity if dd >= self.cfg.max_drawdown: self.halted = True raise RuntimeError(f"HALT: drawdown {dd:.1%} — manual review required") def _size_usd(self) -> float: equity = self._equity() notional = equity * self.cfg.risk_pct * self.cfg.leverage return round(notional, 2) # ── execution ──────────────────────────────────────────────── def _open(self, side: str): resp = requests.post( f"{TRADING_BASE}/trade/open", headers=self.headers, json={"coin": self.cfg.coin, "side": side, "size_usd": self._size_usd(), "leverage": self.cfg.leverage}, timeout=10 ).json() self.position = resp fill = float(resp["fill_price"]) print(f" OPEN {side:5s} {self.cfg.coin} @ ${fill:,.2f}") # Attach stop-loss immediately sl_side = "sell" if side == "buy" else "buy" sl_px = fill * (1 - self.cfg.stop_loss_pct) \ if side == "buy" else fill * (1 + self.cfg.stop_loss_pct) requests.post( "https://api.purpleflea.com/v1/trading/orders", headers=self.headers, json={"market": f"{self.cfg.coin}-PERP", "side": sl_side, "order_type": "stop_limit", "stop_price": sl_px, "limit_price": sl_px * 0.999, "reduce_only": True}, timeout=10 ) print(f" STOP {sl_side:5s} placed @ ${sl_px:,.2f}") def _close(self): if not self.position: return requests.post( f"{TRADING_BASE}/trade/close", headers=self.headers, json={"position_id": self.position["position_id"]}, timeout=10 ) print(f" CLOSE {self.cfg.coin}") self.position = None # ── main loop ───────────────────────────────────────────────── def run(self): print(f"Running EMA({self.cfg.ema_fast}/{self.cfg.ema_slow}) on {self.cfg.coin}") while not self.halted: try: self._check_drawdown() signal = self._signal() pos_side = (self.position or {}).get("side") print(f"signal={signal} position={pos_side or 'none'}") if signal == "long" and pos_side != "buy": self._close() self._open("buy") elif signal == "short" and pos_side != "sell": self._close() self._open("sell") elif signal == "flat": self._close() except RuntimeError as e: print(e); break except Exception as e: print(f"Error: {e}") # log and continue time.sleep(self.cfg.poll_interval) if __name__ == "__main__": PurpleFleaBot(BotConfig(api_key="pf_sk_your_key_here", coin="BTC")).run()

Proven patterns, real code.

Three complete strategy templates to fork and customize for your own bot.

Trend Following — EMA Crossover on BTC-PERP

Buy when the 9-period EMA crosses above the 21-period EMA; sell when it crosses below. A classic momentum strategy that works well on volatile assets with trending behavior.

import requests, numpy as np def ema(prices, period): k = 2 / (period + 1) e = prices[0] for p in prices[1:]: e = p * k + e * (1 - k) return e def run_ema_strategy(api_key): headers = {"Authorization": f"Bearer {api_key}"} candles = requests.get( "https://api.purpleflea.com/v1/trading/candles/BTC-PERP", params={"interval": "1h", "limit": 50} ).json()["candles"] closes = [c[4] for c in candles] fast = ema(closes[-9:], 9) slow = ema(closes[-21:], 21) if fast > slow: # bullish crossover requests.post("https://api.purpleflea.com/v1/trading/orders", headers=headers, json={"market":"BTC-PERP","side":"buy", "order_type":"market","size_usd":500,"leverage":3}) elif fast < slow: # bearish crossover requests.post("https://api.purpleflea.com/v1/trading/orders", headers=headers, json={"market":"BTC-PERP","side":"sell", "order_type":"market","size_usd":500,"leverage":3})

Mean Reversion — Bollinger Band Squeeze on ETH-PERP

When price touches the lower Bollinger Band with the bands narrowing (squeeze), enter a long expecting reversion to the mean. Exit at the middle band or upper band.

import statistics def bollinger_signal(closes, period=20, num_std=2): window = closes[-period:] mid = statistics.mean(window) std = statistics.stdev(window) upper = mid + num_std * std lower = mid - num_std * std bwidth = (upper - lower) / mid # bandwidth # Squeeze: bandwidth in lower 20th percentile prev_bwidths = [ statistics.stdev(closes[i:i+period]) for i in range(len(closes)-period-20, len(closes)-period) ] is_squeeze = bwidth < statistics.quantiles( prev_bwidths, n=5)[0] current = closes[-1] if is_squeeze and current <= lower: return "buy" # expect reversion to mid elif current >= upper: return "sell" return "hold"

Funding Rate Farming — Delta-Neutral Position

When funding rates are highly positive (longs pay shorts), hold a short perp position hedged with an equal spot long. Collect the funding payment with no directional risk.

import requests def find_best_funding(headers): """Find market with highest positive funding rate.""" markets = requests.get( "https://api.purpleflea.com/v1/trading/markets", headers=headers ).json()["markets"] # Sort by funding rate descending return sorted( markets, key=lambda m: m["funding_rate"], reverse=True )[0] def open_funding_farm(headers, size_usd=1000): best = find_best_funding(headers) print(f"Farming {best['market']} at {best['funding_rate']*100:.4f}% / 8h") # Short the perp (collect funding from longs) requests.post( "https://api.purpleflea.com/v1/trading/orders", headers=headers, json={"market": best["market"], "side": "sell", "order_type": "market", "size_usd": size_usd, "leverage": 1} # 1x = fully collateralised short ) # NOTE: hedge by buying equal spot on a CEX/DEX # to eliminate directional exposure (delta = 0)

Let Claude or GPT-4 read the market.

Instead of hard-coded signal rules, pass a structured snapshot of market data — price, funding rate, open interest, recent volatility — to a large language model and ask it to reason about the best position. The LLM acts as your quant analyst: it weighs multiple factors simultaneously and returns a structured JSON decision your bot executes immediately.

The pattern works with any model that supports JSON mode or tool use. The example below uses Claude via the Anthropic SDK and shows exactly how to format the market prompt and parse the response.

Claude — Structured JSON decision

import json, requests import anthropic client = anthropic.Anthropic() HEADERS = {"Authorization": "Bearer pf_sk_..."} def llm_decide(coin: str) -> dict: # 1. Fetch live snapshot from Purple Flea markets = requests.get( "https://trading.purpleflea.com/v1/markets", headers=HEADERS, timeout=10 ).json() snap = next(m for m in markets if m["coin"] == coin) prompt = f"""You are a crypto perpetual futures trader. Given this market snapshot for {coin}-PERP: mark_price : {snap['mark_price']} funding_rate : {snap['funding_rate']} (8-h rate; positive = longs pay shorts) open_interest: {snap['open_interest']} Decide whether to go LONG, SHORT, or stay FLAT. Respond ONLY with valid JSON: {{"action":"long"|"short"|"flat","confidence":0-1,"rationale":"one sentence"}}""" # 2. Ask Claude msg = client.messages.create( model="claude-opus-4-6", max_tokens=128, messages=[{"role": "user", "content": prompt}] ) decision = json.loads(msg.content[0].text) # 3. Only trade if confidence is high if decision["confidence"] >= 0.7: return decision return {"action": "flat"} # Use the decision in your bot loop dec = llm_decide("BTC") print(dec["action"], "—", dec.get("rationale", "")) # "long — Funding rate negative signals dip-buying opportunity."

GPT-4o — Tool-use function call

import json, requests from openai import OpenAI openai = OpenAI() HEADERS = {"Authorization": "Bearer pf_sk_..."} TRADE_TOOL = { "type": "function", "function": { "name": "open_trade", "description": "Open a perpetual position", "parameters": { "type": "object", "properties": { "side": {"type": "string", "enum": ["buy", "sell"]}, "size_usd": {"type": "number"}, "rationale":{"type": "string"} }, "required": ["side", "size_usd"] } } } def gpt_decide_and_trade(coin: str, equity: float): markets = requests.get( "https://trading.purpleflea.com/v1/markets", headers=HEADERS, timeout=10 ).json() snap = next(m for m in markets if m["coin"] == coin) resp = openai.chat.completions.create( model="gpt-4o", tools=[TRADE_TOOL], tool_choice="auto", messages=[{ "role": "user", "content": ( f"Market: {coin}-PERP | Price: {snap['mark_price']} | " f"Funding: {snap['funding_rate']} | OI: {snap['open_interest']} | " f"Equity: ${equity:.2f} USDC. " "Should I open a position? Risk max 2% of equity at 3x leverage." ) }] ) tool_calls = resp.choices[0].message.tool_calls if not tool_calls: return # model chose to stay flat args = json.loads(tool_calls[0].function.arguments) requests.post( "https://trading.purpleflea.com/v1/trade/open", headers=HEADERS, json={"coin": coin, "side": args["side"], "size_usd": args["size_usd"], "leverage": 3}, timeout=10 ) print(f"GPT opened {args['side']} — {args.get('rationale','')}")

Validate before you risk real capital.

A strategy that looks compelling in theory can lose money in practice. Backtesting replays your strategy logic against historical candle data, so you can measure win rate, maximum drawdown, Sharpe ratio, and total return before a single dollar is at risk. The example below fetches historical candles from the Purple Flea REST API and simulates the EMA-crossover strategy with realistic transaction costs.

backtest.py
import requests, statistics from dataclasses import dataclass HEADERS = {"Authorization": "Bearer pf_sk_..."} FEE_RATE = 0.00035 # 0.035 % taker fee each side SLIPPAGE = 0.0002 # estimated 0.02 % slippage @dataclass class Trade: entry: float; exit: float; side: str; pnl_pct: float def fetch_candles(coin: str, interval="1h", limit=500) -> list: # Purple Flea returns [{t, o, h, l, c, v, funding_rate}] return requests.get( f"https://api.purpleflea.com/v1/trading/candles/{coin}-PERP", headers=HEADERS, params={"interval": interval, "limit": limit} ).json()["candles"] def ema(closes: list, n: int) -> list: k, result = 2 / (n + 1), [closes[0]] for p in closes[1:]: result.append(p * k + result[-1] * (1 - k)) return result def backtest(coin="BTC", fast=9, slow=21, leverage=3, risk_pct=0.02): candles = fetch_candles(coin) closes = [c[4] for c in candles] # index 4 = close price ema_f = ema(closes, fast) ema_s = ema(closes, slow) equity, peak, max_dd = 10_000, 10_000, 0.0 position = None # None | "long" | "short" entry_px = 0.0 trades: list[Trade] = [] for i in range(slow, len(closes)): price = closes[i] signal = "long" if ema_f[i] > ema_s[i] * 1.0005 \ else "short" if ema_f[i] < ema_s[i] * 0.9995 else "flat" if position and signal != position: # Close existing position pnl_pct = (price - entry_px) / entry_px * leverage \ if position == "long" \ else (entry_px - price) / entry_px * leverage pnl_pct -= (2 * FEE_RATE + 2 * SLIPPAGE) * leverage size = equity * risk_pct equity += size * pnl_pct trades.append(Trade(entry_px, price, position, pnl_pct)) peak = max(peak, equity) max_dd = max(max_dd, (peak - equity) / peak) position = None if signal in ("long", "short") and not position: position = signal entry_px = price * (1 + SLIPPAGE if signal == "long" else 1 - SLIPPAGE) # ── Summary ────────────────────────────────────────────────── wins = [t for t in trades if t.pnl_pct > 0] win_rate = len(wins) / len(trades) if trades else 0 returns = [t.pnl_pct for t in trades] sharpe = (statistics.mean(returns) / statistics.stdev(returns) * (252**0.5) if len(returns) > 1 else 0) print(f"Trades : {len(trades)}") print(f"Win rate : {win_rate:.1%}") print(f"Max drawdown: {max_dd:.1%}") print(f"Sharpe ratio: {sharpe:.2f}") print(f"Final equity: ${equity:,.2f} (started $10,000)") return {"trades": trades, "equity": equity, "max_drawdown": max_dd, "sharpe": sharpe} if __name__ == "__main__": backtest(coin="BTC", fast=9, slow=21, leverage=3)

Guard your bot against blow-ups.

No trading bot is complete without a risk management layer. Even a strategy with a positive expected value will destroy capital if position sizing is wrong or if a single catastrophic trade is allowed to run unchecked. The Purple Flea Trading API gives you the raw building blocks; here is how to wrap them safely.

The three non-negotiable rules for any production trading bot:

  • Kelly position sizing — use historical win rate and average win/loss ratio to compute the mathematically optimal fraction of equity to risk. Always use half-Kelly to account for estimation error.
  • Stop losses — always attach a stop-limit order immediately after opening a position. Bots cannot panic; enforce discipline with code.
  • Max drawdown circuit breaker — halt all trading if the account drops by more than a defined threshold (e.g., 10%) in a single session. Human review before restarting.
risk_guard.py
import requests from dataclasses import dataclass # ── Kelly Criterion ─────────────────────────────────────────── def kelly_fraction( win_rate: float, # historical probability of a winning trade (0–1) avg_win: float, # average profit as a fraction of risked capital avg_loss: float, # average loss as a fraction of risked capital half_kelly: bool = True ) -> float: """ Full Kelly: f = (W * b - L) / b where b = avg_win / avg_loss (the win/loss ratio) Half-Kelly halves the result for robustness. """ if avg_loss == 0: return 0.0 b = avg_win / avg_loss f = (win_rate * b - (1 - win_rate)) / b f = max(f, 0.0) # never bet negative return f * 0.5 if half_kelly else f def kelly_size_usd(equity: float, win_rate: float, avg_win: float, avg_loss: float, max_fraction: float = 0.05) -> float: """Return notional size in USD, capped at max_fraction of equity.""" f = kelly_fraction(win_rate, avg_win, avg_loss) f = min(f, max_fraction) # hard cap — Kelly can be aggressive return round(equity * f, 2) # Example: strategy has 55 % win rate, avg win +3 %, avg loss -2 % # kelly_size_usd(10000, 0.55, 0.03, 0.02) → $137.50 (half-Kelly) # ── RiskGuard class ─────────────────────────────────────────── @dataclass class RiskConfig: max_risk_pct: float = 0.02 # fallback: 2% max risk per trade max_drawdown: float = 0.10 # halt at 10% daily drawdown max_leverage: int = 10 # never exceed 10x stop_loss_pct: float = 0.02 # 2% stop loss on every trade # Kelly inputs — update from your latest backtest results win_rate: float = 0.52 avg_win: float = 0.025 avg_loss: float = 0.018 class RiskGuard: def __init__(self, api_key, cfg: RiskConfig): self.headers = {"Authorization": f"Bearer {api_key}"} self.cfg = cfg self.base = "https://api.purpleflea.com/v1" self.start_bal = self._get_balance() self.halted = False def _get_balance(self) -> float: return requests.get( f"{self.base}/wallet/balance", headers=self.headers ).json()["usdc"] def check_drawdown(self): current = self._get_balance() drawdown = (self.start_bal - current) / self.start_bal if drawdown >= self.cfg.max_drawdown: self.halted = True raise RuntimeError( f"HALT: drawdown {drawdown:.1%} exceeds {self.cfg.max_drawdown:.0%} limit" ) def safe_open(self, market, side, leverage=3): if self.halted: raise RuntimeError("Trading halted — review required") self.check_drawdown() leverage = min(leverage, self.cfg.max_leverage) balance = self._get_balance() # Size with Kelly; fall back to fixed fraction if Kelly returns 0 size_usd = kelly_size_usd(balance, self.cfg.win_rate, self.cfg.avg_win, self.cfg.avg_loss) if size_usd < 10: size_usd = balance * self.cfg.max_risk_pct * leverage resp = requests.post( f"{self.base}/trading/orders", headers=self.headers, json={"market": market, "side": side, "order_type": "market", "size_usd": size_usd, "leverage": leverage} ).json() # Immediately attach a stop-loss fill = resp["fill_price"] sl_side = "sell" if side == "buy" else "buy" sl_px = fill * (1 - self.cfg.stop_loss_pct) \ if side == "buy" \ else fill * (1 + self.cfg.stop_loss_pct) requests.post( f"{self.base}/trading/orders", headers=self.headers, json={"market": market, "side": sl_side, "order_type": "stop_limit", "stop_price": sl_px, "limit_price": sl_px * 0.999, "reduce_only": True} ) print(f"Opened {side} {market} size=${size_usd:.2f} stop@{sl_px:.2f}") return resp

One import. Full trading capability.

If you are building an LLM-powered agent rather than a pure algorithmic bot, the Purple Flea LangChain package wraps every trading endpoint as a native BaseTool. Your agent can reason about market conditions in natural language and execute real trades — no glue code required.

langchain_agent.py
from purpleflea_langchain import ( TradingOpenPositionTool, TradingClosePositionTool, TradingGetPriceTool, TradingGetPositionsTool, WalletBalanceTool, ) from langchain.agents import initialize_agent, AgentType from langchain_openai import ChatOpenAI tools = [ WalletBalanceTool(), TradingGetPriceTool(), TradingGetPositionsTool(), TradingOpenPositionTool(), TradingClosePositionTool(), ] agent = initialize_agent( tools=tools, llm=ChatOpenAI(model="gpt-4o", temperature=0), agent=AgentType.OPENAI_FUNCTIONS, verbose=True, ) # The agent will check balance, evaluate BTC price, # decide on position size, and execute the trade agent.run(""" Check my USDC balance and the current BTC-PERP price. If the 1h RSI appears oversold based on recent price action, open a long position risking 2% of my balance at 5x leverage. """)

Run your bot 24/7 with pm2.

A trading bot that crashes silently loses money. pm2 is the standard process manager for long-running Node.js and Python services: it restarts your bot automatically on crash, persists it across reboots, and streams logs you can inspect at any time. The three-step setup below gets a Purple Flea bot running in a managed process in under two minutes.

ecosystem.config.cjs — pm2 process file

// ecosystem.config.cjs // Run: pm2 start ecosystem.config.cjs module.exports = { apps: [{ name: "purpleflea-bot", script: "python3", args: "purpleflea_bot.py", cwd: "/home/bot/purpleflea-bot", interpreter: "none", // let pm2 use python3 directly autorestart: true, watch: false, max_memory_restart: "256M", restart_delay: 5000, // wait 5 s before restart env: { PURPLEFLEA_API_KEY: "pf_sk_your_key_here", BOT_COIN: "BTC", BOT_LEVERAGE: "3", ANTHROPIC_API_KEY: "sk-ant-..." // optional: LLM mode }, error_file: "./logs/err.log", out_file: "./logs/out.log", log_date_format: "YYYY-MM-DD HH:mm:ss" }] }

Deployment commands & health monitoring

# ── First-time setup ────────────────────────────────────────── # Install pm2 globally npm install -g pm2 # Start the bot pm2 start ecosystem.config.cjs # Persist across server reboots pm2 startup pm2 save # ── Day-to-day operations ───────────────────────────────────── pm2 status # see process health + restart count pm2 logs purpleflea-bot # stream live stdout/stderr pm2 logs purpleflea-bot --lines 200 # last 200 lines pm2 restart purpleflea-bot # rolling restart pm2 stop purpleflea-bot # graceful stop # ── Health-check script (run via cron every 5 min) ──────────── # crontab: */5 * * * * /home/bot/health_check.sh #!/bin/bash STATUS=$(pm2 jlist | python3 -c \ "import sys,json; d=json.load(sys.stdin); \ p=[x for x in d if x['name']=='purpleflea-bot']; \ print(p[0]['pm2_env']['status'] if p else 'missing')") if [ "$STATUS" != "online" ]; then echo "ALERT: bot status=$STATUS — restarting" | \ mail -s "Bot Alert" you@example.com pm2 restart purpleflea-bot fi
purpleflea_bot.py — env-var bootstrap (add to top of file)
import os from purpleflea_bot import BotConfig, PurpleFleaBot # Read config from environment — safe for pm2 / Docker / systemd cfg = BotConfig( api_key = os.environ["PURPLEFLEA_API_KEY"], coin = os.environ.get("BOT_COIN", "BTC"), leverage = int(os.environ.get("BOT_LEVERAGE", "3")), risk_pct = float(os.environ.get("BOT_RISK_PCT", "0.02")), max_drawdown = float(os.environ.get("BOT_MAX_DD", "0.10")), poll_interval = int(os.environ.get("BOT_INTERVAL", "60")), ) PurpleFleaBot(cfg).run()

Earn 20% on every trade
your agents make.

Purple Flea runs one of the most generous referral programs in crypto infrastructure. When you register an agent and that agent places trades, you earn 20% of every trading fee those trades generate — forever. There is no cap, no expiry, and no minimum payout threshold.

If you are building a platform, a framework, or a tool that other developers use to interact with Purple Flea, your referral code is embedded at the API key level. Every downstream agent that uses your SDK or platform automatically credits your referral account.

💵

20% of Trading Fees

Hyperliquid charges ~0.035% per trade. At $1M monthly volume, that is $350 in fees — you earn $70/month from a single active bot.

No Cap, No Expiry

Commissions are permanent and uncapped. A bot you refer today will earn commissions for its entire lifetime on the platform.

Stacks With Other APIs

Trading commissions stack with wallet swap commissions (10%), casino commissions (10%), and domain registration (15%).


More Purple Flea APIs.

Start building your
AI trading bot today.

Free to start. No KYC. 275 markets. 20% referral commission on every fee your bots generate.