Strategy Guide

Basis Trading for AI Agents: Cash-and-Carry Arbitrage

The futures basis is one of the most reliable, exploitable mispricings in crypto. Every time a perpetual or dated futures contract trades at a premium to spot, it represents a lockable yield. AI agents are uniquely suited to capture it: they execute instantly, roll positions mechanically, and never succumb to the impatience that causes human traders to cut positions early. This guide covers everything from basis math to a fully autonomous Python BasisTradingAgent.

What Is the Futures Basis?

The basis is the price difference between a futures (or perpetual) contract and its underlying spot asset:

Basis = Futures Price − Spot Price
Positive basis = contango  ·  Negative basis = backwardation

In traditional commodity markets, the basis reflects storage costs, insurance, and convenience yield. In crypto futures markets it reflects two additional forces: the cost of leverage demand (traders willing to pay a premium to go long on margin) and the time value of money denominated in stablecoins.

When retail traders are bullish they bid up perpetual contract prices above spot, creating a positive basis. A basis trader extracts this premium by taking the opposite side: buy spot, short futures. At expiry (or at any time for perpetuals via the funding mechanism), the basis converges toward zero, realising the spread as profit.

Key insight: The basis trade earns a predictable yield that is largely uncorrelated with the direction of the underlying asset. Whether BTC rises 40% or falls 40%, the basis P&L is determined by the spread at entry minus the spread at exit — not the absolute price level. This makes it one of the few genuinely market-neutral strategies in crypto.

Basis in Perpetual vs Dated Futures

Crypto offers two types of futures contracts, and the basis mechanics differ between them:

Perpetual Swaps

Perpetuals have no expiry date. Instead of converging at a fixed date, they use a funding rate mechanism to anchor the perpetual price to spot. Every 8 hours, the side that is trading at a premium pays the other side a funding payment. When the perpetual trades above spot (positive basis), longs pay shorts. A basis trader who is short the perpetual and long spot receives these payments continuously.

The perpetual basis at any moment is approximately the 8-hour funding rate annualised:

Annualised Basis (%) = Funding Rate (8h) × 3 × 365 × 100
3 funding periods per day × 365 days

Dated Futures

Quarterly and monthly futures have a fixed expiry date. The basis decays predictably toward zero as expiry approaches. The annualised yield for a dated future is:

Annualised Basis (%) = [(Futures / Spot) − 1] × (365 / DTE) × 100
DTE = days to expiry

For example, if BTC spot is $95,000 and the June quarterly future trades at $97,850 with 90 days to expiry:

[(97850 / 95000) − 1] × (365 / 90) × 100 = 12.16% annualised
3% raw basis / 90 days scaled to full year
8–18%
Typical BTC annualised basis (bull market)
15–40%
Alt-coin perpetual annualised funding
0.01%
Min funding rate per 8h period (clamp floor)
0.75%
Max funding rate per 8h period (clamp ceiling)

Contango vs Backwardation

The sign of the basis defines the market structure. Both conditions create tradeable opportunities, but the direction of the trade reverses:

Condition Basis Sign Market Sentiment Basis Trade Direction Typical Yield Source
Contango + Bullish (longs dominant) Long spot + Short futures Receive funding from longs
Backwardation Bearish (shorts dominant) Short spot + Long futures Receive funding from shorts
Flat ≈0 Neutral No position (sub-threshold) None worth taking

In practice, crypto markets spend roughly 70–80% of time in contango during bull markets and 40–60% in backwardation during bear phases. An agent that can flip its position direction based on the basis sign captures yield in both environments.

The Backwardation Basis Trade

Running the inverse trade in backwardation — short spot, long futures — requires the ability to borrow and short the underlying asset. For agents without spot borrowing access this trade is typically skipped. The contango direction (long spot + short perp) is the default for most autonomous agents since it requires only a direct purchase of the spot asset.

Cash-and-Carry Arbitrage Mechanics

The cash-and-carry trade is the physical implementation of a contango basis trade:

  1. Buy the underlying asset (spot leg): Purchase BTC, ETH, or any supported asset at spot price using stablecoin capital from your Purple Flea wallet.
  2. Short the futures contract (short leg): Simultaneously open a short position in the corresponding perpetual or dated futures at the premium price. This hedges your spot exposure, making the combined position delta-neutral.
  3. Hold until convergence: For perpetuals, collect the 8-hourly funding payments. For dated futures, hold until expiry when the basis converges to zero by definition.
  4. Unwind: Sell the spot position and close the short futures. Net P&L = funding collected (perp) or basis at entry (dated) minus execution costs.

Critical: Both legs must execute at approximately the same time. Legged execution — placing the spot order and then waiting to place the futures order — creates temporary directional exposure. Use limit orders on both legs simultaneously, or accept a small market-order premium to ensure tight execution.

Transaction Cost Budget

Basis trades are low-gross-yield strategies. Every basis point of transaction cost matters:

Cost ComponentTypical RangeNotes
Spot maker fee0.02–0.08%Use limit orders to qualify for maker rates
Perp maker fee-0.01–0.03%Negative = rebate for adding liquidity
Spot taker fee0.05–0.12%If you need instant fill
Funding paid (if wrong)variableZero in contango if you are short the perp
Slippage (large sizes)0.01–0.10%Scales with order size relative to book depth

Rule of thumb: only enter a basis position if the annualised yield exceeds 5% after fees. Below that threshold, fee variance alone can eliminate the entire profit.

Annualised Basis Rate Calculation in Detail

To compare basis trades across different assets and time horizons on a standardized basis, always convert raw basis to an annualised percentage yield. The formula for perpetuals uses the current funding rate:

Perp APY = (Spot Funding Rate / 100) × 3 × 365 × 100
Where funding rate is expressed as a decimal for one 8h period

For a more precise measure, use the rolling 7-day average funding rate rather than the instantaneous rate. The instantaneous rate is highly volatile and can produce misleading yield estimates:

PYTHONbasis_math.py
import statistics

def annualised_perp_basis(funding_rates_8h: list[float]) -> float:
    """
    Calculate annualised basis yield from a list of 8-hour funding rates.

    Args:
        funding_rates_8h: List of funding rates (as %, e.g. 0.0300 means 0.03%)
                          Positive = longs pay shorts (contango)

    Returns:
        Annualised yield in percent (e.g. 13.14 means 13.14% APY)
    """
    if not funding_rates_8h:
        return 0.0

    avg_rate = statistics.mean(funding_rates_8h)  # average 8h rate as %
    periods_per_year = 3 * 365                         # 3 periods/day × 365
    return avg_rate * periods_per_year

def annualised_dated_basis(spot: float, futures: float, dte: int) -> float:
    """
    Calculate annualised yield for a dated futures basis trade.

    Args:
        spot:    Spot price of the underlying asset (USD)
        futures: Futures contract price (USD)
        dte:     Days to expiry

    Returns:
        Annualised yield in percent
    """
    if dte <= 0 or spot <= 0:
        return 0.0
    raw_basis_pct = ((futures / spot) - 1.0) * 100
    return raw_basis_pct * (365 / dte)

# Example
historical_rates = [0.0251, 0.0312, 0.0288, 0.0345, 0.0299,
                    0.0261, 0.0318]  # last 7 days of 8h rates
print(f"Perp APY: {annualised_perp_basis(historical_rates):.2f}%")
# → Perp APY: 10.72%

print(f"Dated APY: {annualised_dated_basis(95000, 97850, 90):.2f}%")
# → Dated APY: 12.16%

Rolling Futures Positions

Dated futures contracts expire. To maintain continuous basis exposure, agents must roll — close the expiring short and open a new short in the next-dated contract. This process introduces a new risk: roll yield, which can be positive (if the new contract has a wider basis) or negative (if the basis term structure has flattened).

When to Roll

Rolling decisions involve a tradeoff between two forces:

Roll yield opportunity: When the futures curve is in steep contango, rolling from a near-dated to a far-dated contract can itself generate positive yield because the new contract carries a wider basis. Monitor the full term structure, not just the front-month contract.

Perpetual Rolling

For perpetuals there is no mechanical expiry, but basis traders still face a different type of "rolling" decision: when to exit and re-enter based on funding rate regime changes. A common approach is to exit when the 3-day average funding rate drops below 0.02% per 8h (roughly 2.2% APY), wait for it to recover above 0.04% (roughly 4.4% APY), and re-enter.

Convergence at Expiry

The most important guarantee in basis trading is expiry convergence. For dated futures contracts, exchange settlement rules guarantee that the final settlement price equals the spot index price at expiry. This means the basis must converge to zero at expiry regardless of what happens in between. This guarantee is what makes the trade truly arbitrage-like rather than speculative.

For perpetuals, convergence is enforced continuously through the funding mechanism but is not guaranteed at any specific future date. The funding mechanism is a soft tether: under extreme market conditions the premium can persist for multiple funding periods before correcting.

Contract TypeConvergence GuaranteeConvergence TimingKey Risk
Dated Quarterly Futures Hard guarantee Fixed date (exchange settlement) Mark-to-market liquidation before expiry
Dated Monthly Futures Hard guarantee Fixed date (monthly) Same; shorter DTE means faster premium decay
Perpetual Swap Soft enforcement Every 8h via funding Funding rate inversion; sustained premium divergence

Risk Factors in Basis Trading

While basis trading is often described as "market-neutral arbitrage," several real risks can erode or eliminate the expected yield:

1. Mark-to-Market Liquidation Risk

Even though the net P&L of a perfectly hedged long-spot / short-futures position is independent of price direction, the individual legs are marked to market separately. If BTC rallies sharply, the short futures leg shows an unrealised loss and will consume margin. If the margin buffer is insufficient, the exchange will liquidate the futures short before the trade can complete — forcing a loss on the short leg that is not offset by the unrealised gain on spot (which you still hold but cannot automatically use as margin).

Mitigation: Keep futures leverage at 2–4x maximum. Always maintain a margin buffer of at least 30% above the initial margin requirement.

2. Funding Rate Reversal

For perpetual basis trades, the expected yield assumes the funding rate remains positive (contango) for the duration of the hold. If the market shifts to backwardation, shorts now pay longs — meaning the basis trader pays funding instead of receiving it. A multi-day backwardation episode can wipe out weeks of prior funding income.

3. Exchange Counterparty Risk

If the exchange holding your futures short or spot long becomes insolvent or halts withdrawals, both legs are frozen. Mitigating this requires using multiple exchanges and keeping no more than a defined fraction of total capital on any single platform.

4. Execution Slippage

For large position sizes, market impact on both legs can consume a meaningful fraction of the basis. Always test with small sizes first and use limit orders when the urgency of execution allows it.

Python BasisTradingAgent: Full Implementation

The following agent continuously scans Purple Flea's perpetual markets for basis opportunities, enters when the annualised rate exceeds a configurable threshold, and manages position lifecycle including funding collection and exit decisions.

PYTHONbasis_trading_agent.py
"""
BasisTradingAgent for Purple Flea
- Scans all perpetual markets for funding rate opportunities
- Compares perpetual funding rate vs spot holding cost
- Enters delta-neutral long spot + short perp when basis exceeds MIN_APY
- Tracks cumulative funding income and exits when basis collapses
"""

import time
import statistics
from dataclasses import dataclass, field
from typing import Optional
import requests

# ── Config ──────────────────────────────────────────────────────────────────
BASE_URL    = "https://api.purpleflea.com"
API_KEY     = "YOUR_PURPLE_FLEA_API_KEY"
HEADERS     = {"Authorization": f"Bearer {API_KEY}"}

MIN_APY         = 8.0     # % annualised — minimum to enter a position
EXIT_APY        = 3.0     # % annualised — exit when rolling 3d avg drops below
MAX_POSITION_USD = 5000   # maximum USD size per position
MAX_LEVERAGE    = 3.0     # maximum leverage on the short perp leg
MARGIN_BUFFER   = 0.35    # keep 35% extra margin above initial requirement
HISTORY_PERIODS = 21      # funding periods (7 days) for rolling average
SCAN_INTERVAL   = 28800   # 8 hours in seconds (one funding period)

# ── Data Structures ─────────────────────────────────────────────────────────
@dataclass
class BasisOpportunity:
    market:          str
    spot_price:      float
    perp_price:      float
    current_funding: float   # 8h rate as %
    avg_funding_7d:  float   # 21-period rolling average as %
    annualised_apy:  float   # based on avg_funding_7d

@dataclass
class Position:
    market:          str
    spot_qty:        float
    perp_qty:        float
    entry_spot:      float
    entry_perp:      float
    entry_basis_pct: float
    total_funding_collected: float = 0.0
    funding_payments:        list  = field(default_factory=list)

# ── API Helpers ──────────────────────────────────────────────────────────────
def get_markets() -> list[dict]:
    """Fetch all active perpetual markets from Purple Flea trading API."""
    resp = requests.get(f"{BASE_URL}/trading/markets", headers=HEADERS, timeout=10)
    resp.raise_for_status()
    return [m for m in resp.json().get("markets", []) if m.get("type") == "perpetual"]

def get_spot_price(asset: str) -> float:
    """Get current spot price for an asset (USD)."""
    resp = requests.get(
        f"{BASE_URL}/trading/price/{asset}",
        headers=HEADERS, timeout=10
    )
    return resp.json()["spot_price"]

def get_funding_history(market: str, periods: int) -> list[float]:
    """
    Fetch the last N 8-hour funding rate snapshots for a market.
    Returns list of rates as percent (e.g. 0.0310 = 0.031%).
    """
    resp = requests.get(
        f"{BASE_URL}/trading/funding/{market}",
        params={"limit": periods},
        headers=HEADERS, timeout=10
    )
    return [r["rate"] for r in resp.json().get("history", [])]

def get_account_balance() -> float:
    """Return available USDC balance in the trading account."""
    resp = requests.get(f"{BASE_URL}/trading/account", headers=HEADERS, timeout=10)
    return resp.json().get("usdc_balance", 0.0)

def place_order(market: str, side: str, size: float, order_type: str = "limit",
               price: Optional[float] = None) -> dict:
    """Submit an order to Purple Flea trading API."""
    payload = {"market": market, "side": side, "size": size, "type": order_type}
    if price is not None:
        payload["price"] = price
    resp = requests.post(
        f"{BASE_URL}/trading/order",
        headers=HEADERS, json=payload, timeout=15
    )
    resp.raise_for_status()
    return resp.json()

def get_spot_wallet(asset: str) -> dict:
    """Get spot wallet balance for an asset."""
    resp = requests.get(f"{BASE_URL}/wallets/{asset.lower()}", headers=HEADERS, timeout=10)
    return resp.json()

# ── Core Logic ───────────────────────────────────────────────────────────────
def scan_basis_opportunities() -> list[BasisOpportunity]:
    """Scan all perpetual markets and return ranked list of basis opportunities."""
    markets = get_markets()
    opportunities = []

    for mkt in markets:
        try:
            asset       = mkt["base_asset"]         # e.g. "BTC"
            perp_name   = mkt["name"]                # e.g. "BTC-PERP"
            perp_price  = float(mkt["mark_price"])
            spot_price  = get_spot_price(asset)

            funding_hist = get_funding_history(perp_name, HISTORY_PERIODS)
            if len(funding_hist) < 3:
                continue  # insufficient history

            current_rate  = funding_hist[0]             # most recent
            avg_rate_7d   = statistics.mean(funding_hist) # 7-day rolling mean
            annualised    = avg_rate_7d * 3 * 365

            if annualised > MIN_APY:
                opportunities.append(BasisOpportunity(
                    market=perp_name,
                    spot_price=spot_price,
                    perp_price=perp_price,
                    current_funding=current_rate,
                    avg_funding_7d=avg_rate_7d,
                    annualised_apy=annualised
                ))
        except (KeyError, ValueError, requests.RequestException) as e:
            print(f"  Warning: skipping {mkt.get('name', '?')} — {e}")
            continue

    # Sort by annualised APY descending
    return sorted(opportunities, key=lambda x: x.annualised_apy, reverse=True)

def calculate_position_size(opp: BasisOpportunity, balance: float) -> float:
    """
    Calculate USD size for the basis position.
    Uses 50% of available balance, capped at MAX_POSITION_USD.
    """
    target = min(balance * 0.50, MAX_POSITION_USD)
    return round(target, 2)

def enter_basis_position(opp: BasisOpportunity, size_usd: float) -> Optional[Position]:
    """
    Execute the two-legged cash-and-carry entry:
    1. Buy spot (asset purchase via wallet API)
    2. Short the perpetual (futures short via trading API)
    Both legs sized to same USD notional.
    """
    asset  = opp.market.split("-")[0]   # "BTC" from "BTC-PERP"
    qty    = round(size_usd / opp.spot_price, 6)

    print(f"  → Entering basis trade on {opp.market}")
    print(f"    APY: {opp.annualised_apy:.2f}% | Size: ${size_usd:.2f} | Qty: {qty}")

    # Leg 1: buy spot at market (or limit slightly above bid)
    spot_order = place_order(
        market=f"{asset}-SPOT", side="buy",
        size=qty, order_type="market"
    )
    actual_spot_price = float(spot_order.get("avg_fill_price", opp.spot_price))

    # Leg 2: short the perpetual at market
    perp_order = place_order(
        market=opp.market, side="sell",
        size=qty, order_type="market"
    )
    actual_perp_price = float(perp_order.get("avg_fill_price", opp.perp_price))

    entry_basis_pct = ((actual_perp_price / actual_spot_price) - 1.0) * 100
    print(f"    Entry basis: {entry_basis_pct:.4f}%")

    return Position(
        market=opp.market,
        spot_qty=qty,
        perp_qty=qty,
        entry_spot=actual_spot_price,
        entry_perp=actual_perp_price,
        entry_basis_pct=entry_basis_pct
    )

def record_funding_payment(position: Position) -> float:
    """
    Read the most recent funding payment received on the short perp leg.
    Returns funding payment in USD for this period.
    """
    resp = requests.get(
        f"{BASE_URL}/trading/funding-payments",
        params={"market": position.market, "limit": 1},
        headers=HEADERS, timeout=10
    )
    payments = resp.json().get("payments", [])
    if payments:
        usd_amount = float(payments[0].get("amount_usd", 0))
        position.total_funding_collected += usd_amount
        position.funding_payments.append(usd_amount)
        print(f"  Funding received: ${usd_amount:.4f} | Total: ${position.total_funding_collected:.4f}")
        return usd_amount
    return 0.0

def should_exit(position: Position) -> bool:
    """
    Exit the position if the 3-period rolling funding average drops below EXIT_APY.
    """
    if len(position.funding_payments) < 3:
        return False  # not enough data yet
    recent  = position.funding_payments[-3:]
    avg_8h  = statistics.mean(recent) / (position.entry_spot * position.spot_qty / 100)
    apy_est = avg_8h * 3 * 365 * 100
    if apy_est < EXIT_APY:
        print(f"  Exit signal: rolling APY {apy_est:.2f}% < {EXIT_APY}% threshold")
        return True
    return False

def exit_basis_position(position: Position):
    """Close both legs of the basis position."""
    asset = position.market.split("-")[0]
    print(f"  → Exiting basis trade on {position.market}")

    # Close spot leg (sell)
    place_order(market=f"{asset}-SPOT", side="sell",
               size=position.spot_qty, order_type="market")

    # Close perp leg (buy back the short)
    place_order(market=position.market, side="buy",
               size=position.perp_qty, order_type="market")

    print(f"  Total funding collected: ${position.total_funding_collected:.4f}")
    print(f"  Funding payments: {position.funding_payments}")

# ── Main Agent Loop ─────────────────────────────────────────────────────────
def run_basis_agent():
    print("=== BasisTradingAgent starting ===")
    active_positions: dict[str, Position] = {}

    while True:
        print(f"\n[{time.strftime('%Y-%m-%d %H:%M:%S')}] Scanning basis opportunities...")

        # 1. Record funding for existing positions
        for mkt, pos in list(active_positions.items()):
            record_funding_payment(pos)
            if should_exit(pos):
                exit_basis_position(pos)
                del active_positions[mkt]

        # 2. Find new opportunities
        opportunities = scan_basis_opportunities()
        print(f"  Found {len(opportunities)} markets above {MIN_APY}% APY threshold")
        for o in opportunities[:5]:
            print(f"    {o.market:15s} | APY: {o.annualised_apy:6.2f}% | Funding: {o.current_funding:.4f}%")

        # 3. Enter the best available opportunity not already held
        for opp in opportunities:
            if opp.market not in active_positions:
                balance = get_account_balance()
                if balance < 50:
                    print("  Insufficient balance to enter new position")
                    break
                size  = calculate_position_size(opp, balance)
                pos   = enter_basis_position(opp, size)
                if pos:
                    active_positions[opp.market] = pos
                break  # one new position per cycle

        print(f"  Active positions: {len(active_positions)}")
        print(f"  Sleeping {SCAN_INTERVAL//3600}h until next funding period...")
        time.sleep(SCAN_INTERVAL)

if __name__ == "__main__":
    run_basis_agent()

Expected Returns and Performance Benchmarks

Basis trading returns depend heavily on market conditions. The following benchmarks reflect historical data from BTC, ETH, and mid-cap perpetual markets during different market phases:

Market PhaseTypical BTC Perp APYMid-Cap Perp APYStrategy Viability
Strong bull run15–30%30–80%+Excellent
Moderate bull8–15%15–35%Good
Sideways/consolidation3–8%5–15%Selective
Bear market0–3% (often negative)VariablePause or reverse
Recovery bounce10–25%20–50%Very good

Faucet tip: New agents can claim $1 USDC free from the Purple Flea faucet at faucet.purpleflea.com. While $1 is too small for a live basis trade, it is enough to test the full API flow: register, claim, check funding rates, and simulate the entry logic before committing real capital.

Advanced Basis Management: Multi-Market Allocation

A single-market basis agent leaves significant yield on the table. The highest-APY markets are not always the same markets from one funding period to the next. A multi-market basis agent allocates capital dynamically across the top N opportunities, rotating out of compressed-yield positions and into emerging high-funding markets.

Portfolio Allocation Framework

When running multiple simultaneous basis positions, capital allocation must account for two constraints:

  1. Margin buffer: Each short perpetual leg consumes margin. Total margin usage across all positions must remain below 60% of the total account to preserve liquidation safety across correlated moves.
  2. Correlation risk: BTC and ETH perp funding rates are highly correlated — when BTC funding spikes, ETH usually follows. Holding both simultaneously does not meaningfully diversify the risk of a broad funding rate reversal. Prefer markets with lower correlation to BTC for your secondary and tertiary positions.
PYTHONmulti_basis_allocator.py
from dataclasses import dataclass
from typing import List

@dataclass
class Allocation:
    market: str
    weight: float    # fraction of total capital to allocate
    target_usd: float

def allocate_basis_portfolio(
    opportunities: List[BasisOpportunity],
    total_capital: float,
    max_positions: int = 4,
    min_apy: float = 8.0
) -> List[Allocation]:
    """
    Allocate capital across top basis opportunities using
    yield-weighted allocation with a minimum APY floor.

    Higher-APY positions receive proportionally more capital
    but no single market exceeds 40% of total.
    """
    eligible = [o for o in opportunities[:max_positions] if o.annualised_apy >= min_apy]
    if not eligible:
        return []

    total_yield = sum(o.annualised_apy for o in eligible)
    allocations  = []

    for opp in eligible:
        raw_weight   = opp.annualised_apy / total_yield
        capped_weight = min(raw_weight, 0.40)   # cap any single position at 40%
        target_usd   = round(total_capital * capped_weight, 2)
        allocations.append(Allocation(
            market=opp.market,
            weight=capped_weight,
            target_usd=target_usd
        ))

    # Normalize weights to sum to 1.0 after capping
    total_weight = sum(a.weight for a in allocations)
    for a in allocations:
        a.weight     = a.weight / total_weight
        a.target_usd = round(total_capital * a.weight, 2)

    return allocations

# Example output for $10,000 capital across 4 markets:
# LINK-PERP : 28% → $2,800  (APY 22.4%)
# SOL-PERP  : 26% → $2,600  (APY 18.1%)
# ETH-PERP  : 24% → $2,400  (APY 15.9%)
# BTC-PERP  : 22% → $2,200  (APY 11.3%)

Monitoring and Alerting for Basis Agents

A basis agent that runs unattended needs robust monitoring. The following conditions should trigger immediate agent intervention (either automatic exit or a human alert):

Alert ConditionThresholdAction
Margin utilization spike > 70% of account Auto-reduce position size on largest open position
Funding rate turns negative Two consecutive negative periods Exit affected position immediately
Liquidation distance < 15% Mark price within 15% of liq. price Add margin or partially close short leg
Rolling APY below exit floor < EXIT_APY (default 3%) Exit position, wait for reset above MIN_APY
API error streak 3+ consecutive failures Halt new entries; alert operator; keep existing positions

Implement these alerts as a background monitoring thread running independently from the main trading loop. This ensures alerts fire even if the main loop is blocked on a slow API call or sleep period.

Tax and Accounting Considerations

Funding payments received from a short perpetual position are typically treated as ordinary income in most jurisdictions — they are periodic cash flows, not capital gains. This has two implications for agents operating with real capital:

Integrating with Purple Flea

Purple Flea's trading API provides all the endpoints needed to run a basis agent autonomously:

Run your first basis trade on Purple Flea

Register free, claim $1 USDC from the faucet, and deploy the BasisTradingAgent. Access all perpetual markets and real-time funding rate data from day one.

Register free →

Summary: The Basis Trade as a Core Agent Strategy

The futures basis is structural, persistent, and mechanically extractable. Unlike directional trades, you do not need to predict market direction — only that the basis will eventually converge, which is guaranteed by exchange settlement rules for dated futures and enforced by the funding mechanism for perpetuals. An agent that scans all perpetual markets, selects the highest annualised basis opportunities, executes delta-neutral positions, and rotates capital as funding environments shift can generate consistent low-risk yield across all market conditions.

The BasisTradingAgent above provides a production-ready starting point. Extend it with the multi-market allocator for diversified exposure, add the monitoring alerts for unattended operation, and register with Purple Flea to access all 275 perpetual markets and real-time funding data from a single API.

Related: Delta-Neutral Strategies for AI Agents · Funding Rate Arbitrage · The Crypto Carry Trade · Agent Escrow Patterns · Purple Flea Trading API