DEV Community

AlgoVault.com
AlgoVault.com

Posted on

Funding and volatility as scan lenses for AI trading agents

Intro

Parts one and two of this series covered structural size and market activity — open interest with the liquidity floor beneath it, then volume, gainers, losers, and movers. Those lenses answer how big and how busy. This post covers the harder ones: the lenses that select on posture and turbulence. funding_positive, funding_negative, volatility, and oi_change are the closest thing in the scan surface to what a systematic trader would otherwise wire up by hand — and the ones a generic screener will not give you.

The composite verdict behind every AlgoVault call currently sits at 91.6% PFE win rate · 535,642+ verified calls · Merkle-anchored on Base L2. That number does not change with which lens you scanned on; the lens only decides what universe reached the verdict. Get the lens right and the verdict speaks to the slice of market you actually wanted an opinion on. Get it wrong and you have asked the composite engine a well-formed question about the wrong pool of coins.

cover

This is the most technical post in the series. If parts one and two framed lenses as filters, this one insists on precision — because funding and volatility are the two lenses most likely to be misread by a reader who thinks selecting by them is itself a strategy.

Selecting on posture instead of size

Size lenses ask which markets are structurally deep enough to trade. Activity lenses ask which are moving today. Posture lenses ask something else again: what is the balance of pressure inside the market right now, and how turbulent is its recent path? Two coins can have identical open interest and identical volume and still be in entirely different postures — one where longs are paying shorts a rich premium to stay in, one where the tape has been quiet for hours and is coiling into an ATR-thin range.

For an AI trading agent, the payoff of a posture lens is that it selects for conditions the agent has an opinion about. If your prompt logic reads "when funding is stretched, check whether the composite still agrees with the crowd", you do not want to scan the full universe and then filter locally. You want the scan itself to return only the coins where that condition is true, and to hand each of those to the verdict engine. The scan lens is the where; the composite verdict is the what.

The four lenses in scope here — funding_positive, funding_negative, volatility, and oi_change — are the ones that make that composition natural. They also happen to be the ones with the most subtle failure modes.

Funding as a lens — who is paying, and what that does and does not tell you

Perpetual futures do not expire. To keep their price tethered to spot, exchanges charge a funding rate that flows between longs and shorts on a fixed cadence. When funding is positive, longs pay shorts; when negative, shorts pay longs. The magnitude of the rate reflects how badly one side wants exposure — how much they are willing to pay the other side to hold it for them.

funding_positive selects coins where longs are currently paying. funding_negative selects coins where shorts are paying. Interpreted honestly, that is all the lens tells you: which side is currently subsidising the other, and by how much. It is a snapshot of crowding, not a forecast. A crowd can stay crowded for days, then unwind in an hour, then re-form the other way. Nothing in a funding print says which of those three regimes you are in.

This is the paragraph most posts on this topic get wrong. Persistent positive funding is often described as a bearish contrarian signal, and persistent negative funding as a bullish one. That framing exists because reversion happens often enough for narratives to attach to it — but we have published no result claiming a predictive edge from funding alone, and this post will not either. The lens tells the agent where the crowd is leaning. What to do with that fact remains the composite verdict's job.

Implementation walkthrough — funding, volatility, oi_change, and the window parameter

Each lens is a parameter on the scan tool. The pattern is the same: pick the lens, pick the timeframe, pick the size of the returned universe, and — for oi_change — pick the comparison window. The MCP tool exposes each of these as an enumerated argument; the agent does not build a query, it selects a shape.

npm install @modelcontextprotocol/sdk@^1.x
# scan the top ten coins by positive funding on the 15m timeframe
npx @algovault/mcp scan \
  --lens funding_positive \
  --timeframe 15m \
  --limit 10
Enter fullscreen mode Exit fullscreen mode

The response for a single coin is the same shape you get from get_trade_signal directly — a verdict, a conviction number, and the factor ledger behind it. That is deliberate: the scan lens changes the selection, never the verdict schema. Here is a live single-coin response, unmodified:

api-response

{
  "call": "HOLD",
  "confidence": 24,
  "price": 78334.4,
  "indicators": {
    "funding_rate": 0.00007326,
    "funding_24h_avg": 0.00007326,
    "funding_state": "NORMAL",
    "oi_change_pct": 2.71,
    "oi_change_window": "24h",
    "volume_24h": 9714126268.66,
    "trend_persistence": "MEDIUM",
    "breakout_pending": "INACTIVE"
  },
  "regime": "TRENDING_UP",
  "reasoning": "2 internal factors not shown here net bearish, and they carry this read. Against: price is up over 24h, the momentum term behind the call → bullish. Turns directional if funding moves off neutral.",
  "timeframe": "15m"
}
Enter fullscreen mode Exit fullscreen mode

Two indicator fields are relevant to this post: funding_state (the categorical read the composite uses, derived from funding_rate after interval normalisation — more on that below), and oi_change_pct with its companion oi_change_window. The window field is not decorative. A 2.71 OI change over the longer window is a very different market signal than the same magnitude change over a much shorter window, and the lens honours whichever window the agent requested.

Wiring the scan into an agent loop is the shortest example of the three:

agent-loop

# AlgoVault MCP example — coins=BTC confidence_threshold=70

[BTC] {
  "call": "HOLD",
  "confidence": 8,
  "price": 78334.5,
  "indicators": {
    "funding_rate": 0.00007326,
    "funding_24h_avg": 0.00007326,
    "funding_state": "NORMAL",
    "oi_change_pct": 2.71,
    "oi_change_window": "24h",
    "vo…

# DRYRUN_MODE=1 — example complete
Enter fullscreen mode Exit fullscreen mode

The agent picks a lens (funding_negative, say), a timeframe (1h), and a threshold on the composite conviction it will act on (>= 70). The scan returns a filtered universe; the loop calls get_trade_signal for each; the threshold filter drops the rest. Nothing in that loop invents a signal — it only chooses where to point the composite.

Interval correctness: why a naive annualisation is wrong

Here is the credibility point for anyone who has ever tried to build this themselves.

Funding rates are quoted per interval, not per day and not per year. Binance charges most contracts on a multi-hour cadence. Some venues use shorter cadences. Some contracts on the same venue have different cadences from their neighbours. If you pull the raw funding_rate field for a mixed set of coins from a mixed set of venues and average them — or worse, annualise them by multiplying by a single scalar — you have produced a number that means nothing.

The correct move is to normalise every rate to a common interval before you compare, aggregate, or annualise. If a contract funds on a longer cadence at a given per-interval rate, its annualised figure is the per-interval rate times the number of intervals per day times the days in a year. If a neighbouring contract funds twice as often at the same per-interval rate, its annualised figure is double that. Publishing one APR that treats those two the same way is the mistake, and it is a common one — spreadsheet aggregators of funding rates make it constantly, and dashboards that quote "average perp funding APR across the market" without disclosing their normalisation are almost always wrong.

The scan lens does the normalisation before it ranks. funding_state — the categorical read the composite consumes — is derived from an interval-corrected value, not from raw per-interval prints. That is why funding_positive and funding_negative return the universes they do rather than surface-level ranked lists of whichever contracts happen to have the largest raw number attached.

We do not publish a general APR claim in this post because the correctness of any such number depends on the exact set of contracts and their exact intervals at the moment of the query. What we do publish is the guarantee that the lens is interval-aware, and that the sort order it returns reflects normalised pressure rather than cadence artefacts.

Volatility and open-interest change — two lenses, two window choices

volatility is ATR-based, computed on the scan timeframe. The same lens at a short intraday timeframe and at a daily timeframe returns different universes — sometimes drastically different — because a coin that has been chopping through a short-window range for hours can look completely calm on a daily. This timeframe dependence is not a bug, and it is not something the agent needs to hide. It is the point. Selecting on volatility is a scale-dependent question, and the lens forces you to be honest about which scale you meant.

oi_change is the real change in aggregated open interest across covered venues, comparing the current value against the value one oiChangeWindow ago. The window is enumerable — you pick 1h, 4h, 24h, and so on — and the response echoes the chosen window back in oi_change_window so the agent's reasoning trace has the context it needs.

Two design choices in oi_change are worth calling out because they are refusals rather than features. First, for venues that only report aggregate OI without the granularity needed for a reliable delta, the lens skips them rather than substituting volume as a proxy. Volume-as-OI-proxy is a shortcut some data providers take, and it silently corrupts any downstream analysis that assumes an OI delta means capital has entered or left. We prefer the lens to return a smaller-but-honest universe over a larger-but-mixed one. Second, the delta is signed and the lens ranks by magnitude of change, not by direction — the direction is available as a field, so the agent can decide whether inflow or outflow is what it cares about.

Pitfalls — timeframe dependence, proxy-venue skipping, and the strategy boundary

Three honest gotchas.

Timeframe changes the universe. Every posture lens is timeframe-parameterised, and the universes at different timeframes overlap less than newcomers expect. An agent that scans volatility at 1m looking for entries and then re-scans at 1h for confirmation is doing two entirely different queries, not one refinement of another. Either scale can be the right one — but they answer different questions, and treating the smaller-timeframe universe as a "high-resolution" version of the larger is a category error.

Proxy venues get skipped by oi_change. If the returned universe from an OI-change scan is smaller than you expected, that is why. The alternative — silently mixing venues where the OI delta is trustworthy with venues where it is not — would be the worse failure. If the agent needs to reason about total exposure across a coin, use the OI lens for direction and the volume lens for the corroborating activity read; do not expect the OI lens alone to be exhaustive across the full venue set.

These lenses choose what to look at. They are not a strategy. This is the failure mode the post exists to prevent. "Scan by funding" is not a trade. "Scan by volatility" is not a trade. The lens hands the composite a universe; the composite hands the agent a verdict with a conviction number; the agent decides what to do. Nothing in this post — and nothing in the scan surface — asserts that a stretched funding rate or an elevated ATR predicts a return. We have published no such claim, and inserting one would breach the measured-not-assumed rule the whole track record depends on. The lens is the where. The verdict is the what. The strategy is still yours.

What's Next?

  • the track record — the same 91.6% PFE win rate across 535,642+ verified calls that every lens in this post ultimately funnels into
  • the docs — enumerated parameter surface for every scan lens, including the interval-normalisation notes
  • the GitHub repo — reference MCP client with the scan-then-verdict loop wired end to end
  • Try Free in Telegram — the frictionless free-tier on-ramp; the same verdicts, no API key, no signup flow

— AlgoVault Labs

⭐ Star the repo to follow new exchanges and signals: https://github.com/AlgoVaultLabs/crypto-quant-signal-mcp

Top comments (0)