EchoTime Explainable time-series similarity for humans and agents.
Examples / Flagship demo
Flagship demo

BTC, Brent, and VIX in 2024

A macro example on real FRED data asking whether BTC behaved more like oil or more like implied volatility across 2024.

Question

Was BTC structurally closer to oil or to volatility in 2024?

This page loads daily BTC, Brent, and VIX series from a local CSV snapshot built from FRED. The result is intentionally not dramatic: EchoTime shows that BTC is somewhat closer to VIX than to Brent, but the analogy is only moderate and changes across windows.

Input two or more aligned market series Call compare_series(df['btc_usd'], df['vix']) Output SimilarityReport + rolling windows
  1. Load the market series you want to compare.
  2. Run compare_series(...) for the pair you care about first.
  3. Use rolling_similarity(...) when you suspect the relationship changes across regimes.
Result at a glance
Pearson 0.06Spearman 0.09Mutual info 0.12Diff r -0.32
Component mean 0.16 across 5 time-series metrics

BTC vs VIX: Pearson r 0.06, Spearman rho 0.09, Kendall tau 0.05. The weakest agreement appears in shape similarity and trend similarity, so timing or regime differences probably matter.

spectral similarity0.41
dtw similarity0.40
shape similarity0.00
trend similarity0.00
Runnable example

This is the minimal script a human user would actually run: load data, call EchoTime, inspect the returned object.

from pathlib import Path

import pandas as pd
from echotime import compare_series, rolling_similarity

data_path = Path(__file__).resolve().parents[1] / "data" / "real_btc_oil_vix_2024.csv"
df = pd.read_csv(data_path)

btc_vix = compare_series(df["btc_usd"], df["vix"], left_name="BTC", right_name="VIX")
btc_brent = compare_series(df["btc_usd"], df["brent_usd"], left_name="BTC", right_name="Brent")
windows = rolling_similarity(df["btc_usd"], df["vix"], window=30, step=10)

print(btc_vix.to_summary_card_markdown())
print(
    {
        "btc_vix_similarity": round(btc_vix.similarity_score, 3),
        "btc_brent_similarity": round(btc_brent.similarity_score, 3),
        "rolling_windows": len(windows),
    }
)
What you should see

You should get mixed evidence rather than a clean analog: some metrics stay moderate, and the rolling view should show where the relationship strengthens or breaks.

# EchoTime similarity summary

**Compared:** BTC vs VIX

## Headline

BTC vs VIX: Pearson r 0.06, Spearman rho 0.09, Kendall tau 0.05. The weakest agreement appears in shape similarity and trend similarity, so timing or regime differences probably matter.

## Familiar statistics

| metric | value |
|---|---:|
| Pearson r | 0.065 |
| Spearman rho | 0.093 |
| Kendall tau | 0.055 |
| Best-lag Pearson r | 0.328 |
| Mutual info | 0.125 |
| First-difference r | -0.318 |

## Time-series-specific metrics

| plain-language label | score |
|---|---:|
| spectral similarity | 0.413 |
| dtw similarity | 0.401 |
| shape similarity | 0.000 |
| trend similarity | 0.000 |

## Recommended next actions

- Plot both series after z-score normalization to show the shared shape without scale differences.
- Run rolling or windowed similarity if you expect the relationship to change over time.
- Use structural-profile similarity when scales, frequencies, or observation modes differ too much for raw-shape comparison.
  • BTC vs VIX: Pearson 0.06 / Spearman 0.09 / Mutual info 0.12; BTC vs Brent: Pearson -0.40 / Spearman -0.31 / Mutual info 0.21.
  • The rolling curve shows that the analogy is regime-dependent rather than something you should treat as globally stable.
  • This is a better external demo than a hand-picked market anecdote because the claim is explicit and reproducible.
Use your own data

This is the same workflow you would use for returns, prices, search trends, or any pair of aligned signals.

  • For very different scales, compare returns or z-scored values instead of raw levels.
  • Use rolling_similarity(...) for regime questions; a single whole-period average is usually too blunt.
  • If your series come from a CSV, load them with pandas and pass the numeric columns directly into compare_series(...).
BTC vs VIX
EchoTime series previewSeries previewBTCVIX

The raw scales differ, so EchoTime normalizes before comparing shared structure.

Similarity radar
Similarity radarSimilarity radarRadar over the time-series metrics. Read it together with Pearson, Spearman, and mutual info.ShapeDTWTrendDerivativeSpectral

The radar shows where the BTC-VIX analogy is real and where it stays weak.

Rolling component mean
Rolling component meanRolling component meanmean=0.19, min=0.12, max=0.32 across per-window metric means

Rolling windows show when the average across the similarity metrics strengthens and when it fades.