Support and Resistance Shouldn't Depend on Whoever Is Drawing the Chart

Ask five traders to mark support and resistance on the same BTC chart and you'll get five different sets of lines. Some anchor on wicks, some on closes, some on "the level that felt important last month." None of it is reproducible, which makes it useless as an input to anything automated — a trading bot, a screener, an LLM agent deciding whether to flag a coin.

That's the gap GET /api/v1/indicators/technical closes. It ships an sr block per symbol — up to 3 support and 3 resistance levels, computed the same way every time from swing-high/low pivots on the daily series, no discretion involved. Feed it to a bot and it makes the same call you would, minus the hindsight bias.

This post covers how the levels are actually calculated, what strength and dist_pct mean, and how to combine sr with the other structure fields on the same endpoint — ma, bollinger, range_state, rsi — to build a simple resistance-approach screener.

How Are Support and Resistance Levels Calculated Here?

Three steps, all on the daily candle series, no manual input:

  1. Find swing pivots. A bar is a swing high if it's the highest high within 3 bars on each side (a "fractal" — the standard, simplest swing-point rule); a swing low is the mirror case on lows. This alone produces dozens of raw touch points per coin.
  2. Cluster them. Raw pivots within 1.5% of each other are merged into a single level, averaged to one price. A level with 4 pivots clustered into it has been tested 4 times — that's the strength field.
  3. Filter for relevance. Any clustered level more than 30% from the current price is dropped as not actionable, then the remaining levels are ranked nearest-to-price first and capped at 3 per side.

One detail that surprises people coming from manual chart reading: a cluster becomes support if it sits below current price and resistance if above — regardless of whether the pivots that built it were originally swing highs or swing lows. A broken resistance becomes support and vice versa, exactly like it does when you draw it by hand. The algorithm just tracks the flip automatically instead of you re-drawing the line.

Reading the Response: strength and dist_pct

Call the endpoint and each item in items[] carries an sr object alongside the other structure fields:

curl "https://cryptodataapi.com/api/v1/indicators/technical?source=binance_spot&limit=1" \
  -H "X-API-Key: cdk_live_your_key"

A representative response shape:

{
  "items": [
    {
      "symbol": "ETH",
      "source": "binance_spot",
      "price": 3120.45,
      "sr": {
        "support": [
          { "price": 3042.10, "strength": 4, "dist_pct": -2.51 },
          { "price": 2895.00, "strength": 2, "dist_pct": -7.22 },
          { "price": 2680.50, "strength": 6, "dist_pct": -14.09 }
        ],
        "resistance": [
          { "price": 3210.75, "strength": 3, "dist_pct": 2.89 },
          { "price": 3450.00, "strength": 2, "dist_pct": 10.56 }
        ]
      },
      "range_state": { "zone": "mid", "position_pct": 61.4 },
      "ma": { "above_200": true, "dist_from_200_pct": 8.3 },
      "rsi": { "rsi_14_1d": 58.2, "state_1d": "neutral" }
    }
  ],
  "count": 1,
  "universe_size": 214
}

Two fields do all the interpretive work:

In the example above, ETH's nearest resistance at 3210.75 is only 2.89% away and has been touched 3 times — a real level actively containing price, not chart noise.

Support vs Resistance: Quick Reference

Both sides come from the identical pivot-clustering algorithm — only their position relative to price differs:

SupportResistance
PositionBelow current priceAbove current price
dist_pct signNegativePositive
Sort orderNearest (least negative) firstNearest (smallest positive) first
Max levels33
InterpretationPrice has bounced here beforePrice has stalled here before
On a clean breakBecomes resistance if price falls backBecomes support if price falls back

That last row is the role-reversal behavior from the previous section — it's a property of the clustering, not a separate rule, so it shows up in the data automatically once price crosses a level and later retests it.

sr Is One Block — the Rest of the Structure Overlay

/indicators/technical returns sr alongside three other fields on the same per-symbol payload, all computed off the same universe of Binance spot pairs and Hyperliquid perps:

sr is the sharpest tool for "where exactly is price likely to react," but it reads best paired with the others — range_state and ma tell you the broader trend context a level is sitting inside.

Worked Example: Flag Coins Approaching Resistance in an Uptrend

A single level in isolation is weak signal. Combine sr with the built-in filters and it becomes a screener. The endpoint takes ma_state, bb, range_zone, rsi, source, sort, order and limit, all AND-combined server-side:

curl "https://cryptodataapi.com/api/v1/indicators/technical?range_zone=near_high&ma_state=above_200" \
  -H "X-API-Key: cdk_live_your_key"

That query alone returns coins sitting near the top of their 20-day range while above their 200-day SMA — price approaching resistance inside an established uptrend, not a random spike. Client-side, add one more filter: keep only items whose nearest resistance[0].dist_pct is under 2% and whose strength is 2 or higher, to exclude untested levels.

Two more screener queries straight from the endpoint's own filters:

None of this requires plotting a single candle. It's three HTTP filters and a two-field client-side check.

When to Use This (and Its Limits)

Use it for: setting bot stop-loss / take-profit levels off real structure instead of a fixed %, screening for coins approaching a well-tested level, and confirming a breakout by checking whether price has cleared a strength-3+ level rather than a throwaway one.

Don't use it for: intraday scalping — the pivots are computed on daily bars, so levels update once a day, not tick by tick. And a level with strength: 1 is barely more than a single wick; weight it accordingly rather than trading it like a strength: 5 level.

The endpoint is Pro tier, covers both binance_spot and hyperliquid_perp sources, and returns the full universe (200+ symbols) in one call — no per-symbol looping required for a screener.