patternfetch Stock chart pattern detection API

Stock chart patterns · API + MCP

Chart patterns on stocks & ETFs — measured against the baseline, not against 50%.

One POST /v1/brief with a stock or ETF ticker and a timeframe detects the multi-bar formations — double top, double bottom, head & shoulders — geometrically. Every detection ships the backtested hit rate, the pattern-free baseline for that same market, timeframe and horizon, and a cluster-robust 95% interval on the difference. That comparison is the only one that means anything: US equities drift up, so any forward window closes up more often than down with no pattern present. Measured that way on 117 US stocks & ETFs, the daily high-confidence chart patterns land inside their baseline — and your model is told so, instead of reading drift as an edge.

StocksETFs1m → 1wYahoo · adjustedmulti-bar geometry

Three textbook chart patterns, each against its own baseline.

Each shape scored a near-perfect geometric fit. Here is how often it resolved in its own direction over the next 10 bars on US stocks & ETFs — set against how often the same window resolved that way with no pattern present.

The vertical rule in each row is that row's pattern-free baseline. The band is the cluster-robust 95% interval on the lift; where it covers the rule, the shape is indistinguishable from no shape at all.

SPY · 1d
double bottom · bullish
shape 0.75–1.00 · baseline 57.8%
56.9%−0.9pp ±2.8n=6,692
No lift
QQQ · 1d
double top · bearish
shape 0.75–1.00 · baseline 42.0%
43.1%+1.1pp ±2.7n=7,508
No lift
NVDA · 1d
head & shoulders · bearish
shape 0.75–1.00 · baseline 42.0%
42.0%+0.0pp ±3.1n=2,795
On baseline
Directional hit rate over the next 10 bars, non-overlapping samples, no lookahead, 117 US stocks & ETFs (Yahoo, adjusted), asOf 2026-07-18. The axis is a plain 30–70 scale; the vertical rule inside each row is that row's own pattern-free baseline — 57.8% for a bullish call on the daily, 42.0% for a bearish one (n=46,038) — not the 50% mark. The shaded band is the cluster-robust 95% interval on the lift, clustered by date because ~117 tickers move together on the same day. All three bands cover their baseline: on this corpus and horizon none of these shapes shifts the odds measurably, and head & shoulders lands exactly on its baseline. That is the same evidence block your model receives in the payload. Competitors publish a hit rate on its own — the open web quotes the same bearish engulfing at 57%, 75.76% and 79%, none of them with a baseline or an interval.

TL;DR — One POST /v1/brief (or the MCP tool patternfetch_brief) with { ticker, timeframe } detects multi-bar chart patterns on stocks & ETFs — double_top, double_bottom, head_and_shoulders — plus 1–2 bar candlestick patterns, all in analysis.patterns. Each directional pattern carries a geometric confidence (0..1), the candle index at, the span, and an evidence block: the backtested hit rate, the pattern-free baseline for that market, timeframe and horizon, the lift between them and a cluster-robust 95% interval on that lift. So the model can tell a real shift in the odds from the market's own drift. No charting, no image recognition — it reads the adjusted numeric series.

Chart patterns vs candlestick patterns

Both shapes come back in the same analysis.patterns array. Chart patterns describe a formation over many bars; candlesticks are local 1–2 bar signals.

ClassBars coveredExamples (on stocks & ETFs)
Chart patternsmany (a formation)double_top · double_bottom · head_and_shoulders
Candlestick patterns1–2 barsbullish_engulfing · bearish_engulfing · hammer · doji

Each chart pattern reports a span — the number of candles the formation covers. Want the local 1–2 bar signals instead? See the stock candlestick patterns API.

Request in, patterns + baseline comparison out.

A real /v1/brief shape for an S&P 500 ETF on the daily. The evidence.lift block is the part every other API is missing.

Request

POST https://patternfetch.com/v1/brief
Authorization: Bearer pf_…
Content-Type: application/json

{ "ticker": "SPY",
  "timeframe": "1d" }

Response — analysis.patterns[0]

{ "name": "double_bottom",
  "confidence": 0.83, "at": 176, "span": 22,
  "evidence": {
    "scope": "US stocks & ETFs",
    "tf": "1d", "band": "0.75-1.00",
    "horizon": 10, "n": 6692,
    "hitRate": 0.569, "ci95": 0.012,
    "lift": {
      "baseline": 0.578, "lift": -0.009,
      "ci95Clustered": 0.028,
      "informative": false,
      "reading": "indistinguishable-from-baseline"
    },
    "dist": { "winRate": 0.569, "median": 0.006 }
  } }

Read it as: a clean double bottom completing at candle 176 over 22 bars — and historically, that exact pattern on the daily resolved up 56.9% of the time (n=6,692) over the next 10 bars on US equities. Read alone that looks bullish. Against the 57.8% baseline for the same market, timeframe and horizon it is a lift of −0.9pp with a cluster-robust interval of ±2.8pp — indistinguishable from no pattern at all, which is why informative comes back false. Your model can now weight the shape as context rather than as a signal. The same call also returns support/resistance levels, the regime (trend + volatility), interpreted indicators (RSI/EMA state), and a one-line nl summary — a few hundred tokens, not a candle wall. See it live →

The nl line carries the comparison too, so the summary can never sound more certain than the data: "SPY: uptrend (moderate), +0.42% last 1d, RSI 57.90 (neutral), double_bottom (conf 0.83, n=22, hist 56.9% vs 57.8% base over 10b — within baseline)."

Every stock pattern ships its hit rate — and the baseline it has to clear.

A hit rate on its own is unreadable, and a crypto-derived one is wrong on a stock. patternfetch keeps a baseline per market, timeframe and horizon and routes by asset class: stocks & ETFs (Yahoo, adjusted) score against the US-equities table, crypto against the crypto-pairs table. Below: the daily, high-confidence buckets for the three chart patterns on US stocks & ETFs, each next to the rate the same window produced with no pattern present.

Chart patternDirectionHit rate (10-bar)BaselineLift95% CI (clustered)SampleRead
double_bottombullish56.9%57.8%−0.9pp±2.8pp6,692within baseline
double_topbearish43.1%42.0%+1.1pp±2.7pp7,508within baseline
head_and_shouldersbearish42.0%42.0%+0.0pp±3.1pp2,795exactly on baseline

117 US stocks & ETFs · timeframe 1d · confidence band 0.75–1.00 · horizon 10 bars · non-overlapping samples, gross-directional, no lookahead · asOf 2026-07-18. Baselines are measured the same way over every window in the corpus with no pattern involved: 57.8% up / 42.0% down on the daily (n=46,038). They shift by timeframe — 1w 61.2/38.8, 4h 54.0/46.0, 1h 52.7/47.2 — which is exactly why a fixed 50% reference would misread three of the four. Hit rates and baselines both vary by timeframe and confidence band; the live numbers are whatever the corpus says at call time.

Where the bullish/bearish split actually comes from

Equities carry a structural upward drift. Over any random 10-bar window price is more likely to close up than down, and on the daily that prior is 57.8% up / 42.0% down with no pattern involved at all. A bullish shape only has to agree with that drift to print a number in the high 50s; a bearish shape has to fight it, so it prints in the low 40s. Both numbers are almost entirely the drift. Subtract it and what remains here is −0.9pp, +1.1pp and +0.0pp — inside the interval in all three cases.

Two corrections got us there. The reference line moved from 50% to the measured baseline for each market, timeframe and horizon. And the intervals are now clustered by date: counting ~117 tickers that move together on the same day as independent samples had made the intervals on high-volume daily stock buckets 2.1×–2.7× too narrow. Across all 105 buckets we publish (60 stock, 45 crypto), three clear an uncorrected cluster-robust interval — all three crypto, and fewer than the ~5.3 that chance alone would produce — and after correcting for testing 105 of them, not one survives; on US stocks & ETFs it is 0 of 60. The patterns stay in the payload as shape and context — the change is that the number next to them no longer implies an edge that the measurement does not support. See the methodology →

Same shape, different baseline — and the split disappears

Crypto has no structural drift, so its baselines sit near a coin flip: 49.7% up / 50.1% down on 4h (n=11,990). Run the same high-confidence double_bottom there and it hits 47.5% against that 49.7% baseline — a lift of −2.2pp (n=1,508). The bullish-above / bearish-below split that shows up so cleanly on stocks simply does not appear on crypto. That is the cleanest evidence that the split on stocks was the drift and not the pattern: change the drift, and the "edge" moves with it.

One schema, one baseline per market. Your agent is never handed a crypto baseline for a stock, or a 50% reference for either. Compare on the crypto chart pattern API.

Adjusted equity data, free to start.

Free to start:No-signup demoPOST /v1/demo returns a real brief with detected patterns and evidence, no key. ② Free key with $3.00 starter credit (300 briefs) from one call, no card. A brief is $0.01. Pay with x402 (USDC on Base, no account) or Stripe. Credits never expire. Pricing →

Connect over MCP. Read analysis.patterns.

Streamable HTTP at /mcp. Discovery (tools/list) is free — no key; a tools/call is billed like the REST route. Five tools, one schema across stocks, ETFs and crypto.

patternfetch_brief patternfetch_multi patternfetch_delta patternfetch_analogs patternfetch_capabilities

A) OAuth — one-click, nothing to paste

# Claude.ai → Settings → Connectors → Add
# custom connector, then Authorize once —
# a free-tier key is minted for you.
https://patternfetch.com/mcp

# or one line:
claude mcp add --transport http \
  patternfetch https://patternfetch.com/mcp

B) Bearer key (config)

{ "mcpServers": {
    "patternfetch": {
      "url": "https://patternfetch.com/mcp",
      "headers": {
        "Authorization": "Bearer pf_…"
      } } } }

Or let the agent pay as it goes: x402 settles ~$0.01 per call in USDC on Base — no account, no card, no key — discoverable at /.well-known/x402.json.

Questions.

Which chart patterns does it detect on stocks?
Multi-bar chart patterns: double_top, double_bottom and head_and_shoulders, detected geometrically from the adjusted price series. The same response also returns 1–2 bar candlestick patterns (bullish_engulfing, bearish_engulfing, hammer, doji) in analysis.patterns. See the candlestick patterns API for those.
What is the base rate, and how is it different from confidence?
confidence is a geometric shape score (0..1) — how cleanly the series matches the pattern. The base rate (evidence.hitRate) is separate: how often that exact pattern, timeframe and confidence band historically resolved in its own direction over the next 10 bars, with sample size (n), measured with no lookahead. That number cannot be read on its own, so evidence.lift ships alongside it: the pattern-free baseline for the same market, timeframe and horizon, the lift between the two, and a cluster-robust interval (ci95Clustered) on that lift. Confidence says "this is a clean shape"; lift says whether the clean shape changed the odds.
Do these chart patterns actually give an edge on stocks?
On what we measured, no — and the API says so rather than leaving your model to guess. Over 117 US stocks & ETFs at a 10-bar horizon, the daily high-confidence buckets came in at double_bottom −0.9pp (±2.8), double_top +1.1pp (±2.7) and head_and_shoulders +0.0pp (±3.1) against their own baselines. On US stocks & ETFs that is 0 of 60 buckets. Across all 105 buckets we publish (60 stock, 45 crypto), three clear an uncorrected cluster-robust interval — all three crypto, and fewer than the ~5.3 that chance alone would produce — while none of them survives correcting for having tested 105 buckets. That is a statement about this corpus, horizon and confidence band, not about every pattern in every market. The patterns still ship — as shape, span and location, next to regime, support/resistance levels and interpreted indicators — with a number that stops an agent inventing significance that is not there.
Why are the stock base rates different from crypto?
Because the baselines are different. US equities drift up, so the daily pattern-free baseline is 57.8% up / 42.0% down (n=46,038). Crypto has no comparable drift — its 4h baseline is 49.7% up / 50.1% down (n=11,990). So a high-confidence double bottom reads ~57% on stocks and ~47.5% on crypto, and nearly all of that gap is the baseline rather than the shape: measured against their own baselines both are flat (−0.9pp and −2.2pp, each inside its interval). patternfetch routes by asset class automatically, so a stock is never scored against a crypto baseline.
Which timeframes and tickers are supported?
US stocks and ETFs (e.g. AAPL, SPY, NVDA, QQQ) plus crypto spot pairs (e.g. BTC/USDT). Timeframes 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w. Pass ticker and timeframe to POST /v1/brief.
Is this investment advice?
No. It's impersonal market data and algorithmic signals, for informational purposes only — not investment, financial, legal or tax advice, not personalized, non-executing. See the disclaimer.
Related

Keep exploring.