SPB Git

spb/anomaly-atlas Public License

Systematic discovery & rigorous validation of statistical anomalies in open HF market data (hfmarketdata.io) — pre-registered, artifact-null-driven, fully reproducible. Live atlas: www.anomaly-atlas.io

Python 61.4% JavaScript 28.7% CSS 8.6% Shell 0.7% Makefile 0.5%

Web: server-rendered SVG figures from results.json (dataviz-validated)

- web/lib/charts.js: expB staleness scatters, expC VR30-excess strip plot
  (FDR emphasis), expD raw-vs-fresh dumbbells; palette validated
  (validate_palette.js all-pairs PASS on card surface), native tooltips,
  ink-token text, selective direct labels
- figures injected on experiment pages + latest figure on home
- rendered and eyeballed (rsvg): fixed tick-label collision

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 4 h ago (Aug 12, 2026) parent c4977f2

Showing 7 changed files with +771 and −26

added benchmarks/synthetic/test_gate_expd.py +98 −0
@@ -0,0 +1,98 @@
1 +# =============================================================================
2 +# Project : anomaly-atlas
3 +# File : benchmarks/synthetic/test_gate_expd.py
4 +# Purpose : §8.1 gate for expD: grids, LOCF masks, both-fresh de-artifacting
5 +# Author : Simon-Pierre Boucher
6 +# Contact : contact@spboucher.ai
7 +# Data src : hfmarketdata.io (sole data source)
8 +# Created : 2026-08-12
9 +# Modified : 2026-08-12
10 +# Platform : macOS / Apple Silicon (arm64)
11 +# License : All rights reserved (research code)
12 +# =============================================================================
13 +"""Gate the expD alignment primitives before real data:
14 +
15 + * grid building from bar dicts is exact (slots, NaN gaps, RTH filter);
16 + * LOCF returns carry correct fresh-masks; missing days never leak;
17 + * the both-fresh treatment REMOVES the planted non-synchronicity artifact
18 + that the raw LOCF join manufactures (the core expD claim).
19 +"""
20 +
21 +from __future__ import annotations
22 +
23 +import sys
24 +from pathlib import Path
25 +
26 +import numpy as np
27 +
28 +sys.path.insert(0, str(Path(__file__).resolve().parent))
29 +
30 +from generators import correlated_pair # noqa: E402
31 +
32 +from anomaly_atlas.data.cleaning import (
33 + both_fresh,
34 + locf_day_returns,
35 + nan_xcorr,
36 + rth_day_grids,
37 +)
38 +
39 +SEEDS = [1, 2, 3]
40 +
41 +
42 +def bars_for_day(day: str, prices: dict[str, float]) -> list[dict]:
43 + return [{"datetime": f"{day} {hhmm}:00", "close": p} for hhmm, p in prices.items()]
44 +
45 +
46 +def test_grid_building_slots_and_rth_filter():
47 + bars = bars_for_day("2024-01-02", {"09:30": 100.0, "09:32": 101.0, "15:59": 102.0})
48 + bars += bars_for_day("2024-01-02", {"04:00": 99.0, "16:00": 103.0}) # outside RTH
49 + days = rth_day_grids(bars)
50 + g = days["2024-01-02"]
51 + assert np.isfinite(g[[0, 2, 389]]).all()
52 + assert np.isnan(g[1]) and np.isnan(g[3])
53 + assert np.isfinite(g).sum() == 3 # extended-hours bars excluded
54 +
55 +
56 +def test_locf_masks_and_missing_days():
57 + bars = bars_for_day("2024-01-02", {"09:30": 100.0, "09:32": 101.0, "09:33": 101.5})
58 + days = rth_day_grids(bars)
59 + r, fresh = locf_day_returns(days, ["2024-01-02", "2024-01-03"])
60 + assert len(r) == 389 * 2
61 + assert r[0] == 0.0 and not fresh[0] # 09:31 carried forward
62 + # 09:31->09:32 return ends fresh but STARTS on a carried value -> not fresh
63 + assert abs(r[1]) > 0 and not fresh[1]
64 + # 09:32->09:33: both endpoints fresh -> a genuine 1-minute return
65 + assert abs(r[2]) > 0 and fresh[2]
66 + assert np.isnan(r[389:]).all() # absent day never leaks
67 + assert not fresh[389:].any()
68 +
69 +
70 +def synthetic_pair_day_grids(n_days: int, rho: float, p_obs: float, seed: int):
71 + """Correlated 1min walks; y observed sparsely. Returns (days_x, days_y, day_list)."""
72 + rng = np.random.default_rng(seed)
73 + px, py = correlated_pair(n_days * 390, rho=rho, sigma=0.001, seed=seed)
74 + days_x, days_y, day_list = {}, {}, []
75 + for d in range(n_days):
76 + day = f"2024-02-{d + 1:02d}"
77 + day_list.append(day)
78 + gx = px[d * 390 : (d + 1) * 390].copy()
79 + gy = py[d * 390 : (d + 1) * 390].copy()
80 + mask = rng.random(390) < p_obs
81 + mask[0] = True
82 + gy[~mask] = np.nan
83 + days_x[day] = gx
84 + days_y[day] = gy
85 + return days_x, days_y, day_list
86 +
87 +
88 +def test_both_fresh_removes_planted_nonsync_artifact():
89 + for seed in SEEDS:
90 + dx, dy, dl = synthetic_pair_day_grids(25, rho=0.7, p_obs=0.3, seed=seed)
91 + rx, fx = locf_day_returns(dx, dl)
92 + ry, fy = locf_day_returns(dy, dl)
93 + raw = nan_xcorr(rx, ry, 2)
94 + assert raw[1] > 0.10 # artifact present in the raw LOCF join
95 + bx, by = both_fresh(rx, fx, ry, fy)
96 + sync = nan_xcorr(bx, by, 2)
97 + assert abs(sync[1]) < 0.05 # and gone on the synchronized subsample
98 + assert sync[0] > 0.6 # true contemporaneous corr (rho=0.7) recovered
modified data_manifest/index.jsonl +198 −0
@@ -453,3 +453,201 @@
453 453 {"author": "Simon-Pierre Boucher", "cache_key": "1eaea539110d9944b65941b61cff5ed2", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/QQQ", "fetched_utc": "2026-08-12T06:30:10Z", "first": "2015-01-22 09:49:00", "last": "2015-06-01 12:01:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-22 09:49:00", "timeframe": "1min"}, "rows": 50000, "sha256": "d8610342038fb74f95f5843b1d3fd5fefde1d4aaf17d69ef5966c57a8cc6700f"}
454 454 {"author": "Simon-Pierre Boucher", "cache_key": "2761824bd1207117f1f146ce48360f4d", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/QQQ", "fetched_utc": "2026-08-12T06:30:11Z", "first": "2015-06-01 12:01:00", "last": "2015-09-30 06:41:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-06-01 12:01:00", "timeframe": "1min"}, "rows": 50000, "sha256": "cf9091dc4a890dce3d364f3e2653dcce351b5bcf0e8031c047e7e2942d7922c5"}
455 455 {"author": "Simon-Pierre Boucher", "cache_key": "95ddc7d093d3f300b8a8e65aebf802af", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/QQQ", "fetched_utc": "2026-08-12T06:30:13Z", "first": "2015-09-30 06:41:00", "last": "2015-12-31 19:59:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-09-30 06:41:00", "timeframe": "1min"}, "rows": 36973, "sha256": "bed3247afef9ee847be9f8c7eb24a731ca73e414bf8fd3b7bdb58fc8a1184403"}
456 +{"author": "Simon-Pierre Boucher", "cache_key": "a4559507f93c9e2f582ac90b84ea0469", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/SPY", "fetched_utc": "2026-08-12T06:40:49Z", "first": "2006-01-03 04:20:00", "last": "2006-05-17 09:47:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "5c5b0930b264757192740551c31ed198ecb65859a679791269f4f9f3cb629a73"}
457 +{"author": "Simon-Pierre Boucher", "cache_key": "45ccc829314d5dcc37d9ae4be82e7bd2", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/SPY", "fetched_utc": "2026-08-12T06:40:50Z", "first": "2006-05-17 09:47:00", "last": "2006-09-22 17:03:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-05-17 09:47:00", "timeframe": "1min"}, "rows": 50000, "sha256": "e3b74dd4386db998d808764d621fdbb47b35f0c19fefe04686bbcf7c31230b3f"}
458 +{"author": "Simon-Pierre Boucher", "cache_key": "ea6c9257afaeec33c9c8b957bf5b5b0b", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/SPY", "fetched_utc": "2026-08-12T06:40:52Z", "first": "2006-09-22 17:03:00", "last": "2007-02-07 16:17:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-09-22 17:03:00", "timeframe": "1min"}, "rows": 50000, "sha256": "5d33c99160ee9e6d81f8179e65e928f2c5c44e2a5a93f9b54200603e6160d596"}
459 +{"author": "Simon-Pierre Boucher", "cache_key": "279a2ce77f79b5e4fcbcc7b94638a9a1", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/SPY", "fetched_utc": "2026-08-12T06:40:54Z", "first": "2007-02-07 16:17:00", "last": "2007-06-11 15:47:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-02-07 16:17:00", "timeframe": "1min"}, "rows": 50000, "sha256": "4b63593727f14db789232a6180cbef717fa99e7275698fdc6a01cb143ffecc5e"}
460 +{"author": "Simon-Pierre Boucher", "cache_key": "1717a055833a55de4d67ff5ed797604c", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/SPY", "fetched_utc": "2026-08-12T06:40:55Z", "first": "2007-06-11 15:47:00", "last": "2007-10-01 08:26:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-06-11 15:47:00", "timeframe": "1min"}, "rows": 50000, "sha256": "168d3f3f0697eaade54947cc42b68e61359a3ee4657bc0f44a7018a904103aff"}
461 +{"author": "Simon-Pierre Boucher", "cache_key": "a6c2cf457b1ae1f5193370b79d9277d7", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/SPY", "fetched_utc": "2026-08-12T06:40:56Z", "first": "2007-10-01 08:26:00", "last": "2007-12-31 19:59:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-10-01 08:26:00", "timeframe": "1min"}, "rows": 41791, "sha256": "926c2740221457464eb7394002256002721516066243e9480e5e27cbd77a4e29"}
462 +{"author": "Simon-Pierre Boucher", "cache_key": "6bee6d677e20807ad2de14148b8fc53e", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AAPL", "fetched_utc": "2026-08-12T06:40:58Z", "first": "2006-01-03 06:37:00", "last": "2006-05-11 16:13:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "0fdba940fe70c7e91831ad07cff7dc934984234ff641e7913c4d06a6437d6fce"}
463 +{"author": "Simon-Pierre Boucher", "cache_key": "4f4185629085a1d2ce387d3b5b6da8aa", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AAPL", "fetched_utc": "2026-08-12T06:41:00Z", "first": "2006-05-11 16:13:00", "last": "2006-09-27 12:47:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-05-11 16:13:00", "timeframe": "1min"}, "rows": 50000, "sha256": "324c77c3babb55382d16bcb51b746eab1f34f9fc46eefb80c699c40ce8a2a1d0"}
464 +{"author": "Simon-Pierre Boucher", "cache_key": "555c92b2d7898f4cbdfa3e5b88cb1850", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AAPL", "fetched_utc": "2026-08-12T06:41:02Z", "first": "2006-09-27 12:47:00", "last": "2007-02-06 12:07:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-09-27 12:47:00", "timeframe": "1min"}, "rows": 50000, "sha256": "2ecf3b9bd4ae2c3037e3a7593023e8899c9066745c3959b78a21e35b5149d3a5"}
465 +{"author": "Simon-Pierre Boucher", "cache_key": "d597dc198c02536c7516122a161ef35a", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AAPL", "fetched_utc": "2026-08-12T06:41:03Z", "first": "2007-02-06 12:07:00", "last": "2007-07-05 15:21:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-02-06 12:07:00", "timeframe": "1min"}, "rows": 50000, "sha256": "595919a1c3c16eb40ca5c07c3bd12bbd65a7faf43e4d50e553920021033084c8"}
466 +{"author": "Simon-Pierre Boucher", "cache_key": "1b3792d403471b5955ff05fbaf5e0577", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AAPL", "fetched_utc": "2026-08-12T06:41:05Z", "first": "2007-07-05 15:21:00", "last": "2007-11-21 18:17:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-07-05 15:21:00", "timeframe": "1min"}, "rows": 50000, "sha256": "73db010df1773a4671703115047703efc1c577ff895ba2772f570a2eab5c78f3"}
467 +{"author": "Simon-Pierre Boucher", "cache_key": "dc7aa90f9fabed719df2cf318a1d3967", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AAPL", "fetched_utc": "2026-08-12T06:41:05Z", "first": "2007-11-21 18:17:00", "last": "2007-12-31 19:59:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-11-21 18:17:00", "timeframe": "1min"}, "rows": 16309, "sha256": "c2b9b5faf7e0a0ca3cb5f0f36a52b950513000a263590d34b6eb88d9b74d9f9b"}
468 +{"author": "Simon-Pierre Boucher", "cache_key": "b7ea8acb1bb5da703eb7ba3378a51b77", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/MSFT", "fetched_utc": "2026-08-12T06:41:07Z", "first": "2006-01-03 07:46:00", "last": "2006-06-05 10:52:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "24983b23aa58427dff523d431f905a5aec651dd96b19a0816051f8d651be6c92"}
469 +{"author": "Simon-Pierre Boucher", "cache_key": "41d7417db5450f0963ef145ee56bc5f1", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/MSFT", "fetched_utc": "2026-08-12T06:41:08Z", "first": "2006-06-05 10:52:00", "last": "2006-11-06 11:57:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-06-05 10:52:00", "timeframe": "1min"}, "rows": 50000, "sha256": "8c5b3f4e45e5fb463f67468b7c4f8f8e583f527489218a3729ccd4863cf169a0"}
470 +{"author": "Simon-Pierre Boucher", "cache_key": "088ed9eb40e20f5593c66aa1f6b86aa1", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/MSFT", "fetched_utc": "2026-08-12T06:41:10Z", "first": "2006-11-06 11:57:00", "last": "2007-04-16 11:53:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-11-06 11:57:00", "timeframe": "1min"}, "rows": 50000, "sha256": "499591b8acb22c718dc2770acabd100c917f5df21398816beadeaf204da949c9"}
471 +{"author": "Simon-Pierre Boucher", "cache_key": "4a5264361afaf5bc43289bc56d1cc13a", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/MSFT", "fetched_utc": "2026-08-12T06:41:11Z", "first": "2007-04-16 11:53:00", "last": "2007-10-10 13:35:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-04-16 11:53:00", "timeframe": "1min"}, "rows": 50000, "sha256": "f4db6f94dae7ac85a942eaebd790e593e487ab2054638e4286f81c31047bb699"}
472 +{"author": "Simon-Pierre Boucher", "cache_key": "081e6efbbf347faeb131a21b7ac3d1b4", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/MSFT", "fetched_utc": "2026-08-12T06:41:12Z", "first": "2007-10-10 13:35:00", "last": "2007-12-31 19:39:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-10-10 13:35:00", "timeframe": "1min"}, "rows": 28465, "sha256": "499263857a72f73e897ce73a2caae96ca44afafa8606d7469822cd8cde78f9a8"}
473 +{"author": "Simon-Pierre Boucher", "cache_key": "c7ac7897f2f0f55372de919ae00fdba6", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/NVDA", "fetched_utc": "2026-08-12T06:41:14Z", "first": "2006-01-03 07:45:00", "last": "2006-06-21 14:47:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "cc37bab45d1d977d555815245533fcf86fece6870f161d0bfd73b2fb79562bce"}
474 +{"author": "Simon-Pierre Boucher", "cache_key": "db58478bba80d6608b1a90622251f3da", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/NVDA", "fetched_utc": "2026-08-12T06:41:16Z", "first": "2006-06-21 14:47:00", "last": "2006-12-05 11:54:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-06-21 14:47:00", "timeframe": "1min"}, "rows": 50000, "sha256": "b031f04326e3f6a4af4098b89f31f54a8e88dff78966eae5dc7dde0cae2132b1"}
475 +{"author": "Simon-Pierre Boucher", "cache_key": "5e862adcffb8960c42d1618c57c48e27", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/NVDA", "fetched_utc": "2026-08-12T06:41:17Z", "first": "2006-12-05 11:54:00", "last": "2007-05-24 14:13:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-12-05 11:54:00", "timeframe": "1min"}, "rows": 50000, "sha256": "45b7ece540a343206d1ceac54f2d788be3608be9fd937370d23ba6c7eda225b4"}
476 +{"author": "Simon-Pierre Boucher", "cache_key": "0b52daf02a9e48723f2ca40ff3173cad", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/NVDA", "fetched_utc": "2026-08-12T06:41:19Z", "first": "2007-05-24 14:13:00", "last": "2007-11-05 09:34:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-05-24 14:13:00", "timeframe": "1min"}, "rows": 50000, "sha256": "d608886447fd3fd6179ab66f543d7673c990fda2f7e6601830f45ff90ba2b4a4"}
477 +{"author": "Simon-Pierre Boucher", "cache_key": "a6ac5edab55bdf5a34e9d55f737ea184", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/NVDA", "fetched_utc": "2026-08-12T06:41:19Z", "first": "2007-11-05 09:34:00", "last": "2007-12-31 18:20:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-11-05 09:34:00", "timeframe": "1min"}, "rows": 16992, "sha256": "d42dbff12e0178dfd900f4064c6d39619e9c68742e3cd35e6962490aa2de7cbe"}
478 +{"author": "Simon-Pierre Boucher", "cache_key": "a5c36893afa6f52dbde09f2a63b21bf3", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AMZN", "fetched_utc": "2026-08-12T06:41:21Z", "first": "2006-01-03 08:01:00", "last": "2006-06-26 10:49:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "88a23dd3f0391471218af88efc6d65b7f9ddb0d65afba9bc574089d1c14a1b8d"}
479 +{"author": "Simon-Pierre Boucher", "cache_key": "d38ee243fc27a420a2b609bfc9bcdcb9", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AMZN", "fetched_utc": "2026-08-12T06:41:23Z", "first": "2006-06-26 10:49:00", "last": "2006-12-14 09:42:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-06-26 10:49:00", "timeframe": "1min"}, "rows": 50000, "sha256": "8f574076d5335e1aca7a381beee194a523ba9291dbb2fae17c1b6a26995b86d5"}
480 +{"author": "Simon-Pierre Boucher", "cache_key": "7cf470b445d17f65036e38cf66a55c8e", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AMZN", "fetched_utc": "2026-08-12T06:41:24Z", "first": "2006-12-14 09:42:00", "last": "2007-05-30 11:46:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-12-14 09:42:00", "timeframe": "1min"}, "rows": 50000, "sha256": "90e8ac7fe51f1236ca5d060787f1a4f3a985bfcaf91bf9bb96b7bb0111ba8f73"}
481 +{"author": "Simon-Pierre Boucher", "cache_key": "4319ff47880759c705c29bf12654a9c7", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AMZN", "fetched_utc": "2026-08-12T06:41:26Z", "first": "2007-05-30 11:46:00", "last": "2007-10-29 10:47:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-05-30 11:46:00", "timeframe": "1min"}, "rows": 50000, "sha256": "d5222e02827d5c6f9f7db1ab4f28f7df4ce7a31c4c6c3030883de923f8754654"}
482 +{"author": "Simon-Pierre Boucher", "cache_key": "8df3b512678bbb85b26a5361a47c327b", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AMZN", "fetched_utc": "2026-08-12T06:41:26Z", "first": "2007-10-29 10:47:00", "last": "2007-12-31 19:26:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-10-29 10:47:00", "timeframe": "1min"}, "rows": 19663, "sha256": "7beca52e18327354afaf4a79abad84537775ce90a9cbce1678af004a04362f3e"}
483 +{"author": "Simon-Pierre Boucher", "cache_key": "5abd2eb4c6a0b9a7f45f5362c88cdfcf", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/GOOGL", "fetched_utc": "2026-08-12T06:41:26Z", "first": null, "last": null, "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 0, "sha256": "8062687d3dbe7963af9b2fa82e28bdbf5ce3aee72af33fa08113f6e5bf11df4e"}
484 +{"author": "Simon-Pierre Boucher", "cache_key": "bbc6102b9588d03e761915f1ca61a40d", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/META", "fetched_utc": "2026-08-12T06:41:27Z", "first": null, "last": null, "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 0, "sha256": "8062687d3dbe7963af9b2fa82e28bdbf5ce3aee72af33fa08113f6e5bf11df4e"}
485 +{"author": "Simon-Pierre Boucher", "cache_key": "a5849e2aa40cc160c585ad3beb7ba74c", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/TSLA", "fetched_utc": "2026-08-12T06:41:27Z", "first": null, "last": null, "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 0, "sha256": "8062687d3dbe7963af9b2fa82e28bdbf5ce3aee72af33fa08113f6e5bf11df4e"}
486 +{"author": "Simon-Pierre Boucher", "cache_key": "ae3a4adcedbf7f599b6d0ffddea25e54", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/JPM", "fetched_utc": "2026-08-12T06:41:29Z", "first": "2006-01-03 08:01:00", "last": "2006-07-03 10:51:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "f7d46d61d835e2a489f167f3de0318612e3b5d2559f06b3a0079e507b009b4cc"}
487 +{"author": "Simon-Pierre Boucher", "cache_key": "d315216f427be860cbef5eb2b5674d7f", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/JPM", "fetched_utc": "2026-08-12T06:41:30Z", "first": "2006-07-03 10:51:00", "last": "2007-01-03 15:40:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-07-03 10:51:00", "timeframe": "1min"}, "rows": 50000, "sha256": "47b4804520f34dbc72463db913f2f77cbd57f8bd56c15f8d403326c063382f01"}
488 +{"author": "Simon-Pierre Boucher", "cache_key": "86a26391669dd855175016f1890659d4", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/JPM", "fetched_utc": "2026-08-12T06:41:32Z", "first": "2007-01-03 15:40:00", "last": "2007-07-05 15:37:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-01-03 15:40:00", "timeframe": "1min"}, "rows": 50000, "sha256": "a682ee0ed239547c64063fc970b6178a708a84debf5f60aee23dc54577bc85ce"}
489 +{"author": "Simon-Pierre Boucher", "cache_key": "a84917b4e50c6e46ed008748ef97d8cb", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/JPM", "fetched_utc": "2026-08-12T06:41:33Z", "first": "2007-07-05 15:37:00", "last": "2007-12-28 14:19:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-07-05 15:37:00", "timeframe": "1min"}, "rows": 50000, "sha256": "99a4eb0f23861f31951b2128708841a79d6fa42850e8cd53fbe00241a3b2fc04"}
490 +{"author": "Simon-Pierre Boucher", "cache_key": "cb583da82b1413ff0400779b7e32285d", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/JPM", "fetched_utc": "2026-08-12T06:41:33Z", "first": "2007-12-28 14:19:00", "last": "2007-12-31 18:26:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-12-28 14:19:00", "timeframe": "1min"}, "rows": 529, "sha256": "4fa48f3fc4d2f469c537af30fb54df4fe03d7ce651c98805e15e032d32daa6ec"}
491 +{"author": "Simon-Pierre Boucher", "cache_key": "6bca93d491007dde5a72a08ec0445d73", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/XOM", "fetched_utc": "2026-08-12T06:41:35Z", "first": "2006-01-03 07:54:00", "last": "2006-06-22 10:53:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "4912251433e1f130a8e0b1e447bf36159412322e30c5d8f7dfed6b7a046ddc8a"}
492 +{"author": "Simon-Pierre Boucher", "cache_key": "bb131804d096c28d266922e56c817b0d", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/XOM", "fetched_utc": "2026-08-12T06:41:36Z", "first": "2006-06-22 10:53:00", "last": "2006-12-07 15:14:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-06-22 10:53:00", "timeframe": "1min"}, "rows": 50000, "sha256": "86c14aa49657f4e256fe9cfef3d1d28860ffdf6011ac80b5035f6ee41394cb1e"}
493 +{"author": "Simon-Pierre Boucher", "cache_key": "25904aa6f0d9dc4219a9d6e5c64b9dae", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/XOM", "fetched_utc": "2026-08-12T06:41:38Z", "first": "2006-12-07 15:14:00", "last": "2007-06-01 14:48:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-12-07 15:14:00", "timeframe": "1min"}, "rows": 50000, "sha256": "6dd8c190832bf574f8506f5b6393e33bcd183bff8932a96dc64747bdc7530dc2"}
494 +{"author": "Simon-Pierre Boucher", "cache_key": "7da17ad911738b4b5cf9157372344c4f", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/XOM", "fetched_utc": "2026-08-12T06:41:40Z", "first": "2007-06-01 14:48:00", "last": "2007-11-26 13:27:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-06-01 14:48:00", "timeframe": "1min"}, "rows": 50000, "sha256": "7ed1cc8f6b78cf828afcaa75ef4fff17f64c3801803383dba9c1843e96677839"}
495 +{"author": "Simon-Pierre Boucher", "cache_key": "57d1c161736cac9191e223f2918fb377", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/XOM", "fetched_utc": "2026-08-12T06:41:40Z", "first": "2007-11-26 13:27:00", "last": "2007-12-31 19:17:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-11-26 13:27:00", "timeframe": "1min"}, "rows": 10253, "sha256": "7fdae9872a40bbf46eb3d0b3777ebacfabb2bd2b45cec7d95c4996f9e87756d7"}
496 +{"author": "Simon-Pierre Boucher", "cache_key": "3da49ae8550dd44d35352b9faa992100", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/UNH", "fetched_utc": "2026-08-12T06:41:42Z", "first": "2006-01-03 08:01:00", "last": "2006-06-27 10:50:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "d65be383a62a0ca724044845fe53259043ea3f1a38e61279f2bf26f787c2baec"}
497 +{"author": "Simon-Pierre Boucher", "cache_key": "54d3bf609b3088f974ccb4a547dff456", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/UNH", "fetched_utc": "2026-08-12T06:41:43Z", "first": "2006-06-27 10:50:00", "last": "2006-12-26 11:47:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-06-27 10:50:00", "timeframe": "1min"}, "rows": 50000, "sha256": "b98fdcb95151f6c744ab89ff52b40b4d46a286013f356dd04ddd965e0ed6c088"}
498 +{"author": "Simon-Pierre Boucher", "cache_key": "25d624fb5657df9098411f0cafd0eb4c", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/UNH", "fetched_utc": "2026-08-12T06:41:45Z", "first": "2006-12-26 11:47:00", "last": "2007-06-27 15:58:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-12-26 11:47:00", "timeframe": "1min"}, "rows": 50000, "sha256": "752e4503ca602cff25508317db5fa5abaeb5defd3188c71e396f14729f8c29de"}
499 +{"author": "Simon-Pierre Boucher", "cache_key": "f4c40ca6fdf74ed250a97851326acd54", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/UNH", "fetched_utc": "2026-08-12T06:41:46Z", "first": "2007-06-27 15:58:00", "last": "2007-12-27 09:50:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-06-27 15:58:00", "timeframe": "1min"}, "rows": 50000, "sha256": "d6953a1e2642fea3a058317a64d1220e992291f384700d07b282858e5af57256"}
500 +{"author": "Simon-Pierre Boucher", "cache_key": "d59b0c5c1c2902e672125fa51ed8c761", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/UNH", "fetched_utc": "2026-08-12T06:41:46Z", "first": "2007-12-27 09:50:00", "last": "2007-12-31 18:20:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-12-27 09:50:00", "timeframe": "1min"}, "rows": 1181, "sha256": "164c92fb9782170522187a9a950bc7de08b956d38077e3158e5e8142cb7b0efc"}
501 +{"author": "Simon-Pierre Boucher", "cache_key": "5499649933c7a6d4979260d37c2f6b1f", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/QQQ", "fetched_utc": "2026-08-12T06:41:48Z", "first": "2006-01-03 09:30:00", "last": "2006-07-07 13:49:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "1ed0776a0c12bc2df17b9903eadb360413259acdf3aadb76d20c7d27f0cffa05"}
502 +{"author": "Simon-Pierre Boucher", "cache_key": "1b6b3f2143f9f15720955957438ad16f", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/QQQ", "fetched_utc": "2026-08-12T06:41:50Z", "first": "2006-07-07 13:49:00", "last": "2007-01-09 10:31:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-07-07 13:49:00", "timeframe": "1min"}, "rows": 50000, "sha256": "5d74180ee69d7189da770daaad23e8e51491e18baabde3669f24affe4adb29f0"}
503 +{"author": "Simon-Pierre Boucher", "cache_key": "78de82bdd41326dbf0e4eed7250f5a62", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/QQQ", "fetched_utc": "2026-08-12T06:41:51Z", "first": "2007-01-09 10:31:00", "last": "2007-05-10 14:53:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-01-09 10:31:00", "timeframe": "1min"}, "rows": 50000, "sha256": "9e8c8f3402252ee3058b2245393a013c36b0828cd4a3b9e46a957876c9698330"}
504 +{"author": "Simon-Pierre Boucher", "cache_key": "2ec18e0da3f1a64fc3fda30b0c2b262a", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/QQQ", "fetched_utc": "2026-08-12T06:41:53Z", "first": "2007-05-10 14:53:00", "last": "2007-09-11 08:54:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-05-10 14:53:00", "timeframe": "1min"}, "rows": 50000, "sha256": "65537e4ef8e6121b6eb415eb4eaea2a6005a795844eba10fc14eb00318660096"}
505 +{"author": "Simon-Pierre Boucher", "cache_key": "9bd5d628ec9983faaa37ac0f4fbbb2e0", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/QQQ", "fetched_utc": "2026-08-12T06:41:54Z", "first": "2007-09-11 08:54:00", "last": "2007-12-31 19:59:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-09-11 08:54:00", "timeframe": "1min"}, "rows": 47885, "sha256": "d963b881e4a896ad12091b4bcf164609b0709561436f2796f9be9b006ced06c6"}
506 +{"author": "Simon-Pierre Boucher", "cache_key": "3bb400f3e92e01139c067a6b9e4137b4", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLF", "fetched_utc": "2026-08-12T06:41:56Z", "first": "2006-01-03 08:00:00", "last": "2006-07-21 10:09:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "8fd6c86b4f7de45dea879b1a538d136da1c1ed1dd7445d9fe56b8c0902fe0109"}
507 +{"author": "Simon-Pierre Boucher", "cache_key": "8f2289e8c45c288ff44390d8b96c8597", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLF", "fetched_utc": "2026-08-12T06:41:57Z", "first": "2006-07-21 10:09:00", "last": "2007-02-05 13:24:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-07-21 10:09:00", "timeframe": "1min"}, "rows": 50000, "sha256": "eec6b79ea533262016c0bdfbfc19e2fcd2a06b8fbc021f9bce046ef40757d876"}
508 +{"author": "Simon-Pierre Boucher", "cache_key": "024e38a83c18b6e06a636f8c20bb31ed", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLF", "fetched_utc": "2026-08-12T06:41:59Z", "first": "2007-02-05 13:24:00", "last": "2007-08-09 14:44:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-02-05 13:24:00", "timeframe": "1min"}, "rows": 50000, "sha256": "a50ed772a3ec40478d75f7f4b75739d3fb41280bbfcf02be8a6bc586955fe5d3"}
509 +{"author": "Simon-Pierre Boucher", "cache_key": "bc19da40b7bf45695890dda19339b35c", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLF", "fetched_utc": "2026-08-12T06:42:00Z", "first": "2007-08-09 14:44:00", "last": "2007-12-31 19:33:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-08-09 14:44:00", "timeframe": "1min"}, "rows": 42419, "sha256": "660b0680584f6bfd61e9cdf2b02690d659f2c03cce9bca1f8a91556a21bd12e4"}
510 +{"author": "Simon-Pierre Boucher", "cache_key": "0bbe6de5ae5b62ab9a45bffaf606f0ad", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLE", "fetched_utc": "2026-08-12T06:42:02Z", "first": "2006-01-03 08:00:00", "last": "2006-06-26 10:02:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "d9505e19de6ee360da60fd6d1fa56e2cd00ef44c286d93902102029481aa65ce"}
511 +{"author": "Simon-Pierre Boucher", "cache_key": "9a0cfb63832affcd1a7e6c4f78e03ad0", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLE", "fetched_utc": "2026-08-12T06:42:04Z", "first": "2006-06-26 10:02:00", "last": "2006-12-15 14:50:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-06-26 10:02:00", "timeframe": "1min"}, "rows": 50000, "sha256": "bb4f51f56651bc3bcfe8ca0db3501d367949371d7d103fa37ca8ed8a26a26617"}
512 +{"author": "Simon-Pierre Boucher", "cache_key": "375c2d72ecdeb69dd483b14c90c368dc", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLE", "fetched_utc": "2026-08-12T06:42:05Z", "first": "2006-12-15 14:50:00", "last": "2007-06-13 11:10:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-12-15 14:50:00", "timeframe": "1min"}, "rows": 50000, "sha256": "a27e19a347730d047e4336985371a93b75518f03d4e71abef54235ecfe5aee4f"}
513 +{"author": "Simon-Pierre Boucher", "cache_key": "656ba3b7ce939125c2588bd0642780e2", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLE", "fetched_utc": "2026-08-12T06:42:07Z", "first": "2007-06-13 11:10:00", "last": "2007-12-04 13:05:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-06-13 11:10:00", "timeframe": "1min"}, "rows": 50000, "sha256": "8153d02162cc9610935ac6d5a70c8707ab79b0c8ab418d3b6a608aff9d74b7f4"}
514 +{"author": "Simon-Pierre Boucher", "cache_key": "70602e62697475784d96813b38fb7add", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLE", "fetched_utc": "2026-08-12T06:42:07Z", "first": "2007-12-04 13:05:00", "last": "2007-12-31 16:45:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-12-04 13:05:00", "timeframe": "1min"}, "rows": 7425, "sha256": "b52bd5174a51155ed8a412eb49e9ab3a5efd0ef43967916fbea03f96a63d4ef9"}
515 +{"author": "Simon-Pierre Boucher", "cache_key": "054dc366190be4ba28796f183c2f0ef7", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLK", "fetched_utc": "2026-08-12T06:42:09Z", "first": "2006-01-03 09:32:00", "last": "2006-08-17 13:10:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "7bd7efdfb66d4b20fd114e1d5007a8d674da09db2742f7a4a8e65fc7d0c51d1f"}
516 +{"author": "Simon-Pierre Boucher", "cache_key": "44d32c6b42a05b098ab0cfd8cd9927a6", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLK", "fetched_utc": "2026-08-12T06:42:10Z", "first": "2006-08-17 13:10:00", "last": "2007-03-19 15:05:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-08-17 13:10:00", "timeframe": "1min"}, "rows": 50000, "sha256": "d4aefb18e824570bb99d793d416a2694c9e2950aed50b851f49b9409af31cb82"}
517 +{"author": "Simon-Pierre Boucher", "cache_key": "6df0cecadcab46e57100549727098ca6", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLK", "fetched_utc": "2026-08-12T06:42:11Z", "first": "2007-03-19 15:05:00", "last": "2007-10-10 10:52:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-03-19 15:05:00", "timeframe": "1min"}, "rows": 50000, "sha256": "33aff5e7151cbb66d885f25ca3142ad020fc0d9d63703d224ebe4f723d9cd565"}
518 +{"author": "Simon-Pierre Boucher", "cache_key": "2d210448163ccb150c7d0426b7fedbe6", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLK", "fetched_utc": "2026-08-12T06:42:12Z", "first": "2007-10-10 10:52:00", "last": "2007-12-31 17:09:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-10-10 10:52:00", "timeframe": "1min"}, "rows": 21342, "sha256": "9a463bd4dcd1f8d40be1235d469945b003de3fdcfdd014c7c9f9d0df09f9b716"}
519 +{"author": "Simon-Pierre Boucher", "cache_key": "8c81cd702622400f0ed5d49660b98866", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLV", "fetched_utc": "2026-08-12T06:42:14Z", "first": "2006-01-03 09:30:00", "last": "2006-08-31 10:57:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "052fac0eaa21ecde6e1070dfb682c589420ac18d4c56a375d9f17c6674d124a5"}
520 +{"author": "Simon-Pierre Boucher", "cache_key": "a2bd104bdd7750f1d0bc74521c28003c", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLV", "fetched_utc": "2026-08-12T06:42:15Z", "first": "2006-08-31 10:57:00", "last": "2007-04-19 12:11:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-08-31 10:57:00", "timeframe": "1min"}, "rows": 50000, "sha256": "a22df587ca4fa62b686c054e264b616444508437238428a019c4945f6b2546d5"}
521 +{"author": "Simon-Pierre Boucher", "cache_key": "9c516ef5e942c802167bbe9b5fa607a6", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLV", "fetched_utc": "2026-08-12T06:42:17Z", "first": "2007-04-19 12:11:00", "last": "2007-11-13 15:15:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-04-19 12:11:00", "timeframe": "1min"}, "rows": 50000, "sha256": "789020be9c88934c20422e0e4b5898d381f12045d317b2d3535687c02af392b7"}
522 +{"author": "Simon-Pierre Boucher", "cache_key": "f0139bad8b5389c83dbbc185182fddca", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLV", "fetched_utc": "2026-08-12T06:42:17Z", "first": "2007-11-13 15:15:00", "last": "2007-12-31 16:17:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-11-13 15:15:00", "timeframe": "1min"}, "rows": 11432, "sha256": "fcbbfb2bccb6ea97289f350fa62edc48a570517394cda566a47ce6ceca6718f8"}
523 +{"author": "Simon-Pierre Boucher", "cache_key": "e3e741e9c9462e4ca1d93a24bc9c02db", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLI", "fetched_utc": "2026-08-12T06:42:19Z", "first": "2006-01-03 09:30:00", "last": "2006-09-26 12:40:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "47819cacc3b60270d944f86a3b94b955017d63408ba5a29b6e6ca2bd8b85b543"}
524 +{"author": "Simon-Pierre Boucher", "cache_key": "f9fa512fea804be4ff463c50fb450c7f", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLI", "fetched_utc": "2026-08-12T06:42:20Z", "first": "2006-09-26 12:40:00", "last": "2007-05-17 11:19:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-09-26 12:40:00", "timeframe": "1min"}, "rows": 50000, "sha256": "169420cc843c14fe668f40f8437b0603ff30d9e11c84e549578fcd941e27ae30"}
525 +{"author": "Simon-Pierre Boucher", "cache_key": "e371a38df13cc46483a4200d29c59a17", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLI", "fetched_utc": "2026-08-12T06:42:22Z", "first": "2007-05-17 11:19:00", "last": "2007-11-29 15:58:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-05-17 11:19:00", "timeframe": "1min"}, "rows": 50000, "sha256": "673170df9f3db38718f9e708a55d9447e95efcb6924b847d33cad8bb2a9dd747"}
526 +{"author": "Simon-Pierre Boucher", "cache_key": "347c04f8f48bc69dcbd58cf5c770e462", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLI", "fetched_utc": "2026-08-12T06:42:22Z", "first": "2007-11-29 15:58:00", "last": "2007-12-31 16:15:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-11-29 15:58:00", "timeframe": "1min"}, "rows": 7603, "sha256": "8caa528909bc7dddb660bb952beeea7b861636d0522a7f12737e3f8fb0c2becc"}
527 +{"author": "Simon-Pierre Boucher", "cache_key": "e05400abc3571e674ca92395d0264f8b", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLY", "fetched_utc": "2026-08-12T06:42:25Z", "first": "2006-01-03 09:32:00", "last": "2006-11-02 11:17:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "7a1e7714b7cae616b50c469541ee4224db28757263a3078fb386bdfb377e18b8"}
528 +{"author": "Simon-Pierre Boucher", "cache_key": "02ab004a7bc364b6f370e8e0a161c553", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLY", "fetched_utc": "2026-08-12T06:42:27Z", "first": "2006-11-02 11:17:00", "last": "2007-06-26 14:33:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-11-02 11:17:00", "timeframe": "1min"}, "rows": 50000, "sha256": "b879f52f67584c5f99316243c1698078e8dfc7fbc413079c745cbce26310445e"}
529 +{"author": "Simon-Pierre Boucher", "cache_key": "62879d85cdcedc82dbb349c46a035d49", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLY", "fetched_utc": "2026-08-12T06:42:29Z", "first": "2007-06-26 14:33:00", "last": "2007-12-31 16:18:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-06-26 14:33:00", "timeframe": "1min"}, "rows": 47248, "sha256": "1c786b1a200854a12dd351bf70b271cdc0adc8f96ff404c825f361f4c4b8e445"}
530 +{"author": "Simon-Pierre Boucher", "cache_key": "aa4a6ee020e1fcbb9d06b24133fec018", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLP", "fetched_utc": "2026-08-12T06:42:31Z", "first": "2006-01-03 09:31:00", "last": "2006-09-20 13:38:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "62dff467d5cbe5a865557f442dba88c23d1649b5bf9ad31f8b1e9eba9ceb8089"}
531 +{"author": "Simon-Pierre Boucher", "cache_key": "248761050b0745a97d295d84fffe7145", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLP", "fetched_utc": "2026-08-12T06:42:33Z", "first": "2006-09-20 13:38:00", "last": "2007-05-30 10:05:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-09-20 13:38:00", "timeframe": "1min"}, "rows": 50000, "sha256": "cd4bff832c8bd2f288b0cc56185979b16b57c6e05a7024b4f2d9f243cb744b18"}
532 +{"author": "Simon-Pierre Boucher", "cache_key": "19105ede13b8ac060e49962776eabbd5", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLP", "fetched_utc": "2026-08-12T06:42:34Z", "first": "2007-05-30 10:05:00", "last": "2007-12-28 13:24:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-05-30 10:05:00", "timeframe": "1min"}, "rows": 50000, "sha256": "ad1fa12159e2c4bf81e69d8a9f7a42a54854aa5fcc81edd6029a2acbd8836514"}
533 +{"author": "Simon-Pierre Boucher", "cache_key": "7058656e9fc48ceac51444b526e8ae55", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLP", "fetched_utc": "2026-08-12T06:42:35Z", "first": "2007-12-28 13:24:00", "last": "2007-12-31 16:16:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-12-28 13:24:00", "timeframe": "1min"}, "rows": 457, "sha256": "fb49e71fa73e849ee63657bc80958f25711e03c357be3ab3afc4d257b1d9bee9"}
534 +{"author": "Simon-Pierre Boucher", "cache_key": "62f355dc385cc1a3c71e8f1c5c123f93", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLU", "fetched_utc": "2026-08-12T06:42:36Z", "first": "2006-01-03 09:31:00", "last": "2006-07-28 11:52:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "88e941641e67ad4bac0be0c825f2decb862a516236f4bed7d393dc239118d639"}
535 +{"author": "Simon-Pierre Boucher", "cache_key": "06f2ccd6962d63c4d1009c00dd2af58a", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLU", "fetched_utc": "2026-08-12T06:42:38Z", "first": "2006-07-28 11:52:00", "last": "2007-02-23 15:19:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-07-28 11:52:00", "timeframe": "1min"}, "rows": 50000, "sha256": "020e64d10855a11eac03768d8e761b0afc8f3079b40390440c43e3249d048d63"}
536 +{"author": "Simon-Pierre Boucher", "cache_key": "58e1245bea5e9a437a0312e9e3448a63", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLU", "fetched_utc": "2026-08-12T06:42:40Z", "first": "2007-02-23 15:19:00", "last": "2007-09-04 14:48:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-02-23 15:19:00", "timeframe": "1min"}, "rows": 50000, "sha256": "82ec57908bda642f0a8589c7efb93c48b93fb1a3480fd05de527735cc9e668b9"}
537 +{"author": "Simon-Pierre Boucher", "cache_key": "83159d404d938bde37dbd4fd89f2d897", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLU", "fetched_utc": "2026-08-12T06:42:41Z", "first": "2007-09-04 14:48:00", "last": "2007-12-31 16:15:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-09-04 14:48:00", "timeframe": "1min"}, "rows": 31059, "sha256": "78fe3bb43c9be18f788d630eeeda354bc4f461a55eb59fb2d0c80f0a2b0c1d3a"}
538 +{"author": "Simon-Pierre Boucher", "cache_key": "5d74f470feade6310040154463139f95", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLB", "fetched_utc": "2026-08-12T06:42:42Z", "first": "2006-01-03 09:30:00", "last": "2006-08-07 13:40:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "8ad2e4f04f9ae9504e5ef6703ad183634df36eb7c2cddbe5afc4f4e60686dcf7"}
539 +{"author": "Simon-Pierre Boucher", "cache_key": "9e403bf15089c1305160daa48ea0e511", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLB", "fetched_utc": "2026-08-12T06:42:44Z", "first": "2006-08-07 13:40:00", "last": "2007-03-08 12:56:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-08-07 13:40:00", "timeframe": "1min"}, "rows": 50000, "sha256": "9e37a8cfb175e7df098c1880e718a27f2471b859ef63cfee5a8a28fa82eb68df"}
540 +{"author": "Simon-Pierre Boucher", "cache_key": "435a38c80497d6c0209d1988b4fb05a0", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLB", "fetched_utc": "2026-08-12T06:42:45Z", "first": "2007-03-08 12:56:00", "last": "2007-09-21 14:59:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-03-08 12:56:00", "timeframe": "1min"}, "rows": 50000, "sha256": "5c7743b0c6a1ee5573613a70e98e85b199ce379d294476e31154efb1c635fcaf"}
541 +{"author": "Simon-Pierre Boucher", "cache_key": "c5d653f9b28a804797bf476ae9de7539", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLB", "fetched_utc": "2026-08-12T06:42:46Z", "first": "2007-09-21 14:59:00", "last": "2007-12-31 16:16:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-09-21 14:59:00", "timeframe": "1min"}, "rows": 26528, "sha256": "5089a30458c9710dee272d7f5e2edad0c47b05b19bf179dcdf5bb45bdef551e6"}
542 +{"author": "Simon-Pierre Boucher", "cache_key": "6ce76d7f382c3722ba35efc78052887f", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/ATRO", "fetched_utc": "2026-08-12T06:42:47Z", "first": "2006-01-03 10:33:00", "last": "2007-12-31 16:00:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 28104, "sha256": "bbe0fcee1f282e2558f3dd8258892a6a41b9517481cdc6c997b86f11fec95460"}
543 +{"author": "Simon-Pierre Boucher", "cache_key": "5e6a15e2728853b9875c0faf3dc70906", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AUVI", "fetched_utc": "2026-08-12T06:42:47Z", "first": null, "last": null, "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 0, "sha256": "8062687d3dbe7963af9b2fa82e28bdbf5ce3aee72af33fa08113f6e5bf11df4e"}
544 +{"author": "Simon-Pierre Boucher", "cache_key": "b66a3b66d0cba96dc32eb93e618881e0", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AXDX", "fetched_utc": "2026-08-12T06:42:47Z", "first": "2006-01-03 11:09:00", "last": "2007-12-31 15:59:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 3652, "sha256": "75304c94b90b7b3f13a8dacd8c28be076fb7ba2245e002efb2c71e1f9e77cb1f"}
545 +{"author": "Simon-Pierre Boucher", "cache_key": "3b5f8ab415d1e2701cf6251e1aa00f51", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/BKE", "fetched_utc": "2026-08-12T06:42:50Z", "first": "2006-01-03 09:33:00", "last": "2007-03-30 14:15:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "2d9105033e4b2a4ab37ca90e582602a27115e579c6a1a06c59876659c23982b5"}
546 +{"author": "Simon-Pierre Boucher", "cache_key": "40edf1d63d65dcee907313a50396ed63", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/BKE", "fetched_utc": "2026-08-12T06:42:52Z", "first": "2007-03-30 14:15:00", "last": "2007-12-31 16:02:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-03-30 14:15:00", "timeframe": "1min"}, "rows": 48435, "sha256": "b5b4ae1ef889a4e85f9194f63132619a8526d053919489ab38439d4b32f60e47"}
547 +{"author": "Simon-Pierre Boucher", "cache_key": "ec478992329c5f54d2a5b5a7ae7ace51", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/CECO", "fetched_utc": "2026-08-12T06:42:53Z", "first": "2007-05-16 09:30:00", "last": "2007-12-31 16:22:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 29309, "sha256": "fb41c5a96fb5eb89ae6d8adb773981f987fe7a912ea25692032f954fac2670c8"}
548 +{"author": "Simon-Pierre Boucher", "cache_key": "abf761eaab101db4cf49cdfefa2b40d1", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/CKX", "fetched_utc": "2026-08-12T06:42:53Z", "first": "2006-01-03 09:30:00", "last": "2007-12-31 15:50:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 1868, "sha256": "612bf1a93ba0aebf0c3180eaa6218399233913d18220f8f8c268b8714bc42662"}
549 +{"author": "Simon-Pierre Boucher", "cache_key": "e6b410ee962e281b6381e4d94ff49ac8", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/GCL", "fetched_utc": "2026-08-12T06:42:53Z", "first": null, "last": null, "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 0, "sha256": "8062687d3dbe7963af9b2fa82e28bdbf5ce3aee72af33fa08113f6e5bf11df4e"}
550 +{"author": "Simon-Pierre Boucher", "cache_key": "25141c1d2190f94f1fba535107ec8a66", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/GRO", "fetched_utc": "2026-08-12T06:42:53Z", "first": null, "last": null, "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 0, "sha256": "8062687d3dbe7963af9b2fa82e28bdbf5ce3aee72af33fa08113f6e5bf11df4e"}
551 +{"author": "Simon-Pierre Boucher", "cache_key": "bfef38a5be61792ebeeace8b27274076", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/HPE", "fetched_utc": "2026-08-12T06:42:54Z", "first": null, "last": null, "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 0, "sha256": "8062687d3dbe7963af9b2fa82e28bdbf5ce3aee72af33fa08113f6e5bf11df4e"}
552 +{"author": "Simon-Pierre Boucher", "cache_key": "dbff9dd476e12b53e7c1f845d84de702", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/HTD", "fetched_utc": "2026-08-12T06:42:55Z", "first": "2006-01-03 09:31:00", "last": "2007-10-26 10:31:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2006-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "4731a3978aacaf28e47f0ca53611485d5dfdd6e06ac2dd198793b0a30047c2bf"}
553 +{"author": "Simon-Pierre Boucher", "cache_key": "c9bba03a9383ed7f5eb50d2624221219", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/HTD", "fetched_utc": "2026-08-12T06:42:56Z", "first": "2007-10-26 10:31:00", "last": "2007-12-31 16:04:00", "params": {"adjustment": "adj_split", "end": "2008-01-01", "limit": 50000, "order": "asc", "start": "2007-10-26 10:31:00", "timeframe": "1min"}, "rows": 5221, "sha256": "848f367dbddaede54eb32cc0fb4901fb24f00f92ec5a7e18935e9d61f08d19f7"}
554 +{"author": "Simon-Pierre Boucher", "cache_key": "f9450c8f366b59bb3ff1b99e06dba5fb", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/index/SPX", "fetched_utc": "2026-08-12T06:43:24Z", "first": "2014-01-02 09:30:00", "last": "2014-07-03 11:55:00", "params": {"end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "f90e210f95843ad1dec563ee0b8a767e49193cfa37908514c12374661f293b53"}
555 +{"author": "Simon-Pierre Boucher", "cache_key": "a75410cb228b4fad4d8012ef7884c5e6", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/index/SPX", "fetched_utc": "2026-08-12T06:43:25Z", "first": "2014-07-03 11:55:00", "last": "2015-01-05 14:55:00", "params": {"end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-03 11:55:00", "timeframe": "1min"}, "rows": 50000, "sha256": "aac1c482bdeaede97de33d74e272a1a01ffe171d36192278232f042cffd1d783"}
556 +{"author": "Simon-Pierre Boucher", "cache_key": "38b7b2f518639177ea3a56d88e535bdf", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/index/SPX", "fetched_utc": "2026-08-12T06:43:27Z", "first": "2015-01-05 14:55:00", "last": "2015-07-07 15:27:00", "params": {"end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-05 14:55:00", "timeframe": "1min"}, "rows": 50000, "sha256": "b1026df87545a2518b3c69a07eb380fa2aa63c7ac50a7aefb09f10cb4ecbbbc4"}
557 +{"author": "Simon-Pierre Boucher", "cache_key": "867458ac1d12e8d92f247f5595d23710", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/index/SPX", "fetched_utc": "2026-08-12T06:43:28Z", "first": "2015-07-07 15:27:00", "last": "2015-12-31 16:06:00", "params": {"end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-07 15:27:00", "timeframe": "1min"}, "rows": 48890, "sha256": "3379f550409ba75e04848e83523990a48792316cb366006cd10f633d746c84cb"}
558 +{"author": "Simon-Pierre Boucher", "cache_key": "1bdaf69aa9af966cbe114269ecf05c01", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLF", "fetched_utc": "2026-08-12T06:43:33Z", "first": "2014-01-02 08:00:00", "last": "2014-06-20 09:54:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "b35c0446461ff825af89d62511d01fc35d30d6195a10b01037a13560409281b2"}
559 +{"author": "Simon-Pierre Boucher", "cache_key": "a4d6a3133192d724f0e3c9eb9b6e3e7c", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLF", "fetched_utc": "2026-08-12T06:43:35Z", "first": "2014-06-20 09:54:00", "last": "2014-12-11 10:58:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-06-20 09:54:00", "timeframe": "1min"}, "rows": 50000, "sha256": "919d99b72b73c87bb30bcd1cd249ad51ec7ed740bcd2e042fc1fd977395dca9b"}
560 +{"author": "Simon-Pierre Boucher", "cache_key": "55163bec5b9357fc09e5eec003b87d88", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLF", "fetched_utc": "2026-08-12T06:43:36Z", "first": "2014-12-11 10:58:00", "last": "2015-06-05 14:51:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-12-11 10:58:00", "timeframe": "1min"}, "rows": 50000, "sha256": "dc3ebc24f08264d77dd9cc47e8af540d8c6def266a58d3424b5fcf0c3e7fb870"}
561 +{"author": "Simon-Pierre Boucher", "cache_key": "cdded14766d7167d1077a427995cb0ba", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLF", "fetched_utc": "2026-08-12T06:43:38Z", "first": "2015-06-05 14:51:00", "last": "2015-11-20 12:48:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-06-05 14:51:00", "timeframe": "1min"}, "rows": 50000, "sha256": "efab85a462bcc906bebe294f9893bfc8259927e131c4365499ea3a102473d077"}
562 +{"author": "Simon-Pierre Boucher", "cache_key": "2c3b6ce683abae205a4043ba519d1763", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLF", "fetched_utc": "2026-08-12T06:43:38Z", "first": "2015-11-20 12:48:00", "last": "2015-12-31 19:54:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-11-20 12:48:00", "timeframe": "1min"}, "rows": 11260, "sha256": "e1ced423116b009c49ecf4d9cfcc07f5ecdbfda178d3970ba5158bb663686952"}
563 +{"author": "Simon-Pierre Boucher", "cache_key": "3c32aa4da1ac917bd54a2eb593ff159f", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLE", "fetched_utc": "2026-08-12T06:43:40Z", "first": "2014-01-02 08:01:00", "last": "2014-06-27 13:20:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "9af037085a4b071b67283717d1885f24e86c538f821842db23ff68e54ba2fdab"}
564 +{"author": "Simon-Pierre Boucher", "cache_key": "1a168d5c8b587ee8257d696a21052c70", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLE", "fetched_utc": "2026-08-12T06:43:41Z", "first": "2014-06-27 13:20:00", "last": "2014-12-15 13:52:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-06-27 13:20:00", "timeframe": "1min"}, "rows": 50000, "sha256": "383c58acdcfe137f1a10b37e43fffab095c542bfc7646b04f0d96a6d69ab8454"}
565 +{"author": "Simon-Pierre Boucher", "cache_key": "87fab6e4107581545a1728ce1af944cf", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLE", "fetched_utc": "2026-08-12T06:43:43Z", "first": "2014-12-15 13:52:00", "last": "2015-05-27 10:58:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-12-15 13:52:00", "timeframe": "1min"}, "rows": 50000, "sha256": "a361722cac0a8b7ac0505d666391c1f0ecf9f9b867f35e332a53bc5794991349"}
566 +{"author": "Simon-Pierre Boucher", "cache_key": "cca10e74c5195dc58250485644001665", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLE", "fetched_utc": "2026-08-12T06:43:44Z", "first": "2015-05-27 10:58:00", "last": "2015-11-04 11:29:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-05-27 10:58:00", "timeframe": "1min"}, "rows": 50000, "sha256": "58a3a2421919fbb7c86c668af30e21a7e5f07b46333a936f306618e7a677ade2"}
567 +{"author": "Simon-Pierre Boucher", "cache_key": "452962ebf1fa9faba1345a5d361b5ed9", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLE", "fetched_utc": "2026-08-12T06:43:45Z", "first": "2015-11-04 11:29:00", "last": "2015-12-31 19:46:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-11-04 11:29:00", "timeframe": "1min"}, "rows": 17943, "sha256": "d6d91d7aef0406f18574cd3efc899f8793b64cbfcfd3556aa60787a1f4e17a63"}
568 +{"author": "Simon-Pierre Boucher", "cache_key": "dc5c93999957ccab0c7dca71545d3277", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLK", "fetched_utc": "2026-08-12T06:43:46Z", "first": "2014-01-02 08:00:00", "last": "2014-07-07 12:36:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "41f15cce96c7aab42762f2891920944bf943cacd5af5751024cc0e059990421a"}
569 +{"author": "Simon-Pierre Boucher", "cache_key": "46301a169739c9a08e155a211b791aec", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLK", "fetched_utc": "2026-08-12T06:43:48Z", "first": "2014-07-07 12:36:00", "last": "2015-01-07 10:40:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-07 12:36:00", "timeframe": "1min"}, "rows": 50000, "sha256": "b1133f2487af222419e9b5826f05510a59e554f48c86b42b21137c74ba6968a9"}
570 +{"author": "Simon-Pierre Boucher", "cache_key": "864264aea64ffa1f1dd623f19788da9c", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLK", "fetched_utc": "2026-08-12T06:43:50Z", "first": "2015-01-07 10:40:00", "last": "2015-07-09 13:19:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-07 10:40:00", "timeframe": "1min"}, "rows": 50000, "sha256": "9f579beb8678f6853046e061c21d1816446440869a18e25c9e57570b298020e3"}
571 +{"author": "Simon-Pierre Boucher", "cache_key": "cad974233064bd744377a32bf3eb39cb", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLK", "fetched_utc": "2026-08-12T06:43:51Z", "first": "2015-07-09 13:19:00", "last": "2015-12-31 16:52:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-09 13:19:00", "timeframe": "1min"}, "rows": 48239, "sha256": "b5f16e84bada1de4169bb780d6cff4affcc88ab7577d6bdb5c2a1c06defac399"}
572 +{"author": "Simon-Pierre Boucher", "cache_key": "81a5a4f34384296946b5da533feb4ef6", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLV", "fetched_utc": "2026-08-12T06:43:53Z", "first": "2014-01-02 09:02:00", "last": "2014-07-07 09:37:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "1663bd6bbb78c89ce9f9f19e7b2716525db17f4d4515b332c55ccbab22003029"}
573 +{"author": "Simon-Pierre Boucher", "cache_key": "79804f9b9a7d3babfd84e259bce82311", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLV", "fetched_utc": "2026-08-12T06:43:54Z", "first": "2014-07-07 09:37:00", "last": "2015-01-05 15:41:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-07 09:37:00", "timeframe": "1min"}, "rows": 50000, "sha256": "3c8b83478b6a7745bf13af21a777a4623239b14824ebcd4f1555c63b1b73fcb8"}
574 +{"author": "Simon-Pierre Boucher", "cache_key": "d1b431e59d54ab1f2d15fa01c3415df6", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLV", "fetched_utc": "2026-08-12T06:43:56Z", "first": "2015-01-05 15:41:00", "last": "2015-07-07 11:13:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-05 15:41:00", "timeframe": "1min"}, "rows": 50000, "sha256": "46ffca6b55655505d1bb7a1e2ee6e5f690bfa29ae293a7832354ad82b0f591a7"}
575 +{"author": "Simon-Pierre Boucher", "cache_key": "ff60186589f30d6bf6f73388300746df", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLV", "fetched_utc": "2026-08-12T06:43:57Z", "first": "2015-07-07 11:13:00", "last": "2015-12-31 16:29:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-07 11:13:00", "timeframe": "1min"}, "rows": 49915, "sha256": "7bcdbd1860b293d654f6251de068aee5b80ebdfcfbdca11037fb20a62a1f0cab"}
576 +{"author": "Simon-Pierre Boucher", "cache_key": "9f5b932d10be30de6f96ae9260f21441", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLI", "fetched_utc": "2026-08-12T06:43:59Z", "first": "2014-01-02 06:30:00", "last": "2014-07-07 09:41:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "d9966d707e1024d8857932245066c1765bfc232bdca98b43d8c21b376054270f"}
577 +{"author": "Simon-Pierre Boucher", "cache_key": "291bc3669d0e4b782e15843542f7ec6b", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLI", "fetched_utc": "2026-08-12T06:44:01Z", "first": "2014-07-07 09:41:00", "last": "2015-01-06 15:25:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-07 09:41:00", "timeframe": "1min"}, "rows": 50000, "sha256": "a40d1acb5a8158cd3cebee4aedaf14c3814c2234f5bb9ee70f15bd83c8609238"}
578 +{"author": "Simon-Pierre Boucher", "cache_key": "06fc8b7b09acc383b62f90fda10d6119", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLI", "fetched_utc": "2026-08-12T06:44:02Z", "first": "2015-01-06 15:25:00", "last": "2015-07-09 14:40:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-06 15:25:00", "timeframe": "1min"}, "rows": 50000, "sha256": "8a3e2e4325910892e6f129c9d27f4e158ef387caefaaba581c4b07db8ba368a7"}
579 +{"author": "Simon-Pierre Boucher", "cache_key": "b4595f92bcae437f44a7fb0ee7298197", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLI", "fetched_utc": "2026-08-12T06:44:03Z", "first": "2015-07-09 14:40:00", "last": "2015-12-31 16:29:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-09 14:40:00", "timeframe": "1min"}, "rows": 47988, "sha256": "9442e485314671b9a963a0ca065d76292671e93c33a0aa3d6245befafd590384"}
580 +{"author": "Simon-Pierre Boucher", "cache_key": "a927cbb457bcaa405a8d0b02d555ae96", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLY", "fetched_utc": "2026-08-12T06:44:05Z", "first": "2014-01-02 09:30:00", "last": "2014-07-08 10:37:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "e0196488b9a26d21bf860387dd9e489184912381ba5a9682f1c125a232560e31"}
581 +{"author": "Simon-Pierre Boucher", "cache_key": "da1132f4f074ae9999ca7ad64c10c974", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLY", "fetched_utc": "2026-08-12T06:44:07Z", "first": "2014-07-08 10:37:00", "last": "2015-01-08 15:49:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-08 10:37:00", "timeframe": "1min"}, "rows": 50000, "sha256": "0733df2e7b0688dd727e1ff7944f9dd677cdf7a703268287729b326c102ad74d"}
582 +{"author": "Simon-Pierre Boucher", "cache_key": "bd393447092972201f15018a1c5b802f", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLY", "fetched_utc": "2026-08-12T06:44:08Z", "first": "2015-01-08 15:49:00", "last": "2015-07-13 15:43:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-08 15:49:00", "timeframe": "1min"}, "rows": 50000, "sha256": "970a35dd8a23448718b90876d720b256c4203c5b485cb552819d41c75eec80f1"}
583 +{"author": "Simon-Pierre Boucher", "cache_key": "27d2045b4f407b6a35b7f2cad8f8240b", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLY", "fetched_utc": "2026-08-12T06:44:10Z", "first": "2015-07-13 15:43:00", "last": "2015-12-31 16:02:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-13 15:43:00", "timeframe": "1min"}, "rows": 47201, "sha256": "11bc1fe8f1767fbe5c7723bf810c9433755816c7c9c2057084bf5152dbc17d63"}
584 +{"author": "Simon-Pierre Boucher", "cache_key": "e851b92cf6bb7ac010aefdfb43c9ecf1", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLP", "fetched_utc": "2026-08-12T06:44:12Z", "first": "2014-01-02 09:02:00", "last": "2014-07-08 15:42:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "0cfb216c020b8379d798eee348bf9a59d583f7df378f67c67f8b80384e9665e1"}
585 +{"author": "Simon-Pierre Boucher", "cache_key": "a75abd18534a98e62579b2c546b87239", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLP", "fetched_utc": "2026-08-12T06:44:13Z", "first": "2014-07-08 15:42:00", "last": "2015-01-12 11:18:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-08 15:42:00", "timeframe": "1min"}, "rows": 50000, "sha256": "04a6f253c59538fc4e9bfbe765075a7a011c2e19a73c36114b33b1e6f0925513"}
586 +{"author": "Simon-Pierre Boucher", "cache_key": "ab31e88ce1cb96dbca98cfab15cad106", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLP", "fetched_utc": "2026-08-12T06:44:15Z", "first": "2015-01-12 11:18:00", "last": "2015-07-15 13:28:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-12 11:18:00", "timeframe": "1min"}, "rows": 50000, "sha256": "c67078f4a1896c928fe019da4375515f5fc155f4f7c7abb1644b6827ddc665c5"}
587 +{"author": "Simon-Pierre Boucher", "cache_key": "1c1a58f90420a373fa0a3562cf8d5eed", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLP", "fetched_utc": "2026-08-12T06:44:16Z", "first": "2015-07-15 13:28:00", "last": "2015-12-31 17:06:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-15 13:28:00", "timeframe": "1min"}, "rows": 46284, "sha256": "3e5cc1bc66b2b10ae9db6800051fa88bb2a275fee93bf215002898e57e478556"}
588 +{"author": "Simon-Pierre Boucher", "cache_key": "d41e0f56121662d3c85def2d127346ad", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLU", "fetched_utc": "2026-08-12T06:44:18Z", "first": "2014-01-02 08:00:00", "last": "2014-07-03 11:19:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "13be9ece7ba2e3735cabfd2fc36f5617b6cd9a1f9eaf95c8fd21b1fd200839e0"}
589 +{"author": "Simon-Pierre Boucher", "cache_key": "908533074f3a7d1de9a947fff02cbecf", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLU", "fetched_utc": "2026-08-12T06:44:19Z", "first": "2014-07-03 11:19:00", "last": "2015-01-06 10:15:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-03 11:19:00", "timeframe": "1min"}, "rows": 50000, "sha256": "2b07c0b7f40000467be7d9d8e94249a91fad1cdc724853577a40bbcb41dd62e9"}
590 +{"author": "Simon-Pierre Boucher", "cache_key": "f92e45b0dabe88877db512f682b8cb6b", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLU", "fetched_utc": "2026-08-12T06:44:21Z", "first": "2015-01-06 10:15:00", "last": "2015-07-07 11:02:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-06 10:15:00", "timeframe": "1min"}, "rows": 50000, "sha256": "2f13e6bd239dd2a04a1d5bbe69fdb9bed697bfa58dc0f125d13e0f963188c4b4"}
591 +{"author": "Simon-Pierre Boucher", "cache_key": "252faa1ed2bb9273b0a80ef1b731883b", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLU", "fetched_utc": "2026-08-12T06:44:22Z", "first": "2015-07-07 11:02:00", "last": "2015-12-31 16:08:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-07 11:02:00", "timeframe": "1min"}, "rows": 49396, "sha256": "29b374ec04d88eb4d7e0269dd2d64ab32b2519a34d1ba8de6601d338c8192dc0"}
592 +{"author": "Simon-Pierre Boucher", "cache_key": "6739fc4b3f92302040336ee7a7cd0948", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLB", "fetched_utc": "2026-08-12T06:44:24Z", "first": "2014-01-02 08:00:00", "last": "2014-07-09 09:59:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "70ad65a0eafc27dd08943f38947e491beeefd671ed344d4cd369883c0882e3d6"}
593 +{"author": "Simon-Pierre Boucher", "cache_key": "d8b963ad61c8d0c8eb309462d9f039e2", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLB", "fetched_utc": "2026-08-12T06:44:25Z", "first": "2014-07-09 09:59:00", "last": "2015-01-12 13:04:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-09 09:59:00", "timeframe": "1min"}, "rows": 50000, "sha256": "5421c5ca0544b3b38cd43a43a7484e40e17e869639064882606aaa6454fdea0d"}
594 +{"author": "Simon-Pierre Boucher", "cache_key": "e1f2fe3e5995fc9046ad5648ce2261eb", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLB", "fetched_utc": "2026-08-12T06:44:27Z", "first": "2015-01-12 13:04:00", "last": "2015-07-17 12:08:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-12 13:04:00", "timeframe": "1min"}, "rows": 50000, "sha256": "133da717fa25d0e25b0396564394e9acaed1e03c5a8af8a61f1564814542e512"}
595 +{"author": "Simon-Pierre Boucher", "cache_key": "9f138f19a107dff9b1c172c2e881068a", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/etf/XLB", "fetched_utc": "2026-08-12T06:44:28Z", "first": "2015-07-17 12:08:00", "last": "2015-12-31 16:08:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-17 12:08:00", "timeframe": "1min"}, "rows": 45431, "sha256": "2ef42669cb486f77fd7c9836018c2dd002045f1b5197a80d5705a50625fecee7"}
596 +{"author": "Simon-Pierre Boucher", "cache_key": "ff7b7f51a6a6d9758ee8d85941b4545c", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/ATRO", "fetched_utc": "2026-08-12T06:44:30Z", "first": "2014-01-02 09:30:00", "last": "2015-01-13 10:22:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "0e14cba2f8119bc6e9ec812332343d26ae28666aa5c777b9024efabd731adcd8"}
597 +{"author": "Simon-Pierre Boucher", "cache_key": "b5b52d0d391a6f4a7f0dc8a0b7ae91da", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/ATRO", "fetched_utc": "2026-08-12T06:44:31Z", "first": "2015-01-13 10:22:00", "last": "2015-12-31 16:00:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-13 10:22:00", "timeframe": "1min"}, "rows": 49626, "sha256": "64d9d5c14bc7fece29b30c29aa47e0000f58d134b663aaf54bfe267a7a61b853"}
598 +{"author": "Simon-Pierre Boucher", "cache_key": "6cfa7ce0edd395ef9e981ffc39a33b5f", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AUVI", "fetched_utc": "2026-08-12T06:44:31Z", "first": null, "last": null, "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 0, "sha256": "8062687d3dbe7963af9b2fa82e28bdbf5ce3aee72af33fa08113f6e5bf11df4e"}
599 +{"author": "Simon-Pierre Boucher", "cache_key": "4c344e82e69687d64c74762514dc0443", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AXDX", "fetched_utc": "2026-08-12T06:44:33Z", "first": "2014-01-02 09:30:00", "last": "2015-02-18 11:48:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "31b06bd993f1778e8d8f8979a7a9a84a7131063a00beae64bf7164d40fef8cd2"}
600 +{"author": "Simon-Pierre Boucher", "cache_key": "38c1f078e996b47829e667984fb87698", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/AXDX", "fetched_utc": "2026-08-12T06:44:34Z", "first": "2015-02-18 11:48:00", "last": "2015-12-31 16:04:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-02-18 11:48:00", "timeframe": "1min"}, "rows": 40136, "sha256": "58cca882bfdbbc6cc5cbad969723b0b742fb686aa7feaeb19e9865ef6f00fe85"}
601 +{"author": "Simon-Pierre Boucher", "cache_key": "0e054be3f05ee0c9498ff54f8d85c11b", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/BKE", "fetched_utc": "2026-08-12T06:44:36Z", "first": "2014-01-02 09:30:00", "last": "2014-09-22 15:29:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "5c480a4fe67a703a13862771044383b7ba0069f99c53700722fc6a151bfdeebe"}
602 +{"author": "Simon-Pierre Boucher", "cache_key": "6d73e59a994f902711d902b4696140ba", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/BKE", "fetched_utc": "2026-08-12T06:44:37Z", "first": "2014-09-22 15:29:00", "last": "2015-07-08 14:35:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-09-22 15:29:00", "timeframe": "1min"}, "rows": 50000, "sha256": "e65588ce0e92f540c85334effe337ab25724a919796e7140e1189be739cbb320"}
603 +{"author": "Simon-Pierre Boucher", "cache_key": "642623bb6eac62120a242baa3a0e2569", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/BKE", "fetched_utc": "2026-08-12T06:44:38Z", "first": "2015-07-08 14:35:00", "last": "2015-12-31 17:05:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-08 14:35:00", "timeframe": "1min"}, "rows": 35266, "sha256": "9347e02b3714053b268bcbc43dde6cadb5e11497648fdea8eee6380e43df2e83"}
604 +{"author": "Simon-Pierre Boucher", "cache_key": "de45bcd7453e06e685f615a267e12e8d", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/CECO", "fetched_utc": "2026-08-12T06:44:40Z", "first": "2014-01-02 09:30:00", "last": "2015-08-10 09:37:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "8702e678032375721eefdbd399555bccd6c810973644f722dd0301d16e8d5dc5"}
605 +{"author": "Simon-Pierre Boucher", "cache_key": "6e408f9512a8ff377262af95c4a21320", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/CECO", "fetched_utc": "2026-08-12T06:44:41Z", "first": "2015-08-10 09:37:00", "last": "2015-12-31 16:00:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-08-10 09:37:00", "timeframe": "1min"}, "rows": 19838, "sha256": "ca01bbe40a85354d5f91ae5d3ea76d1e87d0dc98f6bfa295bd19bcab077af72e"}
606 +{"author": "Simon-Pierre Boucher", "cache_key": "cfab9f4feedc6e18c7303037eb54a567", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/CKX", "fetched_utc": "2026-08-12T06:44:41Z", "first": "2014-01-08 13:59:00", "last": "2015-12-31 15:22:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 1875, "sha256": "d1986d2aea4f2ebefbfb4a8361a516660be598838a167031ad70cd8655719e73"}
607 +{"author": "Simon-Pierre Boucher", "cache_key": "cbfd13a52c88dc939a13fa924e1f273d", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/GCL", "fetched_utc": "2026-08-12T06:44:41Z", "first": null, "last": null, "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 0, "sha256": "8062687d3dbe7963af9b2fa82e28bdbf5ce3aee72af33fa08113f6e5bf11df4e"}
608 +{"author": "Simon-Pierre Boucher", "cache_key": "9c33002e19145a0f68657b2dccad3bf6", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/GRO", "fetched_utc": "2026-08-12T06:44:41Z", "first": null, "last": null, "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 0, "sha256": "8062687d3dbe7963af9b2fa82e28bdbf5ce3aee72af33fa08113f6e5bf11df4e"}
609 +{"author": "Simon-Pierre Boucher", "cache_key": "659bf634fadd2afed9ca96eb82e21fde", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/HPE", "fetched_utc": "2026-08-12T06:44:42Z", "first": "2015-11-02 07:28:00", "last": "2015-12-31 19:22:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 16578, "sha256": "2fc288a24fe0484688b67b7d91b418f7602f47eacc0830a071c5a5dd2c9726a5"}
610 +{"author": "Simon-Pierre Boucher", "cache_key": "398fe9513084b7d5fd36cb91f99c182f", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/HTD", "fetched_utc": "2026-08-12T06:44:43Z", "first": "2014-01-02 09:30:00", "last": "2015-10-15 11:22:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "7362ad433649d82ee0cf7013ea1831039f6e7bb4670b4cfad73676d1f8d6e705"}
611 +{"author": "Simon-Pierre Boucher", "cache_key": "cd72d9f2a1f6ff61aa22c8124cb613e2", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/stock/HTD", "fetched_utc": "2026-08-12T06:44:43Z", "first": "2015-10-15 11:22:00", "last": "2015-12-31 16:02:00", "params": {"adjustment": "adj_split", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-10-15 11:22:00", "timeframe": "1min"}, "rows": 5613, "sha256": "30f1bf27e397f798ed96316bcfce8a6248debdb8bc947e86948d27a1ad463e2b"}
612 +{"author": "Simon-Pierre Boucher", "cache_key": "723035ff5a32bd450572bb0acd9429a9", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:44:46Z", "first": "2014-01-02 06:00:00", "last": "2014-02-24 07:12:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "755992e6f701908b0982b98acea70abcab5cf6d751d175f75769d5a364cf5e1b"}
613 +{"author": "Simon-Pierre Boucher", "cache_key": "39fc83a336cfee690426101f0a360bd2", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:44:48Z", "first": "2014-02-24 07:12:00", "last": "2014-04-15 20:24:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-02-24 07:12:00", "timeframe": "1min"}, "rows": 50000, "sha256": "74c5384c128f1cc6cafb4c56f0087e01fcf68b51fbe41c1a7fe0d8055753606e"}
614 +{"author": "Simon-Pierre Boucher", "cache_key": "715b310ef0f9d305abd0650384498a78", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:44:50Z", "first": "2014-04-15 20:24:00", "last": "2014-06-09 06:31:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-04-15 20:24:00", "timeframe": "1min"}, "rows": 50000, "sha256": "6ae26b1bb09bd0a845c72646806d43483c53aa5ed3f9d31fb6f9c0016163f353"}
615 +{"author": "Simon-Pierre Boucher", "cache_key": "5acd4927f7494a6a7db5469bb74a3a06", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:44:52Z", "first": "2014-06-09 06:31:00", "last": "2014-07-30 23:37:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-06-09 06:31:00", "timeframe": "1min"}, "rows": 50000, "sha256": "085a17544efdeba20820f2ce7f4ce282e53a4d85096825de7e697d25f8860702"}
616 +{"author": "Simon-Pierre Boucher", "cache_key": "8cbd910e85dc8a981453f7e9f60e3446", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:44:54Z", "first": "2014-07-30 23:37:00", "last": "2014-09-22 09:31:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-30 23:37:00", "timeframe": "1min"}, "rows": 50000, "sha256": "dd39af8e3b01e2226669708fd4a79c5d3e1b87bea8f0bb3c6bf3171f53ee043c"}
617 +{"author": "Simon-Pierre Boucher", "cache_key": "e045aa913d7b9db1cb7aabe1ff13c27c", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:44:56Z", "first": "2014-09-22 09:31:00", "last": "2014-11-11 23:12:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-09-22 09:31:00", "timeframe": "1min"}, "rows": 50000, "sha256": "52be11e1be892f57d503860d193c49605382d4d4ad828696e7232d5b1763d0c6"}
618 +{"author": "Simon-Pierre Boucher", "cache_key": "f88182c88ac73c57f56004580f631808", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:44:58Z", "first": "2014-11-11 23:12:00", "last": "2015-01-06 11:11:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-11-11 23:12:00", "timeframe": "1min"}, "rows": 50000, "sha256": "e99399355cd014148510cf876d6f5a210469c4e4cda8eb342db50a55ea72ceff"}
619 +{"author": "Simon-Pierre Boucher", "cache_key": "d68479bb1fd0f48d432a9871076335c7", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:00Z", "first": "2015-01-06 11:11:00", "last": "2015-02-26 10:52:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-06 11:11:00", "timeframe": "1min"}, "rows": 50000, "sha256": "e213ec413c775c978379bcd59adce80a4ddeeae54fde237dc0732de489d5898b"}
620 +{"author": "Simon-Pierre Boucher", "cache_key": "bc01a0cfb9781d7f65a94a150f33c988", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:02Z", "first": "2015-02-26 10:52:00", "last": "2015-04-20 15:47:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-02-26 10:52:00", "timeframe": "1min"}, "rows": 50000, "sha256": "608543ef50fc736b1aa8d7e13a03a81c36624c1b246625334962e9d6387fcfca"}
621 +{"author": "Simon-Pierre Boucher", "cache_key": "4518a455134b96f6c54f0cafe64a0106", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:03Z", "first": "2015-04-20 15:47:00", "last": "2015-06-10 20:23:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-04-20 15:47:00", "timeframe": "1min"}, "rows": 50000, "sha256": "7ada421e68b8a3bb24e4640d1af83488af074980ade4a9ba970b5c112a183321"}
622 +{"author": "Simon-Pierre Boucher", "cache_key": "e98ca95a1f29727946b90e44e1f5de7e", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:05Z", "first": "2015-06-10 20:23:00", "last": "2015-07-31 17:14:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-06-10 20:23:00", "timeframe": "1min"}, "rows": 50000, "sha256": "65b38fa9c8b0460d965e4bbc3c9f0bfdc891ca447188ff33a388f18382e0fd63"}
623 +{"author": "Simon-Pierre Boucher", "cache_key": "259a5dc95bb34d7475c4ee6cef57808e", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:07Z", "first": "2015-07-31 17:14:00", "last": "2015-09-22 07:44:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-31 17:14:00", "timeframe": "1min"}, "rows": 50000, "sha256": "da00d0e8fd5b008429c6dfbabae9325b4b2491e01a3c6cc364de8869481d413d"}
624 +{"author": "Simon-Pierre Boucher", "cache_key": "320f46aca06389f3ab3a32b4c197ee28", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:08Z", "first": "2015-09-22 07:44:00", "last": "2015-11-12 01:05:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-09-22 07:44:00", "timeframe": "1min"}, "rows": 50000, "sha256": "cc35b2bf95e2a264492e208fd617a2c03c3ed0b03dbf6ed5cb971286635c7540"}
625 +{"author": "Simon-Pierre Boucher", "cache_key": "a614e379787ab514468e3c1723f26dc0", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:09Z", "first": "2015-11-12 01:05:00", "last": "2015-12-31 16:59:00", "params": {"adjustment": "contin_adj_ratio", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-11-12 01:05:00", "timeframe": "1min"}, "rows": 46407, "sha256": "f55a40e0f173ee5425fc64dca1c7625838bd7ece00c664cd12a331156f40f311"}
626 +{"author": "Simon-Pierre Boucher", "cache_key": "80ead37bdd05505420ce3c2395b0b773", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:12Z", "first": "2014-01-02 06:00:00", "last": "2014-02-24 07:12:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "629ab5d6e117a1c17f14fe5224daa4a694ed21fcdc34b7bb2ab7c9ebea73f3de"}
627 +{"author": "Simon-Pierre Boucher", "cache_key": "e9c4dd024d996201eea480773620bc4a", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:14Z", "first": "2014-02-24 07:12:00", "last": "2014-04-15 20:24:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-02-24 07:12:00", "timeframe": "1min"}, "rows": 50000, "sha256": "d27e6494bc97a317c3aa944df591ef76a6d7079229bb180f38f5e9c2822c9525"}
628 +{"author": "Simon-Pierre Boucher", "cache_key": "0dc8e261f04157a6d06dcd175f2e3cc8", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:16Z", "first": "2014-04-15 20:24:00", "last": "2014-06-09 06:31:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-04-15 20:24:00", "timeframe": "1min"}, "rows": 50000, "sha256": "a0f7be61f1e9469bae28a9e1935fecf7bad0760bb9b549cd6da364caf7508887"}
629 +{"author": "Simon-Pierre Boucher", "cache_key": "0425a63bffd9059635f05537a4e8d721", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:18Z", "first": "2014-06-09 06:31:00", "last": "2014-07-30 23:37:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-06-09 06:31:00", "timeframe": "1min"}, "rows": 50000, "sha256": "abbcc09631a291da4ad7a2d3a02caa6093ce798828763397f78405d8ed7f0e4f"}
630 +{"author": "Simon-Pierre Boucher", "cache_key": "5f37425e7f623060bf837f97829ff199", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:20Z", "first": "2014-07-30 23:37:00", "last": "2014-09-22 09:31:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-30 23:37:00", "timeframe": "1min"}, "rows": 50000, "sha256": "5c09eabb33937f21260fe4511c9f34b14e6b41c9a71a8559ba3cc39c2e0b2a7b"}
631 +{"author": "Simon-Pierre Boucher", "cache_key": "9752ae7fce9b545b06f84b5e546ca544", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:22Z", "first": "2014-09-22 09:31:00", "last": "2014-11-11 23:12:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-09-22 09:31:00", "timeframe": "1min"}, "rows": 50000, "sha256": "295ac71b0dad0008f61ceb46f903e1646612c2147b731699a921770655da56eb"}
632 +{"author": "Simon-Pierre Boucher", "cache_key": "80545a3f281b3ad3d02d6010bd366508", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:24Z", "first": "2014-11-11 23:12:00", "last": "2015-01-06 11:11:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-11-11 23:12:00", "timeframe": "1min"}, "rows": 50000, "sha256": "25e5679403d7291ea4b72bf7fb1456f085e36d3a9bf11db64fbc31d4e853f40b"}
633 +{"author": "Simon-Pierre Boucher", "cache_key": "00beff221902243eb124e53c1a03e9c4", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:26Z", "first": "2015-01-06 11:11:00", "last": "2015-02-26 10:52:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-06 11:11:00", "timeframe": "1min"}, "rows": 50000, "sha256": "348791bfe15698f1c1801dd1722ca2874cc81f75ad629bd2355ae174b8a6568e"}
634 +{"author": "Simon-Pierre Boucher", "cache_key": "b8a0ec9d5eba3ce5e6eee779ce73333e", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:28Z", "first": "2015-02-26 10:52:00", "last": "2015-04-20 15:47:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-02-26 10:52:00", "timeframe": "1min"}, "rows": 50000, "sha256": "ecaa159031a88789895433f187061b7aa9a0ee4683586e29153eac75e6ce069e"}
635 +{"author": "Simon-Pierre Boucher", "cache_key": "8db9964c1ae4fb1ef744f81370cc2702", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:29Z", "first": "2015-04-20 15:47:00", "last": "2015-06-10 20:23:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-04-20 15:47:00", "timeframe": "1min"}, "rows": 50000, "sha256": "4861c227f3df5b396ee171dfe0b6b48209736126b242444abfdad58ce94fa165"}
636 +{"author": "Simon-Pierre Boucher", "cache_key": "f0e0e3904e5e963e9fd921a66c36022a", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:31Z", "first": "2015-06-10 20:23:00", "last": "2015-07-31 17:14:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-06-10 20:23:00", "timeframe": "1min"}, "rows": 50000, "sha256": "6dceda5aca73102409d2e151eb34beb8e5f3d054a5be7edf25e077c09a56ab6d"}
637 +{"author": "Simon-Pierre Boucher", "cache_key": "bc3ca0d3aca59cd40079e73d206a7ac3", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:32Z", "first": "2015-07-31 17:14:00", "last": "2015-09-22 07:44:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-31 17:14:00", "timeframe": "1min"}, "rows": 50000, "sha256": "396a7283ea0f2e9008c598fd5db5db837e0ace8a1f687d0675bc1e41d8dd4ab0"}
638 +{"author": "Simon-Pierre Boucher", "cache_key": "851f4f614fd7edc538683b9bd806dcf9", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:34Z", "first": "2015-09-22 07:44:00", "last": "2015-11-12 01:05:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-09-22 07:44:00", "timeframe": "1min"}, "rows": 50000, "sha256": "dcf68fb893e4871adcf7afaab90997d76230a885e9b3690225ef4c73bdc672a3"}
639 +{"author": "Simon-Pierre Boucher", "cache_key": "4a9dfbf49cbbb9a3679483d4da0019d4", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:35Z", "first": "2015-11-12 01:05:00", "last": "2015-12-31 16:59:00", "params": {"adjustment": "contin_adj_absolute", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-11-12 01:05:00", "timeframe": "1min"}, "rows": 46407, "sha256": "1ca22b2e9fd9a6bd6ce50cfe70060bc2c60ed75f281123ba4b3aefec247b9505"}
640 +{"author": "Simon-Pierre Boucher", "cache_key": "af1715894690db7999a3d39b6fe27809", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:38Z", "first": "2014-01-02 06:00:00", "last": "2014-02-24 07:12:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-01-01", "timeframe": "1min"}, "rows": 50000, "sha256": "6fccae8c445838f2847160e41074275556c3929345433b25b5402b9e2832a927"}
641 +{"author": "Simon-Pierre Boucher", "cache_key": "afd048be6b62e4623a93790706a71e99", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:40Z", "first": "2014-02-24 07:12:00", "last": "2014-04-15 20:24:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-02-24 07:12:00", "timeframe": "1min"}, "rows": 50000, "sha256": "5cbc63bd165f8326d1f78ea8e64898051fbcc5c8b059e4d3d0e90c963af94421"}
642 +{"author": "Simon-Pierre Boucher", "cache_key": "09229e6ebdecf6c9204b26bc5d0e69b7", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:44Z", "first": "2014-04-15 20:24:00", "last": "2014-06-09 06:31:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-04-15 20:24:00", "timeframe": "1min"}, "rows": 50000, "sha256": "9ea425dd637ac82650188b14506e69dc2c0536544fd1b55a7013d1b1694f5956"}
643 +{"author": "Simon-Pierre Boucher", "cache_key": "aa2e95891aac8975e5b5d8f83d0caec3", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:47Z", "first": "2014-06-09 06:31:00", "last": "2014-07-30 23:37:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-06-09 06:31:00", "timeframe": "1min"}, "rows": 50000, "sha256": "0523b1d3366de01cedbf7842d1e2a067fa120a77ef7d053b4dcc36c9033851c2"}
644 +{"author": "Simon-Pierre Boucher", "cache_key": "e9ac7937ce50a237b349b2e1425c9f85", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:50Z", "first": "2014-07-30 23:37:00", "last": "2014-09-22 09:31:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-07-30 23:37:00", "timeframe": "1min"}, "rows": 50000, "sha256": "832935ae81fa8739df452bec4bda2325d3ecac4b5b3e69c441b3cacd45e6085e"}
645 +{"author": "Simon-Pierre Boucher", "cache_key": "75797f4e89220d37fbeef501b99fc9bb", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:52Z", "first": "2014-09-22 09:31:00", "last": "2014-11-11 23:12:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-09-22 09:31:00", "timeframe": "1min"}, "rows": 50000, "sha256": "d38d009031b357cd48d69ce58c794ab8640dad19198a1d1d1903791306a2e5b6"}
646 +{"author": "Simon-Pierre Boucher", "cache_key": "267d310f34aafe158a0447e9bd51078a", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:55Z", "first": "2014-11-11 23:12:00", "last": "2015-01-06 11:11:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2014-11-11 23:12:00", "timeframe": "1min"}, "rows": 50000, "sha256": "49b0b8001f2d7591fed88a2614aa997e6545c166f69e93c867de947b210fc49f"}
647 +{"author": "Simon-Pierre Boucher", "cache_key": "f0360dd4d018d3937d3f2424a7e15afa", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:57Z", "first": "2015-01-06 11:11:00", "last": "2015-02-26 10:52:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-01-06 11:11:00", "timeframe": "1min"}, "rows": 50000, "sha256": "75d817936f8452a4f85db58c2676c900ea3579639b34e3f48d8c3e92508d4acb"}
648 +{"author": "Simon-Pierre Boucher", "cache_key": "4b4f103c147163118877e45ff7379765", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:45:58Z", "first": "2015-02-26 10:52:00", "last": "2015-04-20 15:47:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-02-26 10:52:00", "timeframe": "1min"}, "rows": 50000, "sha256": "4d361f2556900e22adf89320f74facc10fed3232c4d132d89ab3fa577074ab1d"}
649 +{"author": "Simon-Pierre Boucher", "cache_key": "22a322588e0f8730e833b63948ae481d", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:46:00Z", "first": "2015-04-20 15:47:00", "last": "2015-06-10 20:23:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-04-20 15:47:00", "timeframe": "1min"}, "rows": 50000, "sha256": "9bcdc6480ef4e040833156948775a10e860a4c2d3718055f58feeddf23dac4fc"}
650 +{"author": "Simon-Pierre Boucher", "cache_key": "b87017846cfb2f60b4cf2ead3e232b24", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:46:02Z", "first": "2015-06-10 20:23:00", "last": "2015-07-31 17:14:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-06-10 20:23:00", "timeframe": "1min"}, "rows": 50000, "sha256": "d1ff7e740b3a63c1b68cd66bd86ab63a94daba37e4be04177505987288b61bad"}
651 +{"author": "Simon-Pierre Boucher", "cache_key": "e0663a26b52935dd0f8051c9aadb4ec0", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:46:03Z", "first": "2015-07-31 17:14:00", "last": "2015-09-22 07:44:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-07-31 17:14:00", "timeframe": "1min"}, "rows": 50000, "sha256": "db08bb2f91a67cbb534224e6636eeb392baec609d3f98ac7fdbb656c7182ac52"}
652 +{"author": "Simon-Pierre Boucher", "cache_key": "445e288bf8143ffb040e377f273cd8cd", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:46:05Z", "first": "2015-09-22 07:44:00", "last": "2015-11-12 01:05:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-09-22 07:44:00", "timeframe": "1min"}, "rows": 50000, "sha256": "60b1af5b39fcff997d033db731e833290a1ec47bdbc613859191067c8f548016"}
653 +{"author": "Simon-Pierre Boucher", "cache_key": "feba5806d5ceea82ac362ed3f089b499", "data_source": "hfmarketdata.io", "endpoint": "/v1/bars/futures/ES", "fetched_utc": "2026-08-12T06:46:06Z", "first": "2015-11-12 01:05:00", "last": "2015-12-31 16:59:00", "params": {"adjustment": "contin_UNadj", "end": "2016-01-01", "limit": 50000, "order": "asc", "start": "2015-11-12 01:05:00", "timeframe": "1min"}, "rows": 46407, "sha256": "e4174e785a531002bd4ea75c32b00544a709b2875062f9329631b1818b60baff"}
modified experiments/micro/expD_leadlag_scan/benchmark.py +186 −10
@@ -1,7 +1,7 @@
1 1 # =============================================================================
2 2 # Project : anomaly-atlas
3 3 # File : experiments/micro/expD_leadlag_scan/benchmark.py
4 # Purpose : Benchmark runner: Lead-lag scan: lagged cross-correlations and Granger, separating…
4 +# Purpose : Lead-lag scan — raw LOCF vs both-fresh, artifact share, FDR
5 5 # Author : Simon-Pierre Boucher
6 6 # Contact : contact@spboucher.ai
7 7 # Data src : hfmarketdata.io (sole data source)
@@ -10,25 +10,201 @@
10 10 # Platform : macOS / Apple Silicon (arm64)
11 11 # License : All rights reserved (research code)
12 12 # =============================================================================
13 +"""Experiment D — lead-lag scan (protocol pre-specified in hypothesis.md).
13 14
14 """Benchmark entry point for expD_leadlag_scan.
15
16 Must embed the hardware manifest in all result output
17 (see benchmarks/hardware_manifest.py) and write results to
18 results/expD_leadlag_scan/<timestamp>/. Uses hfmarketdata.io data ONLY, exclusively
19 through src/anomaly_atlas/data/hf_client.py.
15 +The design measures T3 directly: every pair reports its raw-LOCF lead, its
16 +both-fresh lead, and the difference (artifact share). Level 0 throughout.
20 17 """
21 18
19 +from __future__ import annotations
20 +
21 +import json
22 22 import sys
23 +from datetime import UTC, datetime
23 24 from pathlib import Path
24 25
25 sys.path.insert(0, str(Path(__file__).resolve().parents[3] / "benchmarks"))
26 +import numpy as np
27 +
28 +REPO_ROOT = Path(__file__).resolve().parents[3]
29 +sys.path.insert(0, str(REPO_ROOT / "benchmarks"))
30 +sys.path.insert(0, str(REPO_ROOT / "src"))
31 +
26 32 from hardware_manifest import collect_manifest # noqa: E402
27 33
34 +from anomaly_atlas.data.cleaning import ( # noqa: E402
35 + RTH_SLOTS,
36 + both_fresh,
37 + nan_xcorr,
38 + rth_day_grids,
39 +)
40 +from anomaly_atlas.data.hf_client import HFMarketDataClient # noqa: E402
41 +from anomaly_atlas.data.universe import random_stock_universe # noqa: E402
42 +from anomaly_atlas.stats.multiple_testing import ( # noqa: E402
43 + benjamini_hochberg,
44 + bootstrap_pvalue,
45 +)
46 +
47 +ADJ = "adj_split"
48 +LIQUID = ["AAPL", "MSFT", "NVDA", "AMZN", "GOOGL", "META", "TSLA", "JPM", "XOM", "UNH", "QQQ"]
49 +SECTORS = ["XLF", "XLE", "XLK", "XLV", "XLI", "XLY", "XLP", "XLU", "XLB"]
50 +WINDOWS = {"2006-2007": ("2006-01-01", "2008-01-01"),
51 + "2014-2015": ("2014-01-01", "2016-01-01")}
52 +MAX_LAG = 3
53 +BOOT_N, BOOT_SEED = 200, 42
54 +MIN_DAYS, MIN_FRESH = 200, 10_000
55 +
56 +
57 +def day_matrix(days: dict[str, np.ndarray], day_list: list[str]) -> tuple[np.ndarray, np.ndarray]:
58 + """(n_days, 389) LOCF returns + interval-fresh masks, day-aligned."""
59 + rets = np.full((len(day_list), RTH_SLOTS - 1), np.nan)
60 + fresh = np.zeros((len(day_list), RTH_SLOTS - 1), dtype=bool)
61 + for i, day in enumerate(day_list):
62 + p = days.get(day)
63 + if p is None:
64 + continue
65 + observed = np.isfinite(p)
66 + filled = p.copy()
67 + for t in range(1, RTH_SLOTS):
68 + if not observed[t]:
69 + filled[t] = filled[t - 1]
70 + rets[i] = np.diff(filled)
71 + fresh[i] = observed[1:] & observed[:-1]
72 + return rets, fresh
73 +
74 +
75 +def day_block_boot_xcorr(
76 + rx: np.ndarray, fx: np.ndarray, ry: np.ndarray, fy: np.ndarray, lag: int
77 +) -> np.ndarray:
78 + """Bootstrap distribution of the both-fresh xcorr at `lag`, resampling days."""
79 + rng = np.random.default_rng(BOOT_SEED)
80 + n_days = rx.shape[0]
81 + out = np.empty(BOOT_N)
82 + for b in range(BOOT_N):
83 + idx = rng.integers(0, n_days, n_days)
84 + bx, by = both_fresh(rx[idx].ravel(), fx[idx].ravel(), ry[idx].ravel(), fy[idx].ravel())
85 + out[b] = nan_xcorr(bx, by, abs(lag)).get(lag, np.nan)
86 + return out
87 +
88 +
89 +def analyze_pair(rx, fx, ry, fy) -> dict | None:
90 + bx, by = both_fresh(rx.ravel(), fx.ravel(), ry.ravel(), fy.ravel())
91 + n_fresh = int(np.isfinite(bx).sum())
92 + if n_fresh < MIN_FRESH:
93 + return None
94 + raw = nan_xcorr(rx.ravel(), ry.ravel(), MAX_LAG)
95 + fresh_xc = nan_xcorr(bx, by, MAX_LAG)
96 + boot_p1 = day_block_boot_xcorr(rx, fx, ry, fy, 1)
97 + boot_m1 = day_block_boot_xcorr(rx, fx, ry, fy, -1)
98 + return {
99 + "n_fresh_pairs": n_fresh,
100 + "fresh_fraction": round(n_fresh / rx.size, 4),
101 + "raw_xcorr": {str(k): round(v, 5) if np.isfinite(v) else None for k, v in raw.items()},
102 + "fresh_xcorr": {str(k): round(v, 5) if np.isfinite(v) else None
103 + for k, v in fresh_xc.items()},
104 + "artifact_share_+1": round(raw[1] - fresh_xc[1], 5)
105 + if np.isfinite(raw[1]) and np.isfinite(fresh_xc[1]) else None,
106 + "p_fresh_+1": bootstrap_pvalue(boot_p1, 0.0),
107 + "p_fresh_-1": bootstrap_pvalue(boot_m1, 0.0),
108 + }
109 +
28 110
29 111 def main() -> None:
30 collect_manifest() # embedded in results once implemented
31 raise NotImplementedError("experiment not yet implemented")
112 + run_utc = datetime.now(UTC)
113 + client = HFMarketDataClient()
114 + random10 = random_stock_universe(
115 + client.tickers("stock", timeframe="1min", adjustment=ADJ))[:10]
116 +
117 + series_spec: dict[str, tuple[str, str, str | None]] = (
118 + {"SPY": ("etf", "SPY", ADJ), "SPX": ("index", "SPX", None)}
119 + | {t: ("stock", t, ADJ) for t in LIQUID if t != "QQQ"}
120 + | {"QQQ": ("etf", "QQQ", ADJ)}
121 + | {t: ("etf", t, ADJ) for t in SECTORS}
122 + | {t: ("stock", t, ADJ) for t in random10}
123 + | {f"ES[{a}]": ("futures", "ES", a)
124 + for a in ("contin_adj_ratio", "contin_adj_absolute", "contin_UNadj")}
125 + )
126 +
127 + pairs: list[dict] = []
128 + for window, (s, e) in WINDOWS.items():
129 + grids: dict[str, dict] = {}
130 + for name, (asset, ticker, adj) in series_spec.items():
131 + if window == "2006-2007" and (name == "SPX" or name.startswith("ES[")):
132 + continue
133 + bars = client.get_bars(asset, ticker, "1min", adj, s, e)
134 + g = rth_day_grids(bars)
135 + if len(g) >= MIN_DAYS:
136 + grids[name] = g
137 + print(f"{window} {name}: {len(g)} days")
138 + if "SPY" not in grids:
139 + continue
140 + day_list = sorted(grids["SPY"].keys())
141 + mats = {n: day_matrix(g, day_list) for n, g in grids.items()}
142 + rx, fx = mats["SPY"]
143 + for name in mats:
144 + if name == "SPY":
145 + continue
146 + ry, fy = mats[name]
147 + # convention: x = the hypothesized leader.
148 + # ES/SPX pairs: x = ES or SPX, y = SPY. Others: x = SPY, y = ticker.
149 + if name.startswith("ES[") or name == "SPX":
150 + m = analyze_pair(ry, fy, rx, fx)
151 + else:
152 + m = analyze_pair(rx, fx, ry, fy)
153 + if m is None:
154 + continue
155 + bucket = ("es" if name.startswith("ES[") else "index" if name == "SPX"
156 + else "sector" if name in SECTORS
157 + else "liquid" if name in LIQUID else "random")
158 + m |= {"pair": f"{name}->SPY" if bucket in ("es", "index") else f"SPY->{name}",
159 + "bucket": bucket, "window": window}
160 + pairs.append(m)
161 + print(f"{window}: {len(pairs)} pair-cells so far")
162 +
163 + # FDR over all fresh ±1 tests jointly
164 + tests = [(i, "p_fresh_+1") for i in range(len(pairs))] + \
165 + [(i, "p_fresh_-1") for i in range(len(pairs))]
166 + mask = benjamini_hochberg(np.array([pairs[i][k] for i, k in tests]), alpha=0.05)
167 + for (i, k), rej in zip(tests, mask, strict=True):
168 + pairs[i][f"fdr_{k[2:]}"] = bool(rej)
169 +
170 + fdr_survivors = [
171 + {"pair": p["pair"], "window": p["window"], "bucket": p["bucket"],
172 + "fresh_+1": p["fresh_xcorr"]["1"], "fresh_-1": p["fresh_xcorr"]["-1"],
173 + "which": [k for k in ("fresh_+1", "fresh_-1") if p[f"fdr_{k}"]]}
174 + for p in pairs if p.get("fdr_fresh_+1") or p.get("fdr_fresh_-1")
175 + ]
176 + summary = {
177 + "pair_cells": len(pairs),
178 + "tests": len(tests),
179 + "fdr_alpha": 0.05,
180 + "fdr_survivors": fdr_survivors,
181 + "median_artifact_share_by_bucket": {
182 + b: round(float(np.median([p["artifact_share_+1"] for p in pairs
183 + if p["bucket"] == b and p["artifact_share_+1"] is not None])), 5)
184 + for b in ("liquid", "sector", "random")
185 + },
186 + }
187 +
188 + results = {
189 + "experiment": "expD_leadlag_scan",
190 + "run_utc": run_utc.isoformat(),
191 + "author": "Simon-Pierre Boucher",
192 + "contact": "contact@spboucher.ai",
193 + "data_source": "hfmarketdata.io",
194 + "confidence_level": 0,
195 + "protocol": {"windows": WINDOWS, "adjustment": ADJ, "max_lag": MAX_LAG,
196 + "boot": [BOOT_N, BOOT_SEED], "random10": random10,
197 + "min_days": MIN_DAYS, "min_fresh": MIN_FRESH},
198 + "summary": summary,
199 + "pairs": pairs,
200 + "client_stats": vars(client.stats) | {"refreshes": list(client.stats.refreshes)},
201 + "manifest": collect_manifest(),
202 + }
203 + out_dir = REPO_ROOT / "results" / "expD_leadlag_scan" / run_utc.strftime("%Y%m%dT%H%M%SZ")
204 + out_dir.mkdir(parents=True)
205 + (out_dir / "results.json").write_text(json.dumps(results, indent=2) + "\n")
206 + print(f"\nwrote {out_dir.relative_to(REPO_ROOT)}/results.json")
207 + print(json.dumps(summary, indent=1))
32 208
33 209
34 210 if __name__ == "__main__":
modified experiments/micro/expD_leadlag_scan/hypothesis.md +38 −14
@@ -5,34 +5,58 @@ author: Simon-Pierre Boucher
5 5 contact: contact@spboucher.ai
6 6 data_source: hfmarketdata.io
7 7 created: 2026-08-12
8 status: draft
8 +modified: 2026-08-12
9 +status: final
9 10 ---
10 11
11 12 # Hypothesis — expD_leadlag_scan
12 13
14 +*Pre-specified 2026-08-12 before the scan ran. Alignment primitives
15 +(interval-fresh masks, both-fresh de-artifacting) passed the §8.1 gate
16 +first — the gate caught an end-freshness-only mask bug (Epps attenuation)
17 +before real data.*
18 +
13 19 ```text
14 20 Hypothesis
15 <what we believe and why — pre-specified BEFORE looking at results>
21 + Tests H07/H08 (scan half) and previews H09/H11. Expectations:
22 + (i) raw LOCF joins will show SPY "leading" everything, in proportion to
23 + staleness (T3); (ii) on both-fresh subsamples, liquid and sector-ETF
24 + pairs will show NO lead-lag at ±1..3 min in 2014-2015 (H08
25 + expected-negative); (iii) 2006-2007 fresh pairs MAY retain a small lead
26 + (pre-decay regime, Chordia et al. 2005); (iv) ES→SPY: any 1min-visible
27 + lead is expected to be tiny or absent, and must be invariant to the three
28 + futures splice variants; (v) SPX→SPY: the raw lead persists even
29 + both-fresh (index prints are CONTENT-stale though print-fresh) — the H11
30 + artifact case.
16 31
17 32 Falsification criterion
18 <the concrete measurable outcome that would prove this wrong>
33 + (ii) falsified if any liquid/sector both-fresh pair survives FDR(5%) at
34 + |lag| ∈ 1..3 in 2014-2015. (iv) falsified if the ES→SPY fresh lead
35 + changes sign/significance across splice variants (that would mean the
36 + measurement is splice-dominated, not economic).
19 37
20 38 Artifact null(s)
21 <the fake-signal baseline(s) this must beat: bounce / staleness /
22 non-synchronous timestamps / permuted calendar / random walk>
23
24 Method
25 <exact procedure, universe, split (train/validation/holdout), seeds,
26 number of hypotheses tested, correction applied>
39 + T3 non-synchronicity: measured DIRECTLY as artifact share =
40 + raw_xcorr[+1] − fresh_xcorr[+1] per pair. Day-block bootstrap null
41 + (resampled days, n=200, seed=42) for fresh xcorr[±1] vs 0.
42 +
43 +Method (grid pre-declared)
44 + Pairs vs SPY: 11 liquid (AAPL MSFT NVDA AMZN GOOGL META TSLA JPM XOM UNH
45 + QQQ), 9 sector ETFs (XLF XLE XLK XLV XLI XLY XLP XLU XLB), 10 random
46 + (first 10, sorted, of the seed-42 random-30). Plus ES→SPY (all three
47 + splice variants) and SPX→SPY. Windows: W1 2006-01-01→2008-01-01,
48 + W2 2014-01-01→2016-01-01 (ES/SPX: W2 only — history starts 2008).
49 + 1min RTH grids; raw-LOCF vs both-fresh (interval-fresh) treatments;
50 + lags ±3; min 200 covered days and 10k fresh pairs per cell.
51 + Correction: BH-FDR over all fresh xcorr[+1] and xcorr[-1] tests jointly.
52 + Cell count ≤ (30×2 + 4 + 1) ≈ 65 pairs-windows × 2 lags.
27 53
28 54 Result
29 <filled after the run: effect size, bootstrap CIs, corrected p-values,
30 OOS status, cost-adjusted effect, credits used>
55 + <filled after the run>
31 56
32 57 Interpretation
33 <what the numbers mean, WITH confidence level (0-3); alternative
34 explanations considered — artifact first>
58 + <filled after the run — Level 0; survivors go to expF/expH>
35 59
36 60 Next experiment
37 <the most informative follow-up given this result>
61 + expE calendar scan (pre-counted budget); then expF correction battery.
38 62 ```
added web/lib/charts.js +228 −0
@@ -0,0 +1,228 @@
1 +// ============================================================================
2 +// Project : anomaly-atlas
3 +// File : web/lib/charts.js
4 +// Purpose : Server-rendered SVG figures built from experiment results.json
5 +// Author : Simon-Pierre Boucher
6 +// Contact : contact@spboucher.ai
7 +// Data src : hfmarketdata.io (sole data source)
8 +// Created : 2026-08-12
9 +// Modified : 2026-08-12
10 +// Platform : macOS / Apple Silicon (arm64) — Node.js (deployed on MacLustr)
11 +// License : All rights reserved (research code)
12 +// ============================================================================
13 +"use strict";
14 +
15 +/* Figures follow the dataviz method: form by job, validated palette
16 + * (slots: blue #2a78d6, orange #eb6834 — all-pairs PASS on #fffdf9; gray
17 + * #898781 is de-emphasis ink, not a series), thin marks with 2px surface
18 + * rings, hairline grid, text in ink tokens (never series color), native
19 + * <title> tooltips, selective direct labels. Every figure is generated from
20 + * the latest committed results.json — never hand-typed numbers. */
21 +
22 +const path = require("path");
23 +
24 +const BLUE = "#2a78d6";
25 +const ORANGE = "#eb6834";
26 +const GRAY = "#898781";
27 +const SURFACE = "#fffdf9";
28 +const GRID = "#e5e1d6";
29 +const INK = "#1a1c20";
30 +const MUTED = "#5d6167";
31 +
32 +function esc(s) {
33 + return String(s).replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c]));
34 +}
35 +
36 +function latestResults(C, experiment) {
37 + const run = C.listResultRuns().find((r) => r.experiment === experiment);
38 + if (!run) return null;
39 + const data = C.readJson(path.posix.join(run.rel, "results.json"));
40 + return data ? { data, run: run.timestamp } : null;
41 +}
42 +
43 +function fig(svg, caption) {
44 + return `<figure class="chart-fig">${svg}<figcaption>${caption}</figcaption></figure>`;
45 +}
46 +
47 +const AXIS_TXT = `font-size="11" fill="${MUTED}"`;
48 +
49 +// ------------------------------------------------------------------- expB
50 +function expBScatterPanel(rows, key, title, W, H, xLabelBottom) {
51 + const ML = 46, MR = 14, MT = 26, MB = 34;
52 + const iw = W - ML - MR, ih = H - MT - MB;
53 + const ys = rows.map((r) => r[key]);
54 + const ymin = Math.min(...ys, 0), ymax = Math.max(...ys, 0);
55 + const pad = (ymax - ymin) * 0.12 || 0.01;
56 + const y0 = ymin - pad, y1 = ymax + pad;
57 + const xp = (v) => ML + v * iw;
58 + const yp = (v) => MT + ih - ((v - y0) / (y1 - y0)) * ih;
59 +
60 + let g = `<text x="${ML}" y="${MT - 10}" font-size="12" font-weight="600" fill="${INK}">${esc(title)}</text>`;
61 + for (const t of [y0 + pad, 0, y1 - pad]) {
62 + const v = Math.round(t * 1000) / 1000;
63 + g += `<line x1="${ML}" y1="${yp(v)}" x2="${ML + iw}" y2="${yp(v)}" stroke="${GRID}" stroke-width="1"/>`;
64 + // skip an extreme tick label that would collide with the zero label
65 + if (v === 0 || Math.abs(yp(v) - yp(0)) > 14) {
66 + g += `<text x="${ML - 6}" y="${yp(v) + 4}" text-anchor="end" ${AXIS_TXT}>${v}</text>`;
67 + }
68 + }
69 + g += `<line x1="${ML}" y1="${yp(0)}" x2="${ML + iw}" y2="${yp(0)}" stroke="#c9c4b6" stroke-width="1"/>`;
70 + for (const t of [0, 0.5, 1]) {
71 + g += `<text x="${xp(t)}" y="${MT + ih + 16}" text-anchor="middle" ${AXIS_TXT}>${t}</text>`;
72 + }
73 + if (xLabelBottom) g += `<text x="${ML + iw / 2}" y="${H - 4}" text-anchor="middle" ${AXIS_TXT}>staleness (share of RTH minutes without a fresh print)</text>`;
74 + const extreme = rows.reduce((a, b) => (Math.abs(b[key]) > Math.abs(a[key]) ? b : a), rows[0]);
75 + for (const r of rows) {
76 + g += `<circle cx="${xp(r.staleness).toFixed(1)}" cy="${yp(r[key]).toFixed(1)}" r="4.5" fill="${BLUE}" stroke="${SURFACE}" stroke-width="2"><title>${esc(r.ticker)} — staleness ${r.staleness}, ${esc(title)} ${r[key]}</title></circle>`;
77 + }
78 + for (const r of [extreme]) {
79 + g += `<text x="${Math.min(xp(r.staleness) + 8, W - 44)}" y="${yp(r[key]) + 4}" font-size="10.5" fill="${MUTED}">${esc(r.ticker)}</text>`;
80 + }
81 + return g;
82 +}
83 +
84 +function expBFigure(C) {
85 + const res = latestResults(C, "expB_artifact_baselines");
86 + if (!res) return "";
87 + const rows = Object.entries(res.data.per_ticker || {})
88 + .map(([ticker, m]) => ({ ticker, ...m }))
89 + .filter((r) => Number.isFinite(r.staleness));
90 + if (rows.length < 5) return "";
91 + const W = 760, H = 250;
92 + const half = 372;
93 + const svg = `<svg viewBox="0 0 ${W} ${H}" role="img" aria-label="Measured artifact levels versus staleness">
94 +<g>${expBScatterPanel(rows.filter((r) => Number.isFinite(r.ac1)), "ac1", "1min return AC1", half, H, true)}</g>
95 +<g transform="translate(${W - half},0)">${expBScatterPanel(rows.filter((r) => Number.isFinite(r["spy_leads_+1"])), "spy_leads_+1", "SPY leads +1 min (LOCF join)", half, H, true)}</g>
96 +</svg>`;
97 + return fig(svg, `expB — artifact null levels, one dot per ticker (Q1 2024, RTH 1min). ` +
98 + `Bounce pushes AC1 negative and LOCF joins make SPY spuriously lead, both in proportion to staleness. ` +
99 + `Run ${esc(res.run)}, regenerated from results.json.`);
100 +}
101 +
102 +// ------------------------------------------------------------------- expC
103 +function expCFigure(C) {
104 + const res = latestResults(C, "expC_reversion_scan");
105 + if (!res) return "";
106 + const cells = (res.data.cells || []).filter((c) => Number.isFinite(c.vr30) && Number.isFinite(c.ac1));
107 + if (!cells.length) return "";
108 + for (const c of cells) c.vr30_excess = c.vr30 - (1 + 2 * c.ac1 * (1 - 1 / 30));
109 + const rowsDef = [];
110 + for (const tf of ["1day", "30min", "5min", "1min"]) {
111 + for (const per of ["2000-2007", "2008-2015", "2014-2015"]) {
112 + const cs = cells.filter((c) => c.timeframe === tf && c.period === per);
113 + if (cs.length) rowsDef.push({ label: `${tf} · ${per}`, cells: cs });
114 + }
115 + }
116 + const W = 760, ML = 150, MR = 16, MT = 30, RH = 30, MB = 46;
117 + const H = MT + rowsDef.length * RH + MB;
118 + const xmin = -0.32, xmax = 0.16;
119 + const iw = W - ML - MR;
120 + const xp = (v) => ML + ((Math.max(xmin, Math.min(xmax, v)) - xmin) / (xmax - xmin)) * iw;
121 + let g = "";
122 + for (const t of [-0.3, -0.2, -0.1, 0, 0.1]) {
123 + g += `<line x1="${xp(t)}" y1="${MT - 6}" x2="${xp(t)}" y2="${MT + rowsDef.length * RH}" stroke="${t === 0 ? "#c9c4b6" : GRID}" stroke-width="1"/>
124 +<text x="${xp(t)}" y="${MT + rowsDef.length * RH + 16}" text-anchor="middle" ${AXIS_TXT}>${t}</text>`;
125 + }
126 + g += `<text x="${ML + iw / 2}" y="${H - 6}" text-anchor="middle" ${AXIS_TXT}>VR(30) excess over the MA(1)-consistent null · negative = multi-lag reversion beyond any lag-1 effect</text>`;
127 + const labeled = new Set(
128 + cells.filter((c) => c.fdr_vr30 && c.vr30_excess < -0.05)
129 + .sort((a, b) => a.vr30_excess - b.vr30_excess).slice(0, 3).map((c) => c.ticker + c.period + c.timeframe));
130 + rowsDef.forEach((row, i) => {
131 + const y = MT + i * RH + RH / 2;
132 + g += `<text x="${ML - 10}" y="${y + 4}" text-anchor="end" font-size="11.5" fill="${INK}">${esc(row.label)}</text>`;
133 + for (const c of row.cells) {
134 + const surv = c.fdr_vr30 && c.vr30_excess < -0.05;
135 + const tip = `${c.ticker} ${c.timeframe} ${c.period}: VR30 ${c.vr30}, excess ${c.vr30_excess.toFixed(3)}${surv ? " (FDR survivor)" : ""}`;
136 + g += surv
137 + ? `<circle cx="${xp(c.vr30_excess).toFixed(1)}" cy="${y}" r="5" fill="${BLUE}" stroke="${SURFACE}" stroke-width="2"><title>${esc(tip)}</title></circle>`
138 + : `<circle cx="${xp(c.vr30_excess).toFixed(1)}" cy="${y}" r="3.5" fill="${SURFACE}" stroke="${GRAY}" stroke-width="1.4" opacity=".8"><title>${esc(tip)}</title></circle>`;
139 + if (labeled.has(c.ticker + c.period + c.timeframe)) {
140 + g += `<text x="${xp(c.vr30_excess) - 8}" y="${y - 8}" text-anchor="middle" font-size="10.5" fill="${MUTED}">${esc(c.ticker)}</text>`;
141 + }
142 + }
143 + });
144 + const legend = `<g font-size="11" fill="${MUTED}">
145 +<circle cx="${ML}" cy="${MT - 16}" r="5" fill="${BLUE}" stroke="${SURFACE}" stroke-width="2"/><text x="${ML + 10}" y="${MT - 12}" fill="${INK}">FDR survivor (excess &lt; −0.05)</text>
146 +<circle cx="${ML + 210}" cy="${MT - 16}" r="3.5" fill="${SURFACE}" stroke="${GRAY}" stroke-width="1.4"/><text x="${ML + 220}" y="${MT - 12}">other scan cells (Level 0)</text></g>`;
147 + const svg = `<svg viewBox="0 0 ${W} ${H}" role="img" aria-label="expC variance-ratio excess by timeframe and period">${legend}${g}</svg>`;
148 + return fig(svg, `expC — multi-lag reversion triage on TRAIN. One dot per ticker-cell; ` +
149 + `the MA(1)-consistent null absorbs all lag-1 effects (bounce included); values beyond the axis range ` +
150 + `pile at its edge. Run ${esc(res.run)}, regenerated from results.json.`);
151 +}
152 +
153 +// ------------------------------------------------------------------- expD
154 +function expDFigure(C) {
155 + const res = latestResults(C, "expD_leadlag_scan");
156 + if (!res) return "";
157 + const out = [];
158 + for (const window of ["2014-2015", "2006-2007"]) {
159 + const rows = (res.data.pairs || [])
160 + .filter((p) => p.window === window && p.raw_xcorr && p.fresh_xcorr &&
161 + Number.isFinite(p.raw_xcorr["1"]) && Number.isFinite(p.fresh_xcorr["1"]))
162 + .sort((a, b) => (a.bucket + "").localeCompare(b.bucket + "") || b.raw_xcorr["1"] - a.raw_xcorr["1"]);
163 + if (!rows.length) continue;
164 + const W = 760, ML = 170, MR = 16, MT = 34, RH = 19, MB = 44;
165 + const H = MT + rows.length * RH + MB;
166 + const vals = rows.flatMap((p) => [p.raw_xcorr["1"], p.fresh_xcorr["1"]]);
167 + const xmin = Math.min(...vals, 0) - 0.01, xmax = Math.max(...vals, 0) + 0.01;
168 + const iw = W - ML - MR;
169 + const xp = (v) => ML + ((v - xmin) / (xmax - xmin)) * iw;
170 + let g = "";
171 + const ticks = [0, 0.05, 0.1].filter((t) => t >= xmin && t <= xmax);
172 + for (const t of ticks) {
173 + g += `<line x1="${xp(t)}" y1="${MT - 6}" x2="${xp(t)}" y2="${MT + rows.length * RH}" stroke="${t === 0 ? "#c9c4b6" : GRID}" stroke-width="1"/>
174 +<text x="${xp(t)}" y="${MT + rows.length * RH + 16}" text-anchor="middle" ${AXIS_TXT}>${t}</text>`;
175 + }
176 + g += `<text x="${ML + iw / 2}" y="${H - 5}" text-anchor="middle" ${AXIS_TXT}>cross-correlation at +1 min (leader → follower)</text>`;
177 + let lastBucket = "";
178 + rows.forEach((p, i) => {
179 + const y = MT + i * RH + RH / 2;
180 + if (p.bucket !== lastBucket) {
181 + lastBucket = p.bucket;
182 + g += `<text x="${ML - 160}" y="${y + 4}" font-size="10" font-weight="700" fill="${MUTED}" letter-spacing=".08em">${esc(p.bucket.toUpperCase())}</text>`;
183 + }
184 + const raw = p.raw_xcorr["1"], fresh = p.fresh_xcorr["1"];
185 + const surv = p.fdr_fresh_p1 || p["fdr_fresh_+1"];
186 + g += `<text x="${ML - 10}" y="${y + 4}" text-anchor="end" font-size="11" fill="${INK}">${esc(p.pair)}</text>
187 +<line x1="${xp(raw)}" y1="${y}" x2="${xp(fresh)}" y2="${y}" stroke="${GRID}" stroke-width="2"/>
188 +<circle cx="${xp(raw).toFixed(1)}" cy="${y}" r="4.5" fill="${ORANGE}" stroke="${SURFACE}" stroke-width="2"><title>${esc(p.pair)} raw LOCF join: ${raw}</title></circle>
189 +<circle cx="${xp(fresh).toFixed(1)}" cy="${y}" r="4.5" fill="${BLUE}" stroke="${SURFACE}" stroke-width="2"><title>${esc(p.pair)} both-fresh: ${fresh}${surv ? " (FDR survivor)" : ""}</title></circle>`;
190 + });
191 + const legend = `<g font-size="11">
192 +<circle cx="${ML}" cy="${MT - 18}" r="4.5" fill="${ORANGE}" stroke="${SURFACE}" stroke-width="2"/><text x="${ML + 9}" y="${MT - 14}" fill="${INK}">raw LOCF join (artifact included)</text>
193 +<circle cx="${ML + 230}" cy="${MT - 18}" r="4.5" fill="${BLUE}" stroke="${SURFACE}" stroke-width="2"/><text x="${ML + 239}" y="${MT - 14}" fill="${INK}">both-fresh (synchronized)</text></g>`;
194 + out.push(fig(
195 + `<svg viewBox="0 0 ${W} ${H}" role="img" aria-label="expD lead-lag: raw versus synchronized cross-correlation, ${window}">${legend}${g}</svg>`,
196 + `expD — lead at +1 min per pair, ${window}: the gap between the raw join and the both-fresh ` +
197 + `subsample is the non-synchronicity artifact (T3), measured. Run ${esc(res.run)}, regenerated from results.json.`
198 + ));
199 + }
200 + return out.join("");
201 +}
202 +
203 +const BUILDERS = {
204 + expB_artifact_baselines: expBFigure,
205 + expC_reversion_scan: expCFigure,
206 + expD_leadlag_scan: expDFigure,
207 +};
208 +
209 +/** Figures for an experiment page ("" when none apply). */
210 +function figuresFor(experiment, C) {
211 + const builder = BUILDERS[experiment];
212 + try {
213 + return builder ? builder(C) : "";
214 + } catch {
215 + return "";
216 + }
217 +}
218 +
219 +/** The most recent experiment figure, for the home page. */
220 +function homeFigure(C) {
221 + for (const exp of ["expD_leadlag_scan", "expC_reversion_scan", "expB_artifact_baselines"]) {
222 + const html = figuresFor(exp, C);
223 + if (html) return { experiment: exp, html: html.split("</figure>")[0] + "</figure>" };
224 + }
225 + return null;
226 +}
227 +
228 +module.exports = { figuresFor, homeFigure };
modified web/public/style.css +8 −0
@@ -382,6 +382,14 @@ a:hover { text-decoration: underline; text-underline-offset: 3px; }
382 382 }
383 383 .chip-k { color: var(--faint); margin-right: 5px; text-transform: uppercase; letter-spacing: .06em; }
384 384
385 +/* --------------------------------------------------------------- figures */
386 +.chart-fig { margin: 18px 0 6px; }
387 +.chart-fig svg { width: 100%; height: auto; display: block; font-family: var(--font-text); }
388 +.chart-fig figcaption {
389 + font-size: .78rem; color: var(--faint); margin-top: 8px; line-height: 1.5;
390 + border-top: 1px solid var(--hairline); padding-top: 8px;
391 +}
392 +
385 393 /* -------------------------------------------------------------- comments */
386 394 .comment-form {
387 395 display: grid; gap: 12px; margin: 6px 0 10px;
modified web/server.js +15 −2
@@ -18,6 +18,7 @@ const path = require("path");
18 18 const express = require("express");
19 19 const C = require("./lib/content");
20 20 const R = require("./lib/render");
21 +const charts = require("./lib/charts");
21 22
22 23 const app = express();
23 24 const PORT = process.env.PORT || 8150;
@@ -118,7 +119,15 @@ app.get("/", (req, res) => {
118 119 <a class="more" href="/doc/research/LOG.md">Full research log →</a></div>
119 120 <div class="log-grid">${logHtml}</div>
120 121 </section>`;
121 page(res, { title: "Home", active: "Home", body });
122 + const homeFig = charts.homeFigure(C);
123 + const figSection = homeFig
124 + ? `<section class="card">
125 + <div class="card-head-row"><h2>Latest measured figure</h2>
126 + <a class="more" href="/experiments/${homeFig.experiment}">${homeFig.experiment} →</a></div>
127 + ${homeFig.html}
128 +</section>`
129 + : "";
130 + page(res, { title: "Home", active: "Home", body: body + figSection });
122 131 });
123 132
124 133 // ---------------------------------------------------------------- atlas
@@ -279,9 +288,13 @@ app.get("/experiments/:id", (req, res) => {
279 288 const codeLink = C.exists(path.posix.join(exp.rel, "benchmark.py"))
280 289 ? `<p><a class="more" href="/file/${exp.rel}/benchmark.py">View benchmark implementation (benchmark.py) →</a></p>`
281 290 : "";
291 + const figures = charts.figuresFor(exp.id, C);
292 + const figuresHtml = figures
293 + ? `<section class="card"><h2>Figures</h2><p class="lede-small">Generated server-side from the latest committed <code>results.json</code> — never hand-typed.</p>${figures}</section>`
294 + : "";
282 295 const body = `<p class="crumb"><a href="/experiments">Experiments</a> / ${R.esc(exp.id)}</p>
283 296 <h1 class="page-title">${R.esc(exp.id)}</h1><p class="lede-small">${R.esc(exp.purpose)}</p>
284 ${codeLink}${sections.join("")}${runsHtml}`;
297 +${codeLink}${figuresHtml}${sections.join("")}${runsHtml}`;
285 298 page(res, { title: exp.id, active: "Experiments", body });
286 299 });
287 300
288 301