Skip to content
Finance
Skill

/basis-arb

Use when the user asks for spot-perp basis trade, basis arbitrage, cash-and-carry, perp discount, or any setup that reads the spot–perp basis as a positioning signal. Long-perp leg only — pure two-leg basis arb requires a paired spot short (or long) which Freqtrade can't run

BOOST
From plugin
superior-skills
21630 skills
Install
$ npx -y skills add Superior-Trade/superior-skills --skill basis-arb --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/basis-arb

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when the user asks for spot-perp basis trade, basis arbitrage, cash-and-carry, perp discount, or any setup that reads the spot–perp basis as a positioning signal. Long-perp leg only — pure two-leg basis arb requires a paired spot short (or long) which Freqtrade can't run

SKILL.md

basis-arb.SKILL.md
name: basis-arb
description: Use when the user asks for spot-perp basis trade, basis arbitrage, cash-and-carry, perp discount, or any setup that reads the spot–perp basis as a positioning signal. Long-perp leg only — pure two-leg basis arb requires a paired spot short (or long) which Freqtrade can't run cleanly. The strategy below captures the directional read, not the hedged carry.
metadata:
  version: 0.1.0
  updated: 2026-05-08

Strategy: Basis Flipping — Directional (Long-Perp Leg)

Honest framing — read this first

**True basis arbitrage** is a two-leg trade:

  • Long perp + short spot (when perp trades at a discount to spot, basis < 0)
  • Short perp + long spot (when perp trades at a premium, basis > 0)

You earn the basis as the legs converge. **Freqtrade is a single-leg engine** — it can't run paired hedged trades on the same ticker. The strategy below captures the **directional signal** that "basis flipping negative + funding negative = bullish positioning shift" and goes long the perp accordingly. It's a momentum read on positioning, not a hedged arb.

If you want the actual hedged version, run an external system (or a custom Hyperliquid-only multi-leg runtime). Don't deploy this template thinking it's market-neutral.

Backtest reference

| Window | `BTC/USDC:USDC` 1h, 2026-01-01 → 2026-05-01 | |---|---| | Trades | **0** (no spot leg available in the engine) | | Backtest ID | `01kr42hegps9w20njsty2cqb41` |

The Superior Trade backtest engine doesn't currently expose Hyperliquid spot OHLCV alongside perp pairs via Freqtrade's `informative_pairs` mechanism, so the `spot_close` column is never populated and the entry filter never fires. The strategy code is structurally sound — it runs cleanly to completion with 0 trades — but **this template can't be validated end-to-end on the current backtest engine**. Two paths:

1. **Validate live, paper-traded** — run as a dry-run deployment for a week and compare the entries against an external basis tracker (CoinGlass `basisHistory` or a simple notebook). 2. **Substitute external basis feed** — replace the `informative_pairs` spot fetch with a CoinGlass `/api/futures/basis/history` call from a side-channel cache. Out of scope for this template; would be a Phase 2 backend change.

The strategy is shipped as a **directional blueprint**, not a live-validated runtime. Treat it as a teachable template for how to wire spot-perp basis into a Freqtrade strategy, rather than an off-the-shelf deployment.

When to use

A user asks for:

  • "Basis trade", "basis arb", "perp discount", "cash and carry"
  • A directional follow-on to spot-side accumulation ("spot is buying, perp is short, going long the perp")
  • Anything where the basis flipping negative is the trigger

This template **assumes Hyperliquid has both the spot and perp pair** for the asset (BTC, ETH, SOL — the few HL has spot books for). For perp-only assets, this strategy can't compute basis and won't fire.

The Freqtrade primitive that makes this work

Two `dp.get_pair_dataframe` calls: 1. The current perp's funding rate (same pattern as `strategy-funding-rate-arbitrage`) 2. The corresponding **spot** pair's OHLCV via `informative_pairs()` so we can compute basis

Basis = `(perp_mark - spot_mid) / spot_mid`. Annualised by funding period.

Reference implementation

from freqtrade.strategy import IStrategy, informative
from datetime import datetime
import pandas as pd
import talib.abstract as ta


def perp_to_spot(pair: str) -> str:
    """`BTC/USDC:USDC` → `BTC/USDC`. HL spot lives at the un-suffixed pair."""
    return pair.split(":")[0] if ":" in pair else pair


class BasisFlippingStrategy(IStrategy):
    minimal_roi = {"0": 100.0}
    stoploss = -0.04
    trailing_stop = False
    timeframe = "1h"
    process_only_new_candles = True
    startup_candle_count = 30
    can_short = False

    def informative_pairs(self):
        # Tell Freqtrade we need spot-side OHLCV for every perp in the
        # whitelist. The base pair list is set by the user; we mirror
        # each entry to its spot equivalent.
        pairs = self.dp.current_whitelist()
        return [(perp_to_spot(p), self.timeframe) for p in pairs if ":" in p]

    def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        perp_pair = metadata["pair"]
        spot_pair = perp_to_spot(perp_pair)

        # Funding rate via the dedicated candle type.
        try:
            funding = self.dp.get_pair_dataframe(
                pair=perp_pair,
                timeframe="1h",
                candle_type="funding_rate",
            )
        except Exception:
            funding = pd.DataFrame()
        if not funding.empty and "open" in funding.columns:
            f = funding[["date", "open"]].rename(columns={"open": "funding_rate"}).copy()
            dataframe = dataframe.merge(f, on="date", how="left")
            dataframe["funding_rate"] = dataframe["funding_rate"].ffill().fillna(0.0)
            dataframe["funding_apr"] = dataframe["funding_rate"] * 24 * 365
        else:
            dataframe["funding_rate"] = 0.0
            dataframe["funding_apr"] = 0.0

        # Spot OHLCV — declared via `informative_pairs`.
        try:
            spot = self.dp.get_pair_dataframe(pair=spot_pair, timeframe=self.timeframe)
        except Exception:
            spot = pd.DataFrame()
        # Initialise required columns up front so the entry guard can
        # read them even when the spot leg isn't available on this
        # dataset. Hyperliquid's backtest cache doesn't always expose
        # the matching spot pair via informative_pairs — without these
        # default columns the strategy crashes with KeyError on the
        # first candle.
        dataframe["spot_close"] = float("nan")
        dataframe["basis"] = 0.0
        dataframe["basis_apr"] = 0.0
        if not spot.empty and "close" in spot.columns:
            s = spot[["date", "close"]].rename(columns=
Read more
Ships withsuperior-skills

Trading strategies and intelligence tools for Superior Trade — natural-language strategy authoring, backtesting, and autonomous deployment on Hyperliquid, Lighter, and Polymarket.

Get the whole plugin
Stats
216
Stars
9
Forks
Maintained
Maintenance
JavaScript
Language
MIT
License
1mo ago
Last commit
7mo ago
Created
20m ago
Added

Repo: Superior-Trade/superior-skills

Other skills on superior-skills.