Tool-grounding for trading agents

Why does your trading agent hallucinate RSI/MACD — and how does tool-grounding fix it?

If you hand an LLM a raw candle array and ask for indicators, it will often state confident, wrong numbers. Here is why that happens, and the concrete fix: ground the math in a deterministic tool and let the model read a verified label instead.

Try the grounded brief — no signup Interpreted indicators →

TL;DR

LLMs are unreliable at arithmetic over long number arrays, so an agent handed raw OHLCV invents indicator values like RSI and MACD. The fix is tool-grounding: have a deterministic service compute the indicators and return interpreted state — e.g. "RSI 71 — overbought" — so the model reasons over a verified label instead of recomputing numbers. It reduces and grounds the failure mode; it doesn't make the agent infallible.

Why it happens

An LLM is a next-token predictor, not a calculator. When you paste a few hundred OHLCV rows into context and ask for RSI(14) or MACD, the model has to infer the answer from the surrounding tokens — and attention over a long numeric sequence is exactly the regime where it is weakest. There is no internal accumulator running the actual recurrence; instead the model pattern-completes toward a number that looks plausible. The result is a confident, specific, and frequently wrong value: "RSI is about 62," stated with the same fluency it would use for a fact it actually knows.

The failure is structural, not a prompt bug. Multi-digit arithmetic, running sums over windows, and exponential smoothing are precisely the operations that degrade as the array gets longer. It is well-documented as established practice that binding numeric computation to tools — letting a deterministic function produce the quantity and feeding the model the result — constrains the output to a verifiable value and reduces this class of hallucination. The model stops guessing the number because it is no longer being asked to.

The fix — interpreted state, not raw numbers

patternfetch computes indicators server-side and returns each one as an object carrying both the value and its label, so the agent never does the math:

The numbers are computed by a deterministic function over the candle window and then labeled. Here is the same moment, two ways:

Before — raw candles, model guesses
# agent gets 200 OHLCV rows in context
[[60125.4,60480,59890.1,60310.7,1284],
 [60310.7,60905,60280.0,60840.2,1551],
 … 198 more rows … ]

# agent "computes" RSI:
"RSI is roughly 62, momentum looks
 neutral-to-bullish."
   ^ invented — no calculation ran
After — grounded brief, model reads it
"indicators": {
  "rsi": { "v": 71.2, "state": "overbought" },
  "ema": { "v": 61240.8, "state": "above_20_50" }
},
"regime": { "trend":"up","strength":0.42,"volPct":2.13 }

# agent just reads the label:
"RSI 71.2 — overbought; price above the
 20 and 50 EMA; uptrend, moderate strength."
   ^ verified — value computed server-side

Same candles. In the "before" panel the model fabricates 62; the deterministic value is actually 71.2 — and 62 vs overbought is the difference between "looks neutral" and "stretched." See it live →

Why this is more reliable

Three properties do the work:

This is a narrow but real win: it removes the math from the model's job. What remains the agent's responsibility — and still fallible — is the reasoning built on those grounded facts.

Try it

Grounded indicators, free to start:

No-signup demoPOST /v1/demo returns a real brief with interpreted indicators, no key. ② Free key with $0.05 starter credit (~5 briefs) from one call, no card. ③ Then $0.01 per brief. Works over REST and over MCP so your agent can call it directly.

curl -X POST https://patternfetch.com/v1/demo \
  -H "Content-Type: application/json" \
  -d '{ "ticker": "BTC/USDT", "timeframe": "4h" }'
# -> indicators.rsi:{v,state}, ema:{v,state}, regime{…}

For agents: add the MCP server https://patternfetch.com/mcp (Streamable HTTP, OAuth one-click) and call patternfetch_brief. Full reference in the docs.

Try free — no signup Read the docs

FAQ

Which indicators does patternfetch interpret?

RSI, EMA and ATR are returned both as a computed numeric value and as an interpreted state label (RSI overbought/oversold/neutral, EMA position like above_20_50, and ATR-derived volatility in the regime block). The agent reads the label instead of recomputing the math.

Does this remove all hallucination?

No. It grounds the indicator, level and pattern facts — those are deterministic and verifiable. The agent's own reasoning, conclusions, and any trade idea built on top of them are still its own and can still be wrong. Tool-grounding reduces a specific failure mode (invented numbers); it does not make the agent infallible.

Can I get the raw value too?

Yes. Each indicator is an object with both the numeric value (the v field) and its state — e.g. rsi:{v:71.2,state:"overbought"}. You get the verified number and its label together; nothing is hidden behind the interpretation.

Is this investment advice?

No. It's impersonal market data and algorithmic signals, for informational purposes only — not advice, not personalized, non-executing. See the disclaimer.

Related

Interpreted RSI/EMA/ATR API → How the signals are computed → API & MCP docs → Try it free →