Back to Blog
Free Market Data APIs for Trading Strategies
Data18 min read

Free Market Data APIs for Trading Strategies

A strategy can only be as good as what it sees. Price alone is the thinnest slice of the market. Funding rates, open interest, order book depth, sentiment, news and prediction-market odds all tell you something price hasn't shown yet.

Most of that data is free. Exchanges publish their market data on public endpoints, and a handful of data providers do the same for sentiment, on-chain activity and news. None of the URLs below needs an account or an API key, unless we say so.

Every keyless GET URL in this post was called from the Sigrex strategy runtime itself between October 23 and 25, 2026, and returned data. So you can paste them into an LLM Session prompt or a Code Strategy and expect an answer. Public APIs do change, though, so if one stops responding, check the exchange's API docs for the current path.

Three ways to bring data into a strategy

Two limits to plan around: {{get:}} URLs must be HTTPS, and both {{get:}} and $.Http give a request 1,750 ms to answer. In code, identical GET requests are cached for 5 seconds. And {{get:}} is the cheapest of the three, because the data is already in the prompt when the model starts and costs no extra model call (changelog).

A minimal prompt looks like this:

Current BTC funding on Binance:
{{toon: {{get:https://fapi.binance.com/fapi/v1/premiumIndex?symbol=BTCUSDT}} }}

And the same request in a Code Strategy:

const res = await $.Http.get("https://fapi.binance.com/fapi/v1/premiumIndex", { symbol: "BTCUSDT" });
if (res.status === 200) {
  const funding = Number(JSON.parse(res.text).lastFundingRate);
}

Exchange market data

Every major exchange publishes prices, candles and order books for free. Use the exchange you trade on: the data then matches the market your bot actually fills on.

The same URLs, ready to copy:

# Binance
https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT
https://api.binance.com/api/v3/ticker/24hr?symbols=["BTCUSDT","ETHUSDT"]&type=MINI
https://api.binance.com/api/v3/ticker?symbols=["BTCUSDT","ETHUSDT"]&windowSize=4h&type=MINI
https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1h&limit=24
https://api.binance.com/api/v3/depth?symbol=BTCUSDT&limit=5
https://fapi.binance.com/fapi/v1/klines?symbol=BTCUSDT&interval=4h&limit=24
https://data-api.binance.vision/api/v3/ticker/price?symbol=BTCUSDT

# Bybit
https://api.bybit.com/v5/market/tickers?category=linear&symbol=BTCUSDT
https://api.bybit.com/v5/market/kline?category=linear&symbol=BTCUSDT&interval=60&limit=24
https://api.bybit.com/v5/market/orderbook?category=spot&symbol=BTCUSDT&limit=5

# OKX
https://www.okx.com/api/v5/market/ticker?instId=BTC-USDT
https://www.okx.com/api/v5/market/candles?instId=BTC-USDT&bar=1H&limit=24

# Bitget
https://api.bitget.com/api/v2/spot/market/tickers?symbol=BTCUSDT
https://api.bitget.com/api/v2/spot/market/candles?symbol=BTCUSDT&granularity=1h&limit=24

# Gate.io
https://api.gateio.ws/api/v4/spot/tickers?currency_pair=BTC_USDT
https://api.gateio.ws/api/v4/spot/candlesticks?currency_pair=BTC_USDT&interval=1h&limit=24
https://api.gateio.ws/api/v4/futures/usdt/tickers?contract=BTC_USDT

# MEXC
https://api.mexc.com/api/v3/ticker/price?symbol=BTCUSDT
https://api.mexc.com/api/v3/klines?symbol=BTCUSDT&interval=60m&limit=24

# Kraken, KuCoin, Coinbase
https://api.kraken.com/0/public/Ticker?pair=XBTUSD
https://api.kucoin.com/api/v1/market/stats?symbol=BTC-USDT
https://api.exchange.coinbase.com/products/BTC-USD/ticker
https://api.exchange.coinbase.com/products/BTC-USD/stats

# Deribit
https://www.deribit.com/api/v2/public/ticker?instrument_name=BTC-PERPETUAL
https://www.deribit.com/api/v2/public/get_index_price?index_name=btc_usd

# HTX, Bitfinex, Bitstamp
https://api.huobi.pro/market/detail/merged?symbol=btcusdt
https://api-pub.bitfinex.com/v2/ticker/tBTCUSD
https://www.bitstamp.net/api/v2/ticker/btcusd/

Hyperliquid's market data works differently: one URL, https://api.hyperliquid.xyz/info, takes POST requests with a JSON body. That needs a Code Strategy, so it has its own example further down.

In a Code Strategy you also get $.getExchangeRate(), which returns the current price from Sigrex's own live feed for Binance, Bitget, Gate.io, Hyperliquid and Kraken without any HTTP call:

const price = await $.getExchangeRate($.Exchange.BINANCE, "btcusdt");

Candle formats differ from exchange to exchange

Ask six exchanges for the same hour of BTC and you get six different shapes back. The column order, the sort order, the name of the interval and even the unit of time change from one exchange to the next.

Two habits prevent most mistakes.

Tell the model what the columns are. Given an unlabeled array, a model can read the close as the high. Name the order of the rows and the columns right above the data:

Last 24 Gate.io candles, 1h, oldest first.
Each row: time (seconds), quote volume, close, high, low, open, base volume, closed.
{{toon: {{get:https://api.gateio.ws/api/v4/spot/candlesticks?currency_pair=BTC_USDT&interval=1h&limit=24}} }}

Put newest-first lists in order before you use them. Bybit and OKX return the newest candle first. Reverse the list so index 0 is always the oldest candle, the same as on Binance:

const res = await $.Http.get("https://api.bybit.com/v5/market/kline?category=linear&symbol=BTCUSDT&interval=60&limit=24");
if (res.status !== 200) return;

const candles = JSON.parse(res.text).result.list
  .reverse()
  .map(c => ({ time: Number(c[0]), open: Number(c[1]), high: Number(c[2]), low: Number(c[3]), close: Number(c[4]) }));

The last candle in a list is usually still open. If a rule should only look at closed candles, drop the last one, or check the flag where the exchange gives one: OKX's last column is 1 for a closed candle and Gate.io's is true.

Derivatives positioning: funding, open interest and long/short ratios

Price tells you where the market is. Positioning tells you who is leaning which way, and how hard. For perpetual futures, four free numbers cover most of it:

  • Funding rate: the payment between longs and shorts that keeps the perpetual close to spot. Positive means longs pay shorts, so longs are the crowded side. Negative means shorts pay longs.
  • Open interest: the total size of open positions. Rising open interest means new positions are opening; falling means positions are closing.
  • Long/short ratios: how many accounts, or how much of the top traders' size, is long versus short.
  • Taker flow and liquidations: who is hitting the market right now, and who was forced out.

The same URLs, ready to copy:

# Current funding rate
https://fapi.binance.com/fapi/v1/premiumIndex?symbol=BTCUSDT
https://api.bybit.com/v5/market/tickers?category=linear&symbol=BTCUSDT
https://www.okx.com/api/v5/public/funding-rate?instId=BTC-USDT-SWAP
https://api.bitget.com/api/v2/mix/market/current-fund-rate?symbol=BTCUSDT&productType=USDT-FUTURES
https://api.gateio.ws/api/v4/futures/usdt/tickers?contract=BTC_USDT
https://contract.mexc.com/api/v1/contract/funding_rate/BTC_USDT
https://api-futures.kucoin.com/api/v1/funding-rate/XBTUSDTM/current
https://www.deribit.com/api/v2/public/ticker?instrument_name=BTC-PERPETUAL

# Funding history
https://fapi.binance.com/fapi/v1/fundingRate?symbol=BTCUSDT&limit=3
https://api.bybit.com/v5/market/funding/history?category=linear&symbol=BTCUSDT&limit=3

# Open interest
https://fapi.binance.com/fapi/v1/openInterest?symbol=BTCUSDT
https://fapi.binance.com/futures/data/openInterestHist?symbol=BTCUSDT&period=1h&limit=6
https://api.bybit.com/v5/market/open-interest?category=linear&symbol=BTCUSDT&intervalTime=1h&limit=6
https://www.okx.com/api/v5/public/open-interest?instType=SWAP&instId=BTC-USDT-SWAP
https://api.bitget.com/api/v2/mix/market/open-interest?symbol=BTCUSDT&productType=USDT-FUTURES

# Long/short ratios and taker flow
https://fapi.binance.com/futures/data/globalLongShortAccountRatio?symbol=BTCUSDT&period=1h&limit=3
https://fapi.binance.com/futures/data/topLongShortPositionRatio?symbol=BTCUSDT&period=1h&limit=3
https://fapi.binance.com/futures/data/takerlongshortRatio?symbol=BTCUSDT&period=1h&limit=3
https://api.bybit.com/v5/market/account-ratio?category=linear&symbol=BTCUSDT&period=1h&limit=3

# All in one: open interest, long/short, taker flow, liquidations
https://api.gateio.ws/api/v4/futures/usdt/contract_stats?contract=BTC_USDT&interval=1h&limit=1

A few things to know before you compare venues:

  • Funding is a fraction per period. 0.0001 means 0.01% per funding period. Most BTC perpetuals settle every 8 hours, but the period differs by contract and exchange, so read it from the reply: Bybit's fundingIntervalHour, Bitget's fundingRateInterval, MEXC's collectCycle (hours) and KuCoin's granularity (milliseconds). Hyperliquid settles every hour, so multiply its rate by 8 to compare it with an 8-hour rate.
  • Open interest comes in different units. Binance and Bybit report it in BTC; Gate.io reports contracts plus open_interest_usd. Compare how open interest changes on one venue, not the raw numbers across venues.
  • Long/short ratios count different things. Binance's globalLongShortAccountRatio counts accounts, topLongShortPositionRatio measures the positions of the top 20% of traders by margin balance, and takerlongshortRatio compares taker buy volume to taker sell volume. Above 1 means more long.
  • Gate.io packs it all into one call. contract_stats returns open interest, account and taker long/short ratios, top-trader ratios and long and short liquidations (long_liq_usd, short_liq_usd) for each interval.

Sentiment and market-wide data

These sources describe the whole market rather than one exchange: how fearful or greedy traders are, whether Bitcoin or altcoins are leading, and how big the market is.

The same URLs, ready to copy:

https://api.alternative.me/fng/?limit=7
https://pro-api.coinmarketcap.com/public-api/v3/fear-and-greed/latest
https://pro-api.coinmarketcap.com/public-api/v1/altcoin-season-index/latest
https://pro-api.coinmarketcap.com/public-api/v1/global-metrics/quotes/latest
https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum&vs_currencies=usd&include_24hr_change=true
https://api.coinpaprika.com/v1/global
https://coins.llama.fi/prices/current/coingecko:bitcoin
https://mempool.space/api/v1/fees/recommended
https://api.blockchair.com/bitcoin/stats
  • Ask for a week, not a day. alternative.me's Fear & Greed Index updates once a day. With limit=7 the model sees how the mood changed, which says more than today's number alone.
  • There are two Fear & Greed indexes. CoinMarketCap builds its own from different inputs, so the two don't always agree. Pick one and stick with it, or give the model both and say which is which.
  • The Altcoin Season Index runs from 0 to 100. High values mean most large altcoins beat Bitcoin over the past 90 days.
  • Keyless routes are for light use. CoinMarketCap's public-api routes and CoinGecko's keyless API are rate-limited by IP. For anything you depend on, get a free key: CoinMarketCap's Basic plan gives 15,000 call credits a month at 50 requests a minute, and CoinGecko's Demo plan gives 10,000 call credits a month at 100 requests a minute, with attribution required.

Keep keys out of your prompts. In a Code Strategy, save the key as an environment variable and read it with $.Env, so it never appears in the code you share:

// COINGECKO_KEY is an environment variable you add in Sigrex.
const res = await $.Http.get("https://api.coingecko.com/api/v3/simple/price", {
  ids: "bitcoin,ethereum",
  vs_currencies: "usd",
  include_24hr_change: "true",
  x_cg_demo_api_key: $.Env.COINGECKO_KEY,
});

More on keys and headers in Connecting external APIs securely with HTTP.

On-chain: Bitcoin fees and network activity

Two keyless sources cover the Bitcoin network itself.

mempool.space shows how busy the network is:

  • https://mempool.space/api/v1/fees/recommended returns the fee rates in sat/vB for the next block, half an hour, an hour and the cheapest option.
  • https://mempool.space/api/v1/difficulty-adjustment shows how far the network is into the current difficulty period and the estimated change.
  • https://mempool.space/api/mempool returns the number of unconfirmed transactions and their total size and fees. It also includes a long fee histogram, so in a prompt the fee endpoint above is the cheaper choice.

Blockchair's https://api.blockchair.com/bitcoin/stats returns a broad snapshot in one call: blocks and transactions in the last 24 hours, the mempool, hashrate, average and median fees, and the largest transaction of the day.

Fees and mempool size rise when many people move coins at the same time, which often happens around sharp moves. Use them as context for the model, not as a signal on their own:

Bitcoin network right now:
Fees (sat/vB): {{get:https://mempool.space/api/v1/fees/recommended}}
Next difficulty adjustment: {{get:https://mempool.space/api/v1/difficulty-adjustment}}

News and social feeds

News is where a language model earns its place in a strategy. Code can't tell whether a headline matters; a model can read it and judge.

Google News RSS

Any Google News search works as a feed, with no key:

https://news.google.com/rss/search?q=bitcoin+when:1h&hl=en-US&gl=US&ceid=US:en

when:1h keeps the last hour; when:1d the last day. Put phrases in encoded quotes, for example q=%22bitcoin%20treasury%22. The feed is wordy: every item carries a long tracking link, so a full feed costs thousands of tokens in a prompt. In a Code Strategy, keep just the headlines:

const res = await $.Http.get("https://news.google.com/rss/search?q=bitcoin+when:1h&hl=en-US&gl=US&ceid=US:en");
if (res.status !== 200) return;

const headlines = [...res.text.matchAll(/<item><title>(.*?)<\/title>/g)]
  .map(m => m[1])
  .slice(0, 10);

From there, save the headlines to storage or post them to a Data Webhook, so an LLM Reaction only reads ten short lines. Google's feed terms allow use in a personal feed reader for personal, non-commercial use, so read them before you build on this feed.

rss.app

rss.app turns X accounts and websites that have no feed into RSS or JSON feeds on its paid plans, refreshed every 15 to 60 minutes. The free plan covers two existing RSS feeds, refreshed every 24 hours. Building an LLM strategy that monitors X (Twitter) feeds walks through a full setup.

Perigon

Perigon is a news API with search, filters and three months of history on the free plan. 150 requests a month is about five a day, enough for a daily brief or a few checks a day:

// PERIGON_KEY is an environment variable you add in Sigrex.
const res = await $.Http.get("https://api.perigon.io/v1/articles/all", {
  q: "bitcoin",
  sortBy: "date",
  size: 10,
  apiKey: $.Env.PERIGON_KEY,
});

The free plan is licensed for personal use. For a complete news-driven setup, see Building a news-to-trade workflow for Polymarket.

Prediction markets: Polymarket and Kalshi

Prediction markets put a price on events: a Fed decision, an election, BTC above a level by a date. The price of a Yes share is the crowd's probability that it happens. That makes these markets a clean macro input for a crypto strategy, and the main input for a bot that trades on Polymarket.

The same URLs, ready to copy:

# Polymarket
https://gamma-api.polymarket.com/public-search?q=fed%20rate&limit_per_type=3
https://gamma-api.polymarket.com/markets?slug=another-fed-rate-hike-in-2026
https://data-api.polymarket.com/trades?limit=10

# Kalshi
https://api.elections.kalshi.com/trade-api/v2/markets?series_ticker=KXFED&status=open&limit=5
https://api.elections.kalshi.com/trade-api/v2/markets/{ticker}/orderbook

Polymarket returns outcomes and outcomePrices as JSON text inside the JSON, in the same order, for example ["Yes", "No"] and ["0.765", "0.235"]: Yes trades at 76.5%. The reply also carries bestBid, bestAsk, lastTradePrice and volume24hr, plus the market's full rules text, which is long. In code, parse the prices a second time and keep only what you need:

const res = await $.Http.get("https://gamma-api.polymarket.com/markets", { slug: "another-fed-rate-hike-in-2026" });
if (res.status !== 200) return;

const market = JSON.parse(res.text)[0];
const outcomes = JSON.parse(market.outcomes);                    // ["Yes", "No"]
const prices = JSON.parse(market.outcomePrices).map(Number);      // [0.765, 0.235]
const yes = prices[outcomes.indexOf("Yes")];                      // 0.765 = 76.5%

Kalshi quotes prices in dollars from 0 to 1 (yes_bid_dollars, yes_ask_dollars, last_price_dollars), so 0.4400 means 44%. Each market is one strike, such as "above 5.00%" or "above 5.25%", so read several strikes of the same event together to see the whole distribution. The order book endpoint takes a market's ticker from that list, for example KXFED-27APR-T5.00.

Example 1: an LLM Session that reads positioning across exchanges

This session pulls funding, open interest, long/short ratios and liquidations from three exchanges, then asks the model one question: how crowded is the trade?

  • Session: every 1 hour, signal sending off, send email on. Any free model works; our guide to free LLM providers lists them.
  • Cost: every URL is keyless and fetched before the model runs, so each run is one model request: 24 a day.
{{val:symbol=BTCUSDT}}
You are a derivatives analyst. Judge how crowded {{symbol}} perpetual futures are right now.

Binance funding and mark price:
{{toon: {{get:https://fapi.binance.com/fapi/v1/premiumIndex?symbol={{symbol}}}} }}

Binance open interest, last 6 hours, oldest first (sumOpenInterest is in BTC):
{{toon: {{get:https://fapi.binance.com/futures/data/openInterestHist?symbol={{symbol}}&period=1h&limit=6}} }}

Binance long/short ratio by accounts, last 3 hours:
{{toon: {{get:https://fapi.binance.com/futures/data/globalLongShortAccountRatio?symbol={{symbol}}&period=1h&limit=3}} }}

Binance top traders' positions, last 3 hours:
{{toon: {{get:https://fapi.binance.com/futures/data/topLongShortPositionRatio?symbol={{symbol}}&period=1h&limit=3}} }}

Bybit ticker (fundingRate, fundingIntervalHour, openInterest, price24hPcnt):
{{toon: {{get:https://api.bybit.com/v5/market/tickers?category=linear&symbol={{symbol}}}} }}

Gate.io, last hour (lsr_account, lsr_taker, long_liq_usd, short_liq_usd):
{{toon: {{get:https://api.gateio.ws/api/v4/futures/usdt/contract_stats?contract=BTC_USDT&interval=1h&limit=1}} }}

Answer in this order, one or two lines each:
1. Funding on Binance and Bybit as a percentage per 8 hours. Who pays whom?
2. Is open interest rising or falling over the 6 hours, and how has price moved in 24 hours?
3. Are all accounts and top traders leaning the same way?
4. In the last hour on Gate.io, were more longs or more shorts liquidated?
End with one line: CROWDED LONG, CROWDED SHORT or BALANCED.

The labels above each block tell the model which fields matter, so it doesn't have to guess from 30 columns. Gate.io writes the symbol as BTC_USDT, so change that one by hand if you switch coins.

Once the verdicts look sensible, use them. Turn signals on and add a rule such as "only open a long when the verdict is not CROWDED LONG".

Example 2: a Code Strategy that compares funding on five exchanges

One exchange's funding rate can be skewed by its own users. The same reading on five exchanges at once is much harder to argue with. This Code Strategy reads BTC funding on Binance, Bybit, OKX, Bitget and Gate.io every 5 minutes, averages the ones that answer, and acts only when that average is stretched. It uses no LLM at all.

// Every 5 minutes: read the BTC perpetual funding rate on five exchanges,
// keep a short history, and act only when the average across them is stretched.
const EVERY_MS = 5 * 60 * 1000;
const S = (await $.Storage.get()) || { lastRun: 0, history: [] };
if (Date.now() - S.lastRun < EVERY_MS) return;
S.lastRun = Date.now();

// Read one number from one API. Any error or odd reply counts as "no answer".
const read = async (url, pick) => {
  try {
    const res = await $.Http.get(url);
    if (res.status !== 200) return null;
    const v = Number(pick(JSON.parse(res.text)));
    return Number.isFinite(v) ? v : null;
  } catch (err) {
    return null;
  }
};

// All five requests run in parallel, so the whole run stays well inside 5 seconds.
const rates = await Promise.all([
  read("https://fapi.binance.com/fapi/v1/premiumIndex?symbol=BTCUSDT", d => d.lastFundingRate),
  read("https://api.bybit.com/v5/market/tickers?category=linear&symbol=BTCUSDT", d => d.result.list[0].fundingRate),
  read("https://www.okx.com/api/v5/public/funding-rate?instId=BTC-USDT-SWAP", d => d.data[0].fundingRate),
  read("https://api.bitget.com/api/v2/mix/market/current-fund-rate?symbol=BTCUSDT&productType=USDT-FUTURES", d => d.data[0].fundingRate),
  read("https://api.gateio.ws/api/v4/futures/usdt/tickers?contract=BTC_USDT", d => d[0].funding_rate),
]);

const answered = rates.filter(r => r !== null);
if (answered.length < 3) { await $.Storage.set(S); return; }
const avg = answered.reduce((a, b) => a + b, 0) / answered.length;

S.history.push({ t: S.lastRun, avg });
S.history = S.history.slice(-48); // the last 4 hours of readings
await $.Storage.set(S);

// Example rules only: a contrarian take on crowded funding. Tune or replace them.
const last = $.Strategy.lastTrigger.action;
const inPosition = last === $.Action.LONG || last === $.Action.SHORT;

if (!inPosition && avg > 0.0005) {
  await $.Strategy.action($.Action.SHORT, { id: "funding-crowded-longs" });
} else if (!inPosition && avg < -0.0002) {
  await $.Strategy.action($.Action.LONG, { id: "funding-crowded-shorts" });
} else if (inPosition && Math.abs(avg) < 0.0001) {
  await $.Strategy.action($.Action.EXIT, { id: "funding-normal-again" });
}

How it works:

  • The time gate. A Code Strategy runs in a loop, so the first lines skip every run until 5 minutes have passed. More in Time gates in Code Strategies.
  • Parallel requests. Promise.all sends all five requests at once. Each gets 1,750 ms, and the whole run finishes long before the 5-second limit.
  • Failures don't count. A timeout, an error status or an odd reply becomes "no answer". With fewer than three answers the run does nothing, so one exchange having a bad minute can't trigger a trade.
  • Same units. All five exchanges settled BTC funding every 8 hours when we checked. If you switch to a coin with a shorter funding period on some venue, convert to 8 hours first.
  • The history in storage keeps 4 hours of averages. Use it to demand persistence, for example S.history.slice(-3).every(h => h.avg > 0.0005) to act only after three stretched readings in a row.

The thresholds are an example to show the shape of the code, not levels we recommend. Point the strategy at a Bot Webhook with no bot attached first and forward test it.

Example 3: reading Hyperliquid with a POST request

Hyperliquid serves all of its market data from one URL, https://api.hyperliquid.xyz/info, and you choose what you get with a JSON body. {"type": "metaAndAssetCtxs"} returns every perpetual with its mark price, oracle price, funding, open interest and 24-hour volume. $.Http.post sends the body as JSON by default.

// Once a minute: take a snapshot of BTC on Hyperliquid and keep the last hour.
const EVERY_MS = 60 * 1000;
const S = (await $.Storage.get()) || { lastRun: 0, snaps: [] };
if (Date.now() - S.lastRun < EVERY_MS) return;
S.lastRun = Date.now();

// Hyperliquid's market data API takes POST requests with a JSON body.
const res = await $.Http.post("https://api.hyperliquid.xyz/info", { type: "metaAndAssetCtxs" });
if (res.status !== 200) { await $.Storage.set(S); return; }

// The reply is [meta, contexts]: meta.universe lists the coins,
// and contexts holds the live numbers for each coin in the same order.
const [meta, contexts] = JSON.parse(res.text);
const i = meta.universe.findIndex(c => c.name === "BTC");
if (i < 0) { await $.Storage.set(S); return; }

const btc = contexts[i];
S.snaps.push({
  t: S.lastRun,
  mark: Number(btc.markPx),
  oracle: Number(btc.oraclePx),
  fundingPerHour: Number(btc.funding),   // hourly rate: multiply by 8 to compare with 8-hour venues
  openInterest: Number(btc.openInterest), // in BTC
  volume24hUsd: Number(btc.dayNtlVlm),
});
S.snaps = S.snaps.slice(-60);
await $.Storage.set(S);

// Example use: how much open interest changed over the stored hour (0.05 = +5%).
const first = S.snaps[0];
const last = S.snaps[S.snaps.length - 1];
const oiChange = (last.openInterest - first.openInterest) / first.openInterest;

Three things to know:

  • Coins are matched by position. The reply lists coin names in meta.universe and the numbers in contexts, in the same order. Find the coin's index first, then read the same index from contexts.
  • Funding is paid every hour on Hyperliquid, at one eighth of the 8-hour rate (Hyperliquid docs). Multiply it by 8 before you compare it with Binance or Bybit.
  • Storage stays small. Sixty snapshots of six numbers use a few kilobytes of the 24 KB a strategy can store.

From here, act on oiChange directly, or post the latest snapshot to a Data Webhook and let an LLM Reaction weigh it with the news.

Tips for reliable data

  • Ask for less. Use limit=24, not 500. Ask for one symbol, not the whole market, and use type=MINI on Binance tickers. Small replies arrive faster, cost fewer tokens and stay well inside 1,750 ms.
  • Shrink JSON in prompts. Wrap {{get:}} in {{toon: ... }} to turn JSON into the compact TOON format, and label each block so the model knows what it is reading.
  • Check the reply before you use it. In code, test res.status and parse inside try/catch. Skipping a run is always better than acting on an error page.
  • Numbers arrive as strings. Most exchanges send "80426.50", not 80426.5. Convert with Number() before you compare or add.
  • Watch the time units. Most exchanges use milliseconds, but Gate.io uses seconds. Date.now() is in milliseconds.
  • Have a second source. If one exchange is slow or unreachable, the same data usually exists on another. Binance also serves spot data from data-api.binance.vision. Example 2 shows the pattern: ask several, act on the ones that answer.
  • Use free keys for data you depend on. Keyless endpoints are rate-limited by IP. A free key gives you your own allowance.
  • Don't poll faster than the data changes. In code, identical GET requests are cached for 5 seconds, funding rates drift slowly, and Fear & Greed changes once a day.

Start building

Every source in this post can be used for free: the exchange data, the sentiment and on-chain feeds, the news and the prediction-market odds. Pair them with a free model from our guide to free LLM providers and an AI strategy costs nothing to run.

The Sigrex free plan includes 2 Code Strategies, 2 LLM Sessions, 2 Code Reactions and 2 LLM Reactions, free forever with no card. Create a free account and paste in the first prompt.

Related posts

Free LLM APIs for AI Trading Strategies
LLM Strategy·11 min read

Free LLM APIs for AI Trading Strategies

An AI trading strategy needs two things: data to read and a model to think with. The model is where most people expect a bill. It doesn't have to be one. LLM Sessions and LLM Reactions on Sigrex run on your own API key from one of 21 supported providers. Several of them give API access for free: some with a daily request allowance, some with monthly credit, some with no published cap at all. That is enough to build, test and run a real AI strategy without paying for a single token. This guide

2026-10-26
Building an Evolving Strategy with Checkpoints and an LLM Coach
LLM Reaction·7 min read

Building an Evolving Strategy with Checkpoints and an LLM Coach

Letting an AI edit a running strategy sounds great until you ask one question: how do you know the new version is better? In August we showed how an LLM Reaction can supervise a Code Strategy and patch it when something breaks. This post takes the same idea further. The AI may now replace the whole trading logic, and a small set of rules keeps that from turning into guesswork. We call the setup Evo. It trades BTCUSDT on paper, and it is built only from parts you already have on Sigrex: one Cod

2026-10-10
How to Forward Test a Strategy
Testing·5 min read

How to Forward Test a Strategy

Sigrex has no backtester, and that is a design consequence, not a missing feature. A strategy here can read any API and ask any LLM, and you can't replay that from history. What you can do is run the strategy on the live market with nothing attached to it, and watch. Why a backtester doesn't fit Sigrex A backtest replays the past. It feeds old data into your rules and counts what would have happened. That works when two things are true: every input the strategy uses has a recorded history, an

2026-10-02