Skip to content

Feature idea: Pattern similarity signals as vectorbt indicators #841

@grahammccain

Description

@grahammccain

Idea

vectorbt excels at fast vectorized backtesting with custom indicators. Historical chart pattern similarity could be an interesting signal to test — instead of computing technical indicators from price alone, query what happened historically when the chart looked similar.

Chart Library provides this via API: 24M+ pre-computed pattern embeddings across 19K US equities (10 years). For any (symbol, date), it returns the top 10 most similar historical chart patterns with their actual forward returns.

How it could work with vectorbt

import vectorbt as vbt
import pandas as pd
import requests

def fetch_pattern_signals(symbol: str, dates: pd.DatetimeIndex) -> pd.DataFrame:
    """Fetch pattern similarity signals for a date range."""
    records = []
    for date in dates:
        date_str = date.strftime("%Y-%m-%d")
        try:
            resp = requests.get("https://chartlibrary.io/api/v1/search", params={
                "symbol": symbol, "date": date_str, "timeframe": "RTH"
            }, headers={"X-API-Key": "your-key"}, timeout=5)
            matches = resp.json()["matches"]
            records.append({
                "date": date,
                "pattern_win_rate": sum(1 for m in matches if m["return_5d"] > 0) / len(matches),
                "pattern_avg_return": sum(m["return_5d"] for m in matches) / len(matches),
                "pattern_confidence": 1.0 / (1.0 + matches[0]["distance"]),
            })
        except Exception:
            records.append({"date": date, "pattern_win_rate": 0.5, "pattern_avg_return": 0, "pattern_confidence": 0})
    
    return pd.DataFrame(records).set_index("date")

# Build signals
signals = fetch_pattern_signals("AAPL", price.index)

# Use as vectorbt entry/exit signals
entries = signals["pattern_win_rate"] > 0.7
exits = signals["pattern_win_rate"] < 0.4

pf = vbt.Portfolio.from_signals(price, entries, exits)
pf.stats()

What the API returns per match

  • Symbol, date, timeframe of historical match
  • L2 distance (lower = more similar)
  • Forward returns: 1d, 3d, 5d, 10d actual returns

Additional signals available

  • /api/v1/anomaly/{symbol} — how unusual is today's pattern vs history
  • /api/v1/volume-profile/{symbol} — intraday volume vs historical average
  • /api/v1/scenario — conditional forward returns ("what if SPY drops 3%?")

Details

The workflow would be: pre-fetch pattern signals for your date range, store as a DataFrame column, then use vectorbt's speed for the actual backtesting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions