Find similar chart patterns in Python, or use an API?

Build a similar-chart search in Python with pandas, or call a hosted one? The code steps, five pitfalls from look-ahead to overlap, and what each costs.

Building a similar-chart search in Python is mostly easy code and hard choices. The distance formula is a few lines of pandas. The choices around it decide the answer: how long the window is, how you scale it, and how you stop matches from overlapping. Five pitfalls do most of the damage: look-ahead, overlapping matches, mixed markets, missing bars and window choice. A hosted search saves the plumbing, not the choices: on Comparand, 300 searches cost $3.00 at list price.

Past matches are not a forecast.

For the same steps without code, see How to find past crypto charts that look like today's.

What does a DIY similar-chart search need?

pandas is a free library for tables of data. It gives you labeled tables, time alignment, resampling, rolling statistics and shifts. It does not come with an exchange archive or a way to simulate trades, so your code supplies the data, the timing and the fees.

Here are the steps:

  1. Get clean bars for one coin on one exchange. A bar is the open, high, low and close price over a set time. Keep the exchange, symbol and market type as columns.
  2. Cut the history into windows. A window is a fixed number of bars, such as 48 hourly bars.
  3. Scale each window. Raw prices differ by year. In our test, we turned each window into its hourly price changes (log returns, np.log(close).diff()), then subtracted the window's average and divided by its spread (a z-score). Without that, a match would mean "a similar price level", not a similar shape.
  4. Score every past window. Use one distance score, such as the sum of squared differences between the two scaled windows. We compared the latest window with all past ones, with no shortcuts.
  5. Pick the closest, without overlap. Take the best match, then skip anything that overlaps it, and repeat until you have ten.
  6. Record what came next. Use the same later horizons for every match.
A chart cut into equal windows, with overlapping candidates greyed outIllustration with a made-up price line. Top: a chart cut into 6 equal windows of 48 candles, with the latest window outlined at the right. Below: candidate windows of the same length on one candle axis. The closest window is kept. Two windows that start a few candles later overlap it and are greyed out as skipped, and so is a window that overlaps the latest window. The next closest window with no overlap is kept. The search repeats until 10 matches are kept.WINDOWS AND OVERLAP / ILLUSTRATION48 candlesEvery window is the same length.Chart cut into windowslatestWindows to compare, closest firstlatest window#1 closest: keptskipped: overlaps #1skipped: overlaps #1#2 next closest: keptskipped: overlaps latest288192960candles back from the latest endKeep the closest window, skip any thatoverlap it, then repeat until you have 10.Illustration: made-up chart; spacing to scale.comparand.xyz
A chart cut into equal windows, with overlapping candidates greyed out

Where does the price data come from?

You can use CCXT, a free library under the MIT license. Its repository lists 100+ exchanges and prediction markets. Each exchange's own limits still apply.

Check the limits before you plan. Hyperliquid's candle request returns only the latest 5,000 candles, and its archive bucket does not provide candles. Our CCXT vs hosted API guide compares the routes.

Comparand's venue_bars tool is free and returns completed bars only, from 1 minute to 1 day. That helps with the look-ahead pitfall below. Our guide to exchange price gaps shows why you must keep one exchange fixed.

What goes wrong in a DIY search?
Pitfall What goes wrong The fix
Look-ahead Using a candle that has not closed, or a match whose outcome was not yet known Completed bars only; skip matches whose outcomes come after your query time
Overlap Ten "matches" that are really the same week, shifted by one hour One match per episode; no overlap with the query
Mixed markets Matching Binance Bitcoin against Coinbase Bitcoin or another coin Same coin, same exchange, same timeframe
Missing bars Gaps change the shape without warning Check gaps; do not fill them silently
Window choice A different length picks different cases Choose lengths before you see outcomes

A good test for look-ahead: delete every price after the query time and run the search again. The matches should not change.

Look-ahead can fool you badly. One timing bug turned a losing hourly Bitcoin rule into a fake winner. See our look-ahead bias example.

How much does window length change the matches?

This is the warning from our own data. We ran the same 300 hourly search times per market with windows of 24, 48 and 96 candles. Searches ran from January 2020 to September 29, 2026. Each search returned its ten closest past charts. A match counted as kept if two windows picked a past chart ending at exactly the same hour.

How much does window length change the matches?
Market 24 vs 48 candles 48 vs 96 candles 24 vs 96 candles
Binance BTCUSDT 15.57% kept 19.57% kept 5.67% kept
Binance ETHUSDT 14.47% kept 18.97% kept 5.53% kept
Coinbase BTC-USD 12.77% kept 18.80% kept 4.43% kept
Coinbase ETH-USD 11.80% kept 15.20% kept 4.00% kept

Each row is 300 searches. BTCUSDT and ETHUSDT are Binance perps (futures that never expire); the other two are Coinbase spot markets.

In plain terms: doubling the window kept 1 or 2 of the 10 matches. Between 24 and 96 candles, the two lists shared nothing in 69.00% of Binance Bitcoin searches. Even when we let a match count if it ended within 12 hours of another, Binance Bitcoin only moved from 1.96 to 2.04 kept cases out of 10 for 48 vs 96 candles.

No length was the best across all four markets, and how often the matches pointed the right way over the next 24 hours stayed between 42.00% and 55.00%. So window length is a setting you must record. If you tune it until your results look good, you are fitting luck. Our overfitting test shows how that ends, and the full window-length study has more detail.

DIY or hosted: how do they compare?

DIY or hosted: how do they compare?
Question DIY with pandas Comparand shape_analogs
Setup You write the data loading, windows, scaling, distance, overlap rule and outcome table One request with venue, symbol, timeframe, window and number of matches
Cost Libraries are free; your time, storage and compute are not measured here $0.01 per search, paid from credits
Coins and exchanges Any you can get data for Big coins on Binance, Bybit, OKX and Coinbase, plus Hyperliquid perps
Matching method You choose and can change it Set by Comparand; the methods page explains it
Output Whatever you build Each case's path and later moves; no average or hit rate
Same coin, same exchange Your job to enforce Always; matches never come from another coin or exchange
Overlap and look-ahead Your job to enforce One match per episode, never overlapping the query

The hosted search takes a window from 20 to 200 bars (default 48), 1 to 20 matches (default 10) and five timeframes: 5 minutes, 15 minutes, 1 hour (default), 4 hours or 1 day. Each match shows its later moves after a quarter, half and full window, in basis points. One basis point is one hundredth of one percent.

Choose DIY if you need a different distance measure, extra inputs, or coins and exchanges Comparand does not cover. Choose hosted if you want the plumbing done and the same-market rule enforced.

When do you need many searches at once?

For Hyperliquid, hl_analogs finds the past moments nearest to a coin's state at a decision time, with the outcome over the next 1 or 4 hours. hl_analogs_batch runs up to 100 of these in one call and can return CSV. You pay $0.01 per search that runs; refused queries are free. For shape_analogs, each search is its own request: 300 searches cost $3.00 at list price.

How we measured this

We used public Binance and Coinbase hourly prices. For each search, we turned the last 24, 48 or 96 hourly price changes into a shape on a common scale. We scored every past window and kept the ten closest from the same coin on the same exchange, with no overlap. Every past match had its full 48 hours of later prices known at the search time. The same past cases can show up in many searches, so searches are not independent. We did not time or cost a DIY build, and four markets cannot prove results for other coins or periods.

Try this in Comparand

With Comparand connected to your AI agent, ask:

  • "Find the 10 closest past charts to the latest 48 completed hourly bars of Binance Ethereum, and list the end time of each." shape_analogs returns each case with its own path and later moves.
  • "Repeat with 96 bars, and tell me which end times appear in both lists." This checks the window effect on your own market.

In code, the same search is a POST request to /v1/shape/analogs; the docs show the settings. Use it to check your pandas output on the same coin, exchange and end time.

You can try 3 coins free. Results are past cases, not a forecast.

The short version

  • A DIY search is a few lines of pandas plus careful choices on scaling, overlap and timing.
  • Window length changed most past matches in our test: 48 vs 96 kept 15.20% to 19.57%.
  • Use completed bars only, and one coin on one exchange.
  • Hosted search saves the plumbing and enforces those rules; DIY lets you change the method.
  • Pick settings before you see outcomes.

Questions people ask

How do you find similar chart patterns in Python?

Cut the price history into windows of equal length, scale each window to a common size, score its distance to the latest window, and keep the closest ones that do not overlap. Then record what price did after each match, using only data that was known at the time.

Why do my similar-chart results change when I change the window?

Because a different window is a different shape. In our hourly Bitcoin and Ethereum tests, going from 48 to 96 candles kept only 15.20% to 19.57% of the ten closest past matches. Pick the window length before you look at outcomes.

Is there an API that finds similar past charts?

Comparand has one. Its shape_analogs search takes a coin, an exchange and a window, and returns up to 20 past cases of the same coin on the same exchange, each with its own later moves. It costs $0.01 per search and gives no average or hit rate.

What is the biggest mistake when matching past charts in code?

Using information from after the decision. One common case is an unfinished candle. Use completed bars only, and only count past matches whose outcomes were already known at the time of your query.

Read next