SPB Git

spb/wp40_uqo

Public MIT

WP40 RAID: Phase 6 — E1–E6 drivers, E5 results (R=1000), E7 generation sweep (11 nodes, cold/warm compile), e0 universe, references.bib (Crossref-verified)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Nov 2, 2026) parent 54c354d Browse files

15 changed files +3,330 −2

modified backends/metal/host/metal_backend.mm +7 −1
@@ -10,6 +10,7 @@
10 #include <map> 10 #include <map>
11 #include <mutex> 11 #include <mutex>
12 #include <unistd.h> 12 #include <unistd.h>
13+#include <cstdlib>
13 #include <mach-o/dyld.h> 14 #include <mach-o/dyld.h>
14 15
15 namespace raid { namespace metal { const char* msl_bundle(); } } 16 namespace raid { namespace metal { const char* msl_bundle(); } }
@@ -51,12 +52,14 @@ bool ensure_library(KernelStats* st) {
51 NSError* err = nil; Timer t; 52 NSError* err = nil; Timer t;
52 // 1. prebuilt metallib: RAID_METALLIB env, compile-time path, next to the executable 53 // 1. prebuilt metallib: RAID_METALLIB env, compile-time path, next to the executable
53 std::vector<std::string> candidates; 54 std::vector<std::string> candidates;
55+ const bool runtime_only = std::getenv("RAID_METAL_RUNTIME_ONLY") != nullptr; // force runtime MSL compilation (benchmarks)
54 if (const char* e = std::getenv("RAID_METALLIB")) candidates.push_back(e); 56 if (const char* e = std::getenv("RAID_METALLIB")) candidates.push_back(e);
55 #ifdef RAID_METALLIB_PATH 57 #ifdef RAID_METALLIB_PATH
56 candidates.push_back(RAID_METALLIB_PATH); 58 candidates.push_back(RAID_METALLIB_PATH);
57 #endif 59 #endif
58 { char buf[4096]; uint32_t sz = sizeof buf; if (_NSGetExecutablePath(buf, &sz) == 0) { std::string p(buf); auto k = p.rfind('/'); if (k != std::string::npos) candidates.push_back(p.substr(0, k) + "/raid.metallib"); } } 60 { char buf[4096]; uint32_t sz = sizeof buf; if (_NSGetExecutablePath(buf, &sz) == 0) { std::string p(buf); auto k = p.rfind('/'); if (k != std::string::npos) candidates.push_back(p.substr(0, k) + "/raid.metallib"); } }
59 for (auto& c : candidates) { 61 for (auto& c : candidates) {
62+ if (runtime_only) break;
60 if (access(c.c_str(), R_OK) != 0) continue; 63 if (access(c.c_str(), R_OK) != 0) continue;
61 library_ = [device_ newLibraryWithURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:c.c_str()]] error:&err]; 64 library_ = [device_ newLibraryWithURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:c.c_str()]] error:&err];
62 if (library_) { library_source_ = "metallib:" + c; compile_seconds_ = t.s(); break; } 65 if (library_) { library_source_ = "metallib:" + c; compile_seconds_ = t.s(); break; }
@@ -64,7 +67,10 @@ bool ensure_library(KernelStats* st) {
64 // 2. runtime compilation of the embedded MSL 67 // 2. runtime compilation of the embedded MSL
65 if (!library_) { 68 if (!library_) {
66 MTLCompileOptions* opts = [MTLCompileOptions new]; opts.fastMathEnabled = NO; // keep IEEE semantics (no reassociation): required by the double-float transforms 69 MTLCompileOptions* opts = [MTLCompileOptions new]; opts.fastMathEnabled = NO; // keep IEEE semantics (no reassociation): required by the double-float transforms
67− library_ = [device_ newLibraryWithSource:[NSString stringWithUTF8String:raid::metal::msl_bundle()] options:opts error:&err]; 70+ // RAID_MSL_SALT appends a unique comment so that the system shader cache cannot serve a previous compilation
71+ // (used to measure genuinely cold runtime compilation in E7).
72+ std::string src = raid::metal::msl_bundle(); if (const char* salt = std::getenv("RAID_MSL_SALT")) src += "\n// salt " + std::string(salt) + "\n";
73+ library_ = [device_ newLibraryWithSource:[NSString stringWithUTF8String:src.c_str()] options:opts error:&err];
68 if (!library_) { log::error("metal: shader compilation failed", {{"error", err ? std::string([[err localizedDescription] UTF8String]) : "?"}}); available_ = false; return false; } 74 if (!library_) { log::error("metal: shader compilation failed", {{"error", err ? std::string([[err localizedDescription] UTF8String]) : "?"}}); available_ = false; return false; }
69 library_source_ = "runtime"; compile_seconds_ = t.s(); if (st) st->compiled_now = true; 75 library_source_ = "runtime"; compile_seconds_ = t.s(); if (st) st->compiled_now = true;
70 } 76 }
added benchmarks/end_to_end/bench_e1_batched_rv.cpp +66 −0
@@ -0,0 +1,66 @@
1+// E1 — batched realized measures on a real equity panel (FinData 2024 exports, cache) and synthetic panels:
2+// scaling versus panel width S ∈ {1,10,100,1000,10000(synthetic)} and segment length (1 day = ~390, 1 week ≈ 1950,
3+// 1 month ≈ 8 580 returns, 1 year ≈ 98 000), RAID CPU 1 thread / CPU all threads / Metal (fused and unfused).
4+// Usage: bench_e1_batched_rv <e0_universe.json> <out.jsonl> [reps]
5+#include <cstdio>
6+#include <fstream>
7+#include <random>
8+#include <nlohmann/json.hpp>
9+#include "raid/core/manifest.hpp"
10+#include "raid/core/hash.hpp"
11+#include "raid/core/rng.hpp"
12+#include "raid/core/thread_pool.hpp"
13+#include "raid/data/io.hpp"
14+#include "raid/data/calendar.hpp"
15+#include "raid/data/returns.hpp"
16+#include "raid/estimators/realized.hpp"
17+#include "raid/backend/backend.hpp"
18+using namespace raid; using json = nlohmann::json;
19+
20+namespace { f64 now() { return std::chrono::duration<f64>(std::chrono::steady_clock::now().time_since_epoch()).count(); } }
21+
22+int main(int argc, char** argv) {
23+ if (argc < 3) { std::fprintf(stderr, "usage: %s e0_universe.json out.jsonl [reps]\n", argv[0]); return 2; }
24+ json e0 = json::parse(std::ifstream(argv[1])); const int reps = argc > 3 ? std::atoi(argv[3]) : 5; std::ofstream out(argv[2], std::ios::app);
25+ ExperimentManifest man; man.experiment = "E1.batched_rv"; man.created_at_utc = now_utc_iso(); man.raid_version = RAID_VERSION; man.host = host_info(); man.seed = 20261102; man.parameters = {{"reps", std::to_string(reps)}};
26+ man.inputs["e0_universe.json"] = Sha256::of_file(argv[1]); man.parameters["dataset_versions"] = e0["dataset_versions"].dump();
27+ // ---- load the real panel: per symbol, regular-session intraday log returns for 2024 (CSR by symbol, and by symbol×session)
28+ MarketCalendar cal; std::map<std::string, data::IntradayReturns> rets; f64 load_s = 0, prep_s = 0; usize bars_total = 0;
29+#ifdef RAID_WITH_ARROW
30+ for (auto& ex : e0["exports"]) { const f64 t0 = now(); auto pb = data::read_bars_parquet(ex["path"].get<std::string>()); load_s += now() - t0; const f64 t1 = now();
31+ for (auto& [sym, b] : pb.series) { bars_total += b.size(); auto reg = b.filter_session(cal, SessionPolicy::regular); if (reg.n_sessions() < 200) continue; rets[sym] = data::intraday_returns(reg); } prep_s += now() - t1; }
32+#else
33+ std::fprintf(stderr, "E1 requires the Arrow build\n"); return 1;
34+#endif
35+ const auto universe = e0["samples"]["1000"].get<std::vector<std::string>>(); std::vector<std::string> syms; for (auto& s : universe) if (rets.count(s)) syms.push_back(s);
36+ std::fprintf(stderr, "loaded %zu symbols (%zu bars, load %.1fs, prep %.1fs)\n", syms.size(), bars_total, load_s, prep_s);
37+ out << json({{"kind", "load"}, {"symbols", syms.size()}, {"bars", bars_total}, {"load_seconds", load_s}, {"prep_seconds", prep_s}, {"peak_rss", peak_rss_bytes()}}).dump() << "\n";
38+ auto cpu1 = backend::make_cpu_backend(1), cpuN = backend::make_cpu_backend(0); std::shared_ptr<backend::Backend> gpu;
39+#ifdef RAID_ENABLE_METAL
40+ gpu = backend::make_metal_backend();
41+#endif
42+ struct Case { std::string source; usize S; std::string seg; usize seg_len; std::string backend; bool fused; };
43+ std::vector<Case> cases; const std::vector<std::pair<std::string, usize>> segs = {{"day", 1}, {"week", 5}, {"month", 22}, {"year", 252}};
44+ for (usize S : {1ul, 10ul, 100ul, 1000ul}) for (auto& [sn, nd] : segs) { if (S > syms.size()) continue; for (auto bk : {"cpu1", "cpuN", "metal", "metal_unfused"}) cases.push_back({"real", S, sn, nd, bk, std::string(bk) != "metal_unfused"}); }
45+ for (usize S : {10000ul}) for (auto& [sn, nd] : segs) { if (nd > 22) continue; for (auto bk : {"cpu1", "cpuN", "metal"}) cases.push_back({"synthetic", S, sn, nd, bk, true}); }
46+ std::mt19937_64 order(20261102); std::shuffle(cases.begin(), cases.end(), order);
47+ usize done = 0;
48+ for (auto& c : cases) {
49+ if ((c.backend == "metal" || c.backend == "metal_unfused") && !gpu) continue;
50+ // Build the batch: segments = consecutive groups of `seg_len` sessions per symbol (real) or synthetic Student-t returns
51+ std::vector<f64> v; std::vector<i64> off = {0}; const f64 tb0 = now();
52+ if (c.source == "real") { for (usize s = 0; s < c.S; ++s) { auto& ir = rets[syms[s]]; const usize ns = ir.session_dates.size(); for (usize k = 0; k + c.seg_len <= ns; k += c.seg_len) { const usize a = static_cast<usize>(ir.session_offsets[k]), b = static_cast<usize>(ir.session_offsets[k + c.seg_len]); v.insert(v.end(), ir.r.begin() + a, ir.r.begin() + b); off.push_back(static_cast<i64>(v.size())); } } }
53+ else { Rng r(7, c.S); const usize n = 390 * c.seg_len; v.resize(c.S * n); for (auto& x : v) x = 1e-3 * r.student_t(5.0); off.resize(c.S + 1); for (usize s = 0; s <= c.S; ++s) off[s] = static_cast<i64>(s * n); }
54+ const f64 build_s = now() - tb0; backend::Batch b{v, off};
55+ auto be = c.backend == "cpu1" ? cpu1 : (c.backend == "cpuN" ? cpuN : gpu);
56+ est::RealizedOptions ro; ro.fuse_kernels = c.fused; ro.plan.backend = be->kind();
57+ auto run = [&]() { if (c.backend == "cpu1") { ExecutionPlan p; p.backend = Backend::cpu; p.threads = 1; est::RealizedOptions r1 = ro; r1.plan = p; return est::realized_measures_batch(b, r1); } return est::realized_measures_batch(b, ro); };
58+ for (int w = 0; w < 2; ++w) run();
59+ for (int rep = 0; rep < reps; ++rep) { const f64 t0 = now(); auto m = run(); const f64 wall = now() - t0;
60+ // accuracy vs CPU FP64 reference (first segment summary) — recorded for the GPU rows
61+ f64 max_rel = 0; if (be->kind() == Backend::metal) { est::RealizedOptions rc = ro; rc.plan.backend = Backend::cpu; auto ref = est::realized_measures_batch(b, rc); for (usize s = 0; s < m.rv.size(); ++s) if (ref.rv[s] > 0) max_rel = std::max(max_rel, std::abs(m.rv[s] - ref.rv[s]) / ref.rv[s]); }
62+ out << json({{"kind", "bench"}, {"experiment", "E1"}, {"source", c.source}, {"S", c.S}, {"segments", off.size() - 1}, {"segment", c.seg}, {"segment_sessions", c.seg_len}, {"elements", v.size()}, {"backend", c.backend}, {"fused", c.fused}, {"rep", rep}, {"wall_seconds", wall}, {"kernel_wall_seconds", m.stats.wall_seconds}, {"device_seconds", m.stats.device_seconds}, {"build_seconds", build_s}, {"max_rel_err_rv_vs_fp64", max_rel}, {"precision", std::string(to_string(m.stats.precision))}, {"threads", c.backend == "cpu1" ? 1u : ThreadPool::global().size()}, {"peak_rss", peak_rss_bytes()}}).dump() << "\n"; }
63+ out.flush(); ++done; std::fprintf(stderr, "[%zu/%zu] %s S=%zu seg=%s %s elements=%zu\n", done, cases.size(), c.source.c_str(), c.S, c.seg.c_str(), c.backend.c_str(), v.size());
64+ }
65+ man.save(std::string(argv[2]) + ".manifest.json"); return 0;
66+}
added benchmarks/end_to_end/bench_e2_har.cpp +49 −0
@@ -0,0 +1,49 @@
1+// E2 — HAR-RV on the real daily RV panel (from the 2024 1-minute exports): (a) rolling causal forecasts h ∈ {1,5,22}
2+// with QLIKE/MSE vs a random-walk benchmark (RV_{t+h} forecast = RV_t) on a strict chronological split, per symbol;
3+// (b) runtime of per-series QR fits (CPU) vs batched sufficient-statistics fits (CPU-MT, Metal) for S ∈ {10,100,1000}.
4+// Note: 2024 alone gives ≈ 252 daily RVs per symbol — rolling windows are short (120 days); the point is runtime and
5+// relative accuracy, not a new forecasting result. Usage: bench_e2_har <e0_universe.json> <out.jsonl> [reps]
6+#include <cstdio>
7+#include <fstream>
8+#include <random>
9+#include <nlohmann/json.hpp>
10+#include "raid/core/manifest.hpp"
11+#include "raid/core/hash.hpp"
12+#include "raid/core/thread_pool.hpp"
13+#include "raid/data/io.hpp"
14+#include "raid/data/calendar.hpp"
15+#include "raid/data/returns.hpp"
16+#include "raid/estimators/realized.hpp"
17+#include "raid/estimators/har.hpp"
18+using namespace raid; using json = nlohmann::json;
19+namespace { f64 now() { return std::chrono::duration<f64>(std::chrono::steady_clock::now().time_since_epoch()).count(); } }
20+
21+int main(int argc, char** argv) {
22+ if (argc < 3) { std::fprintf(stderr, "usage: %s e0_universe.json out.jsonl [reps]\n", argv[0]); return 2; }
23+#ifndef RAID_WITH_ARROW
24+ return 1;
25+#else
26+ json e0 = json::parse(std::ifstream(argv[1])); const int reps = argc > 3 ? std::atoi(argv[3]) : 5; std::ofstream out(argv[2], std::ios::app);
27+ ExperimentManifest man; man.experiment = "E2.har"; man.created_at_utc = now_utc_iso(); man.raid_version = RAID_VERSION; man.host = host_info(); man.inputs["e0_universe.json"] = Sha256::of_file(argv[1]);
28+ MarketCalendar cal; std::map<std::string, std::vector<f64>> rv, rq;
29+ for (auto& ex : e0["exports"]) { auto pb = data::read_bars_parquet(ex["path"].get<std::string>()); for (auto& [sym, b] : pb.series) { auto reg = b.filter_session(cal, SessionPolicy::regular); if (reg.n_sessions() < 240) continue; auto ir = data::intraday_returns(reg); est::RealizedOptions ro; ro.plan.backend = Backend::cpu; auto m = est::realized_measures(ir, ro); bool ok = true; for (f64 v : m.rv) if (!(v > 0)) ok = false; if (ok) { rv[sym] = m.rv; rq[sym] = m.rq; } } }
30+ const auto universe = e0["samples"]["1000"].get<std::vector<std::string>>(); std::vector<std::string> syms; for (auto& s : universe) if (rv.count(s)) syms.push_back(s);
31+ std::fprintf(stderr, "E2: %zu symbols with >= 240 sessions of RV\n", syms.size()); out << json({{"kind", "load"}, {"experiment", "E2"}, {"symbols", syms.size()}}).dump() << "\n";
32+ // (a) forecasting accuracy: window 120, step 1, horizons 1/5/22, HAR-RV vs log-HAR vs HARQ vs random walk; first 100 symbols
33+ const usize nacc = std::min<usize>(100, syms.size());
34+ for (int h : {1, 5, 22}) { std::vector<json> rows(nacc);
35+ ThreadPool::global().parallel_for(nacc, [&](usize a, usize b) { for (usize i = a; i < b; ++i) { auto& x = rv[syms[i]]; auto& q = rq[syms[i]]; json r = {{"symbol", syms[i]}, {"h", h}, {"T", x.size()}};
36+ for (auto& [name, lg, hq] : std::vector<std::tuple<std::string, bool, bool>>{{"har", false, false}, {"loghar", true, false}, {"harq", false, true}}) { est::HarSpec s; s.horizon = h; s.log = lg; s.harq = hq; try { auto roll = est::har_rolling(x, s, 120, 1, hq ? std::span<const f64>(q) : std::span<const f64>()); auto l = est::forecast_loss(roll.actual, roll.forecast); r[name] = {{"qlike", l.qlike}, {"mse", l.mse}, {"n", l.n}, {"fits", roll.n_fits}, {"seconds", roll.seconds}}; if (name == "har") { std::vector<f64> rw(roll.origin.size()); for (usize j = 0; j < rw.size(); ++j) rw[j] = x[roll.origin[j]]; auto lr = est::forecast_loss(roll.actual, rw); r["random_walk"] = {{"qlike", lr.qlike}, {"mse", lr.mse}, {"n", lr.n}}; } } catch (const RaidError& ex) { r[name] = {{"error", ex.what()}}; } }
37+ rows[i] = r; } });
38+ for (auto& r : rows) { r["kind"] = "accuracy"; r["experiment"] = "E2"; out << r.dump() << "\n"; } out.flush(); std::fprintf(stderr, "E2 accuracy h=%d done\n", h); }
39+ // (b) runtime: per-series fits vs batched sufficient statistics
40+ for (usize S : {10ul, 100ul, 1000ul}) { if (S > syms.size()) continue; std::vector<f64> cat; std::vector<i64> off = {0}; for (usize i = 0; i < S; ++i) { cat.insert(cat.end(), rv[syms[i]].begin(), rv[syms[i]].end()); off.push_back(static_cast<i64>(cat.size())); }
41+ est::HarSpec spec; spec.horizon = 1; spec.cov.type = stats::CovType::classical;
42+ for (auto mode : {"per_series_cpu1", "per_series_cpuMT", "batched_cpu", "batched_metal"}) for (int rep = 0; rep < reps; ++rep) { const f64 t0 = now(); usize okc = 0; std::string backend_used = "cpu"; f64 dev = 0;
43+ if (std::string(mode).rfind("per_series", 0) == 0) { std::vector<int> ok(S, 0); auto fitall = [&](usize a, usize b) { for (usize i = a; i < b; ++i) { try { auto e = est::har_fit(rv[syms[i]], spec); ok[i] = e.ok(); } catch (...) {} } }; if (std::string(mode) == "per_series_cpu1") fitall(0, S); else ThreadPool::global().parallel_for(S, fitall); for (int v : ok) okc += v; }
44+ else { ExecutionPlan p; p.backend = std::string(mode) == "batched_metal" ? Backend::metal : Backend::cpu; auto b = est::har_batch(cat, off, spec, p); for (auto& e : b.fits) okc += e.ok(); backend_used = std::string(to_string(b.stats.backend)); dev = b.stats.device_seconds; }
45+ out << json({{"kind", "runtime"}, {"experiment", "E2"}, {"S", S}, {"mode", mode}, {"backend_used", backend_used}, {"rep", rep}, {"wall_seconds", now() - t0}, {"device_seconds", dev}, {"converged", okc}, {"T_per_series", cat.size() / S}}).dump() << "\n"; }
46+ out.flush(); std::fprintf(stderr, "E2 runtime S=%zu done\n", S); }
47+ man.save(std::string(argv[2]) + ".manifest.json"); return 0;
48+#endif
49+}
added benchmarks/end_to_end/bench_e3_garch.cpp +58 −0
@@ -0,0 +1,58 @@
1+// E3 — GARCH-family panel estimation on real daily close-to-close returns (2024, from the 1-minute exports):
2+// per-symbol CPU QML fits (GARCH, GJR, EGARCH; Gaussian and Student-t): convergence rates, iterations, time, SE;
3+// GPU batched likelihood grid (P = 256 parameter vectors per series) used (i) as a profile-likelihood screen and
4+// (ii) to choose starting values — effect on convergence and time; 1-day-ahead variance forecasts evaluated against
5+// next-day RV (QLIKE) on the last 40 sessions (strict chronological split). Usage: bench_e3_garch <e0.json> <out.jsonl> [S]
6+#include <cstdio>
7+#include <fstream>
8+#include <nlohmann/json.hpp>
9+#include "raid/core/manifest.hpp"
10+#include "raid/core/hash.hpp"
11+#include "raid/core/thread_pool.hpp"
12+#include "raid/data/io.hpp"
13+#include "raid/data/calendar.hpp"
14+#include "raid/data/returns.hpp"
15+#include "raid/estimators/realized.hpp"
16+#include "raid/estimators/har.hpp"
17+#include "raid/models/garch.hpp"
18+#include "raid/backend/backend.hpp"
19+using namespace raid; using json = nlohmann::json;
20+namespace { f64 now() { return std::chrono::duration<f64>(std::chrono::steady_clock::now().time_since_epoch()).count(); } }
21+
22+int main(int argc, char** argv) {
23+ if (argc < 3) { std::fprintf(stderr, "usage: %s e0_universe.json out.jsonl [S]\n", argv[0]); return 2; }
24+#ifndef RAID_WITH_ARROW
25+ return 1;
26+#else
27+ json e0 = json::parse(std::ifstream(argv[1])); const usize Smax = argc > 3 ? static_cast<usize>(std::atoi(argv[3])) : 1000; std::ofstream out(argv[2], std::ios::app);
28+ ExperimentManifest man; man.experiment = "E3.garch"; man.created_at_utc = now_utc_iso(); man.raid_version = RAID_VERSION; man.host = host_info(); man.inputs["e0_universe.json"] = Sha256::of_file(argv[1]);
29+ MarketCalendar cal; std::map<std::string, std::vector<f64>> ret, rvd;
30+ for (auto& ex : e0["exports"]) { auto pb = data::read_bars_parquet(ex["path"].get<std::string>()); for (auto& [sym, b] : pb.series) { auto reg = b.filter_session(cal, SessionPolicy::regular); if (reg.n_sessions() < 240) continue; auto ir = data::intraday_returns(reg); std::vector<f64> r; for (usize k = 1; k < ir.close_to_close.size(); ++k) r.push_back(ir.close_to_close[k]); est::RealizedOptions ro; ro.plan.backend = Backend::cpu; auto m = est::realized_measures(ir, ro); ret[sym] = r; rvd[sym] = std::vector<f64>(m.rv.begin() + 1, m.rv.end()); } }
31+ const auto universe = e0["samples"]["1000"].get<std::vector<std::string>>(); std::vector<std::string> syms; for (auto& s : universe) if (ret.count(s) && syms.size() < Smax) syms.push_back(s);
32+ const usize S = syms.size(); std::fprintf(stderr, "E3: %zu symbols, ~%zu daily returns each\n", S, ret[syms[0]].size());
33+ const usize test = 40; // last 40 sessions held out for forecast evaluation
34+ // ---- (i) per-symbol fits, all models, CPU parallel over symbols
35+ struct Spec { const char* name; models::GarchModel m; models::GarchDist d; }; const std::vector<Spec> specs = {{"garch.n", models::GarchModel::garch, models::GarchDist::gaussian}, {"gjr.n", models::GarchModel::gjr, models::GarchDist::gaussian}, {"egarch.n", models::GarchModel::egarch, models::GarchDist::gaussian}, {"garch.t", models::GarchModel::garch, models::GarchDist::student_t}};
36+ for (auto& sp : specs) { std::vector<json> rows(S); const f64 t0 = now();
37+ ThreadPool::global().parallel_for(S, [&](usize a, usize b) { for (usize i = a; i < b; ++i) { auto& r = ret[syms[i]]; std::vector<f64> train(r.begin(), r.end() - static_cast<long>(test)); models::GarchFitOptions o; o.model = sp.m; o.dist = sp.d; o.forecast_horizon = 1; json row = {{"symbol", syms[i]}, {"model", sp.name}, {"n_train", train.size()}};
38+ try { const f64 f0 = now(); auto e = models::garch_fit(train, o); row["seconds"] = now() - f0; row["converged"] = e.ok(); row["iterations"] = e.convergence.iterations; row["fevals"] = e.convergence.function_evaluations; row["loglik"] = -e.loss; row["coef"] = e.coefficients; row["se"] = e.inference ? e.inference->std_errors : std::vector<f64>{}; row["persistence"] = e.extra.value("persistence", 0.0); row["warnings"] = e.warnings;
39+ // rolling 1-step forecasts over the test window WITHOUT refitting (parameters fixed at the training estimate; variance path updated with realized returns): QLIKE vs next-day RV
40+ if (e.ok()) { std::vector<f64> fc, act; for (usize k = 0; k < test; ++k) { std::vector<f64> hist(r.begin(), r.end() - static_cast<long>(test - k)); auto f = models::garch_forecast(e, hist, 1); fc.push_back(f[0]); act.push_back(rvd[syms[i]][r.size() - test + k]); } auto l = est::forecast_loss(act, fc); row["qlike_vs_rv"] = l.qlike; row["mse_vs_rv"] = l.mse; row["n_forecasts"] = l.n; std::vector<f64> naive; for (usize k = 0; k < test; ++k) naive.push_back(rvd[syms[i]][r.size() - test + k - 1]); auto ln = est::forecast_loss(act, naive); row["qlike_rw_rv"] = ln.qlike; } }
41+ catch (const RaidError& ex) { row["error"] = ex.what(); row["converged"] = false; } rows[i] = row; } });
42+ usize conv = 0; for (auto& r : rows) { conv += r.value("converged", false); r["kind"] = "fit"; r["experiment"] = "E3"; out << r.dump() << "\n"; }
43+ out << json({{"kind", "fit_summary"}, {"experiment", "E3"}, {"model", sp.name}, {"S", S}, {"converged", conv}, {"wall_seconds_all", now() - t0}, {"threads", ThreadPool::global().size()}}).dump() << "\n"; out.flush();
44+ std::fprintf(stderr, "E3 %s: %zu/%zu converged in %.1fs\n", sp.name, conv, S, now() - t0); }
45+ // ---- (ii) GPU grid screen: P = 256 (α, β, ω) combinations per series (μ = sample mean), batched NLL on Metal vs CPU-MT; best grid point as starting value → refit convergence/time
46+ { const usize P = 256; std::vector<f64> cat; std::vector<i64> off = {0}; std::vector<f64> params(S * P * 4); for (usize i = 0; i < S; ++i) { auto& r = ret[syms[i]]; std::vector<f64> train(r.begin(), r.end() - static_cast<long>(test)); cat.insert(cat.end(), train.begin(), train.end()); off.push_back(static_cast<i64>(cat.size())); f64 mu = 0, v = 0; for (f64 x : train) mu += x; mu /= train.size(); for (f64 x : train) v += (x - mu) * (x - mu); v /= train.size();
47+ usize q = 0; for (int ia = 0; ia < 16; ++ia) for (int ib = 0; ib < 16; ++ib) { const f64 alpha = 0.01 + 0.015 * ia, beta = 0.50 + 0.031 * ib; f64* th = params.data() + (i * P + q) * 4; th[0] = mu; th[2] = alpha; th[3] = beta; th[1] = alpha + beta < 0.999 ? v * (1 - alpha - beta) : v * 0.001; ++q; } }
48+ backend::Batch b{cat, off}; auto cpuN = backend::make_cpu_backend(0); std::shared_ptr<backend::Backend> gpu;
49+#ifdef RAID_ENABLE_METAL
50+ gpu = backend::make_metal_backend();
51+#endif
52+ std::vector<f64> nll_cpu, nll_gpu; for (int rep = 0; rep < 3; ++rep) { backend::KernelStats st; const f64 t0 = now(); nll_cpu = cpuN->garch_nll_batch(b, params, P, 4, 0, 0.0, &st); out << json({{"kind", "grid"}, {"experiment", "E3"}, {"backend", "cpuMT"}, {"S", S}, {"P", P}, {"rep", rep}, {"wall_seconds", now() - t0}}).dump() << "\n";
53+ if (gpu) { const f64 t1 = now(); nll_gpu = gpu->garch_nll_batch(b, params, P, 4, 0, 0.0, &st); f64 maxrel = 0; usize agree = 0; for (usize i = 0; i < S; ++i) { usize ac = 0, ag = 0; for (usize q = 1; q < P; ++q) { if (nll_cpu[i * P + q] < nll_cpu[i * P + ac]) ac = q; if (nll_gpu[i * P + q] < nll_gpu[i * P + ag]) ag = q; } agree += (ac == ag); for (usize q = 0; q < P; ++q) if (std::isfinite(nll_cpu[i * P + q]) && std::isfinite(nll_gpu[i * P + q])) maxrel = std::max(maxrel, std::abs(nll_cpu[i * P + q] - nll_gpu[i * P + q]) / std::abs(nll_cpu[i * P + q])); }
54+ out << json({{"kind", "grid"}, {"experiment", "E3"}, {"backend", "metal"}, {"S", S}, {"P", P}, {"rep", rep}, {"wall_seconds", now() - t1}, {"device_seconds", st.device_seconds}, {"max_rel_err_nll", maxrel}, {"argmin_agreement", agree}, {"S_total", S}}).dump() << "\n"; } }
55+ out.flush(); std::fprintf(stderr, "E3 grid screen done\n"); }
56+ man.save(std::string(argv[2]) + ".manifest.json"); return 0;
57+#endif
58+}
added benchmarks/end_to_end/bench_e4_connectedness.cpp +55 −0
@@ -0,0 +1,55 @@
1+// E4 — realized covariance and dynamic connectedness on real data: N ∈ {10, 30, 100} symbols, 5-minute synchronized
2+// returns (calendar-aware aggregation of the 1-minute bars) → daily realized covariance matrices (CPU; conditioning
3+// numbers, Ledoit–Wolf shrinkage), daily log-RV panel → rolling VAR(1) Diebold–Yilmaz total connectedness (window 120,
4+// H = 10): runtime, failures, totals. Memory per window and the N where VAR(1)+intercept becomes rank-limited are recorded.
5+// Usage: bench_e4_connectedness <e0.json> <out.jsonl>
6+#include <cstdio>
7+#include <fstream>
8+#include <set>
9+#include <algorithm>
10+#include <nlohmann/json.hpp>
11+#include "raid/core/manifest.hpp"
12+#include "raid/core/hash.hpp"
13+#include "raid/data/io.hpp"
14+#include "raid/data/calendar.hpp"
15+#include "raid/data/returns.hpp"
16+#include "raid/data/resample.hpp"
17+#include "raid/estimators/realized.hpp"
18+#include "raid/models/var.hpp"
19+#include "raid/core/thread_pool.hpp"
20+using namespace raid; using json = nlohmann::json;
21+namespace { f64 now() { return std::chrono::duration<f64>(std::chrono::steady_clock::now().time_since_epoch()).count(); } }
22+
23+int main(int argc, char** argv) {
24+ if (argc < 3) { std::fprintf(stderr, "usage: %s e0_universe.json out.jsonl\n", argv[0]); return 2; }
25+#ifndef RAID_WITH_ARROW
26+ return 1;
27+#else
28+ json e0 = json::parse(std::ifstream(argv[1])); std::ofstream out(argv[2], std::ios::app);
29+ ExperimentManifest man; man.experiment = "E4.connectedness"; man.created_at_utc = now_utc_iso(); man.raid_version = RAID_VERSION; man.host = host_info(); man.inputs["e0_universe.json"] = Sha256::of_file(argv[1]);
30+ MarketCalendar cal; const auto universe = e0["samples"]["1000"].get<std::vector<std::string>>();
31+ // load up to 100 symbols with full coverage; 5-minute regular-session bars; synchronized grid = the 79 bins per session
32+ std::map<std::string, BarSeries> five; std::map<std::string, std::vector<f64>> logrv;
33+ for (auto& ex : e0["exports"]) { if (five.size() >= 100) break; auto pb = data::read_bars_parquet(ex["path"].get<std::string>()); for (auto& [sym, b] : pb.series) { if (five.size() >= 100) break; auto reg = b.filter_session(cal, SessionPolicy::regular); auto q = reg.validate(cal); if (q.n_sessions < 250 || q.coverage < 0.98) continue; five[sym] = data::aggregate(reg, Interval::m5, cal); auto ir = data::intraday_returns(reg); est::RealizedOptions ro; ro.plan.backend = Backend::cpu; auto m = est::realized_measures(ir, ro); std::vector<f64> lv; for (f64 v : m.rv) lv.push_back(std::log(std::max(v, 1e-12))); logrv[sym] = lv; } }
34+ std::vector<std::string> syms; for (auto& s : universe) if (five.count(s)) syms.push_back(s); std::fprintf(stderr, "E4: %zu symbols with >= 250 sessions and coverage >= 0.98\n", syms.size());
35+ // common sessions
36+ std::set<Date> common; bool first = true; for (auto& s : syms) { std::set<Date> d(five[s].session_dates.begin(), five[s].session_dates.end()); if (first) { common = d; first = false; } else { std::set<Date> inter; for (auto x : common) if (d.count(x)) inter.insert(x); common = inter; } }
37+ std::vector<Date> sessions(common.begin(), common.end()); std::fprintf(stderr, "E4: %zu common sessions\n", sessions.size());
38+ for (usize N : {10ul, 30ul, 100ul}) { if (N > syms.size()) continue;
39+ // (a) daily realized covariance from synchronized 5-minute returns (bins matched by timestamp; a day is used only if all N have the full 79 bins)
40+ const f64 t0 = now(); usize days_ok = 0, days_skipped = 0; f64 cond_max = 0, cond_med = 0; std::vector<f64> conds; f64 lw_shrink_mean = 0;
41+ for (auto d : sessions) { std::vector<std::vector<f64>> R(N); bool ok = true; for (usize i = 0; i < N && ok; ++i) { auto& b = five[syms[i]]; usize k = 0; while (k < b.n_sessions() && b.session_dates[k] != d) ++k; if (k == b.n_sessions()) { ok = false; break; } auto c = b.session_closes(k); const usize expect = cal.expected_regular_bars(d, Interval::m5); if (c.size() != expect) { ok = false; break; } R[i] = data::returns(c); }
42+ if (!ok) { ++days_skipped; continue; } const usize M = R[0].size(); Eigen::MatrixXd Rm(static_cast<Eigen::Index>(M), static_cast<Eigen::Index>(N)); for (usize i = 0; i < N; ++i) for (usize j = 0; j < M; ++j) Rm(static_cast<Eigen::Index>(j), static_cast<Eigen::Index>(i)) = R[i][j];
43+ auto rc = est::realized_covariance(Rm); Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(rc.cov); const f64 cond = es.eigenvalues().maxCoeff() / std::max(es.eigenvalues().minCoeff(), 1e-300); conds.push_back(cond); cond_max = std::max(cond_max, cond); auto lw = models::ledoit_wolf(Rm, true); lw_shrink_mean += lw.shrinkage; ++days_ok; }
44+ if (!conds.empty()) { std::sort(conds.begin(), conds.end()); cond_med = conds[conds.size() / 2]; lw_shrink_mean /= days_ok; }
45+ out << json({{"kind", "rcov"}, {"experiment", "E4"}, {"N", N}, {"days_ok", days_ok}, {"days_skipped", days_skipped}, {"M_per_day", 78}, {"cond_median", cond_med}, {"cond_max", cond_max}, {"rank_deficient_possible", N > 78}, {"ledoit_wolf_shrinkage_mean", lw_shrink_mean}, {"wall_seconds", now() - t0}}).dump() << "\n";
46+ // (b) rolling Diebold–Yilmaz on the daily log-RV panel (aligned on common sessions)
47+ const usize T = sessions.size(); Eigen::MatrixXd Y(static_cast<Eigen::Index>(T), static_cast<Eigen::Index>(N));
48+ for (usize i = 0; i < N; ++i) { auto& b = five[syms[i]]; auto& lv = logrv[syms[i]]; for (usize t = 0; t < T; ++t) { usize k = 0; while (b.session_dates[k] != sessions[t]) ++k; Y(static_cast<Eigen::Index>(t), static_cast<Eigen::Index>(i)) = lv[k]; } }
49+ for (usize window : {120ul, 180ul}) { if (window >= T || window <= N + 12) { out << json({{"kind", "dy"}, {"experiment", "E4"}, {"N", N}, {"window", window}, {"skipped", "window must exceed N·p + p + 10 and be < T"}, {"T", T}}).dump() << "\n"; continue; }
50+ for (int rep = 0; rep < 3; ++rep) { const f64 t1 = now(); auto r = models::rolling_connectedness(Y, 1, 10, window, 1); f64 mean_total = 0; usize nn = 0; for (f64 v : r.total) if (std::isfinite(v)) { mean_total += v; ++nn; } if (nn) mean_total /= nn;
51+ out << json({{"kind", "dy"}, {"experiment", "E4"}, {"N", N}, {"window", window}, {"rep", rep}, {"n_windows", r.n_windows}, {"failures", r.failures}, {"mean_total", mean_total}, {"wall_seconds", now() - t1}, {"threads", ThreadPool::global().size()}, {"peak_rss", peak_rss_bytes()}}).dump() << "\n"; } }
52+ out.flush(); std::fprintf(stderr, "E4 N=%zu done\n", N); }
53+ man.save(std::string(argv[2]) + ".manifest.json"); return 0;
54+#endif
55+}
added benchmarks/end_to_end/bench_e5_inference.cpp +48 −0
@@ -0,0 +1,48 @@
1+// E5 — inference at scale and reproducibility: (a) GARCH(1,1) Monte Carlo R = 1 000 (CPU parallel): bias, RMSE, coverage,
2+// failures, time; (b) HAR-RV h=1/5 HAC coverage R = 1 000; (c) stationary-bootstrap RV intervals on real sessions
3+// (coverage of the "long-sample" IV proxy is not identifiable — we report interval widths and reproducibility);
4+// (d) bitwise reproducibility: same seed → identical bootstrap statistics across thread counts, and identical Metal
5+// realized measures across runs; CPU-vs-Metal differences reported in ulps-equivalent relative error.
6+// Usage: bench_e5_inference <out.jsonl> [R]
7+#include <cstdio>
8+#include <fstream>
9+#include <atomic>
10+#include <nlohmann/json.hpp>
11+#include "raid/core/manifest.hpp"
12+#include "raid/core/rng.hpp"
13+#include "raid/core/thread_pool.hpp"
14+#include "raid/models/garch.hpp"
15+#include "raid/estimators/har.hpp"
16+#include "raid/estimators/realized.hpp"
17+#include "raid/statistics/bootstrap.hpp"
18+#include "raid/statistics/reductions.hpp"
19+using namespace raid; using json = nlohmann::json;
20+namespace { f64 now() { return std::chrono::duration<f64>(std::chrono::steady_clock::now().time_since_epoch()).count(); } }
21+
22+int main(int argc, char** argv) {
23+ if (argc < 2) { std::fprintf(stderr, "usage: %s out.jsonl [R]\n", argv[0]); return 2; }
24+ const int R = argc > 2 ? std::atoi(argv[2]) : 1000; std::ofstream out(argv[1], std::ios::app);
25+ ExperimentManifest man; man.experiment = "E5.inference"; man.created_at_utc = now_utc_iso(); man.raid_version = RAID_VERSION; man.host = host_info(); man.seed = 20261102; man.parameters = {{"R", std::to_string(R)}};
26+ // (a) GARCH MC
27+ for (auto& [n, label] : std::vector<std::pair<usize, const char*>>{{500, "n500"}, {2000, "n2000"}}) { const double tr[4] = {0.0, 0.02, 0.08, 0.90}; std::vector<std::array<double, 4>> est(R), se(R); std::vector<int> okv(R, 0), its(R, 0); const f64 t0 = now();
28+ ThreadPool::global().parallel_for(R, [&](usize a, usize b) { for (usize rep = a; rep < b; ++rep) { Rng rng(20261102, rep); std::vector<double> r(n); double s2 = tr[1] / (1 - tr[2] - tr[3]), e = 0; for (usize t = 0; t < n; ++t) { s2 = tr[1] + tr[2] * e * e + tr[3] * s2; e = std::sqrt(s2) * rng.normal(); r[t] = e; } models::GarchFitOptions o; auto f = models::garch_fit(r, o); its[rep] = f.convergence.iterations; if (!f.ok()) continue; okv[rep] = 1; for (int j = 0; j < 4; ++j) { est[rep][j] = f.coefficients[j]; se[rep][j] = f.inference->std_errors[j]; } } });
29+ json row = {{"kind", "garch_mc"}, {"experiment", "E5"}, {"n", n}, {"R", R}, {"wall_seconds", now() - t0}, {"threads", ThreadPool::global().size()}}; int ok = 0; for (int v : okv) ok += v; row["converged"] = ok;
30+ for (int j = 0; j < 4; ++j) { double bias = 0, mse = 0; int cov = 0; for (int rep = 0; rep < R; ++rep) { if (!okv[rep]) continue; double d = est[rep][j] - tr[j]; bias += d; mse += d * d; if (std::abs(d) <= 1.96 * se[rep][j]) ++cov; } const char* nm[4] = {"mu", "omega", "alpha", "beta"}; row[nm[j]] = {{"bias", bias / ok}, {"rmse", std::sqrt(mse / ok)}, {"coverage95", static_cast<double>(cov) / ok}}; }
31+ out << row.dump() << "\n"; out.flush(); std::fprintf(stderr, "E5 garch MC %s: %d/%d converged %.1fs\n", label, ok, R, now() - t0); }
32+ // (b) HAR HAC coverage
33+ for (int h : {1, 5}) { auto simulate = [](usize nn, u64 seed) { Rng g(4242, seed); std::vector<double> rv(nn); double lv = std::log(1e-4); for (usize t = 0; t < nn; ++t) { lv = 0.3 * std::log(1e-4) + 0.7 * lv + 0.4 * g.normal(); rv[t] = std::exp(lv); } return rv; };
34+ est::HarSpec spec; spec.horizon = h; auto big = simulate(400000, 999); auto pseudo = est::har_fit(big, spec); std::vector<std::array<int, 4>> cov(R); const f64 t0 = now();
35+ ThreadPool::global().parallel_for(R, [&](usize a, usize b) { for (usize rep = a; rep < b; ++rep) { auto rv = simulate(1500, rep); auto f = est::har_fit(rv, spec); for (int j = 0; j < 4; ++j) cov[rep][j] = std::abs(f.coefficients[j] - pseudo.coefficients[j]) <= 1.96 * f.inference->std_errors[j]; } });
36+ json row = {{"kind", "har_mc"}, {"experiment", "E5"}, {"h", h}, {"T", 1500}, {"R", R}, {"wall_seconds", now() - t0}}; for (int j = 0; j < 4; ++j) { int c = 0; for (int rep = 0; rep < R; ++rep) c += cov[rep][j]; row["coverage95"][j] = static_cast<double>(c) / R; } out << row.dump() << "\n"; out.flush(); std::fprintf(stderr, "E5 har h=%d done\n", h); }
37+ // (d) reproducibility
38+ { Rng g(99); std::vector<double> x(5000); for (auto& v : x) v = 1e-3 * g.student_t(5.0); auto st = [](std::span<const double> v) { return stats::sum_squares<double>(v); };
39+ stats::BootstrapOptions o; o.replicas = 2000; o.mean_block = 10; std::vector<std::vector<double>> results; std::vector<unsigned> thr = {1, 4, 18}; for (unsigned t : thr) { o.threads = t; auto b = stats::bootstrap(x, st, o); results.push_back(b.statistics); }
40+ bool same = results[0] == results[1] && results[1] == results[2]; out << json({{"kind", "repro_bootstrap"}, {"experiment", "E5"}, {"replicas", 2000}, {"threads", thr}, {"bitwise_identical_across_threads", same}}).dump() << "\n";
41+ std::vector<i64> off; for (usize s = 0; s <= 50; ++s) off.push_back(static_cast<i64>(s * 100)); backend::Batch b{x, off}; est::RealizedOptions rc; rc.plan.backend = Backend::cpu; auto c1 = est::realized_measures_batch(b, rc); rc.plan.threads = 1; auto c2 = est::realized_measures_batch(b, rc);
42+ json rr = {{"kind", "repro_realized"}, {"experiment", "E5"}, {"cpu_threads_vs_1_identical", c1.rv == c2.rv}};
43+#ifdef RAID_ENABLE_METAL
44+ est::RealizedOptions rm; rm.plan.backend = Backend::metal; auto m1 = est::realized_measures_batch(b, rm), m2 = est::realized_measures_batch(b, rm); rr["metal_runs_identical"] = m1.rv == m2.rv && m1.bpv == m2.bpv && m1.rq == m2.rq; double maxrel = 0; for (usize s = 0; s < c1.rv.size(); ++s) maxrel = std::max(maxrel, std::abs(m1.rv[s] - c1.rv[s]) / c1.rv[s]); rr["metal_vs_cpu_max_rel_rv"] = maxrel; rr["metal_backend_used"] = std::string(to_string(m1.stats.backend));
45+#endif
46+ out << rr.dump() << "\n"; }
47+ man.save(std::string(argv[1]) + ".manifest.json"); return 0;
48+}
added benchmarks/end_to_end/bench_e6_pipeline.cpp +42 −0
@@ -0,0 +1,42 @@
1+// E6 — end-to-end streaming pipeline: FinData export (cached Parquet) → Arrow/Parquet read → session filter → returns →
2+// realized measures (CPU / Metal), with stage latencies, bytes, peak RSS and the number of full copies of the price
3+// columns. Baselines (pandas / polars / duckdb) are measured by experiments/scripts/e6_baselines.py on the same files.
4+// Usage: bench_e6_pipeline <e0_universe.json> <out.jsonl> [n_files] [reps]
5+#include <cstdio>
6+#include <fstream>
7+#include <nlohmann/json.hpp>
8+#include "raid/core/manifest.hpp"
9+#include "raid/core/hash.hpp"
10+#include "raid/data/io.hpp"
11+#include "raid/data/calendar.hpp"
12+#include "raid/data/returns.hpp"
13+#include "raid/estimators/realized.hpp"
14+using namespace raid; using json = nlohmann::json;
15+namespace { f64 now() { return std::chrono::duration<f64>(std::chrono::steady_clock::now().time_since_epoch()).count(); } }
16+
17+int main(int argc, char** argv) {
18+ if (argc < 3) { std::fprintf(stderr, "usage: %s e0_universe.json out.jsonl [n_files] [reps]\n", argv[0]); return 2; }
19+#ifndef RAID_WITH_ARROW
20+ std::fprintf(stderr, "E6 requires the Arrow build\n"); return 1;
21+#else
22+ json e0 = json::parse(std::ifstream(argv[1])); const int nf = argc > 3 ? std::atoi(argv[3]) : 4; const int reps = argc > 4 ? std::atoi(argv[4]) : 3; std::ofstream out(argv[2], std::ios::app);
23+ ExperimentManifest man; man.experiment = "E6.pipeline"; man.created_at_utc = now_utc_iso(); man.raid_version = RAID_VERSION; man.host = host_info(); man.inputs["e0_universe.json"] = Sha256::of_file(argv[1]);
24+ MarketCalendar cal; int fi = 0;
25+ for (auto& ex : e0["exports"]) { if (fi++ >= nf) break; const std::string path = ex["path"]; const usize bytes = ex["bytes"];
26+ for (auto backend_name : {"cpu", "metal"}) for (int rep = 0; rep < reps; ++rep) {
27+ const u64 rss0 = peak_rss_bytes(); const f64 t0 = now();
28+ auto pb = data::read_bars_parquet(path); const f64 t_read = now(); // copy 1: Arrow → BarSeries columns (+ sort/dedupe)
29+ std::map<std::string, data::IntradayReturns> rets; usize bars = 0, ret_n = 0;
30+ for (auto& [sym, b] : pb.series) { bars += b.size(); auto reg = b.filter_session(cal, SessionPolicy::regular); rets[sym] = data::intraday_returns(reg); ret_n += rets[sym].r.size(); } // copy 2: regular filter; copy 3: returns
31+ const f64 t_prep = now();
32+ std::vector<f64> v; std::vector<i64> off = {0}; for (auto& [sym, ir] : rets) { for (usize k = 0; k + 1 < ir.session_offsets.size(); ++k) { v.insert(v.end(), ir.r.begin() + ir.session_offsets[k], ir.r.begin() + ir.session_offsets[k + 1]); off.push_back(static_cast<i64>(v.size())); } } // copy 4: batch concat
33+ const f64 t_batch = now();
34+ est::RealizedOptions ro; ro.plan.backend = backend_from_string(backend_name); ro.plan.allow_fallback = true; auto m = est::realized_measures_batch(backend::Batch{v, off}, ro); const f64 t_end = now();
35+ out << json({{"experiment", "E6"}, {"file", path}, {"file_bytes", bytes}, {"backend_requested", backend_name}, {"backend_used", std::string(to_string(m.stats.backend))}, {"rep", rep}, {"symbols", pb.series.size()}, {"bars", bars}, {"returns", ret_n}, {"segments", off.size() - 1},
36+ {"read_seconds", t_read - t0}, {"prep_seconds", t_prep - t_read}, {"batch_seconds", t_batch - t_prep}, {"estimate_seconds", t_end - t_batch}, {"total_seconds", t_end - t0}, {"device_seconds", m.stats.device_seconds},
37+ {"bars_per_second", bars / (t_end - t0)}, {"peak_rss_before", rss0}, {"peak_rss_after", peak_rss_bytes()}, {"zero_copy_possible", pb.metadata.count("zero_copy_possible") ? pb.metadata["zero_copy_possible"] : "?"}, {"column_copies", 4}, {"duplicates_dropped", pb.duplicates_dropped}}).dump() << "\n";
38+ std::fprintf(stderr, "%s %s rep %d: %zu bars in %.2fs (read %.2f prep %.2f batch %.2f est %.3f)\n", path.c_str(), backend_name, rep, bars, t_end - t0, t_read - t0, t_prep - t_read, t_batch - t_prep, t_end - t_batch); }
39+ }
40+ man.save(std::string(argv[2]) + ".manifest.json"); return 0;
41+#endif
42+}
added experiments/results/e0_universe.json +2370 −0
@@ -0,0 +1,2370 @@
1+{
2+ "config": {
3+ "dataset_id": "market_bars.stock.1m.raw",
4+ "year": 2024,
5+ "start": "2024-01-02",
6+ "end": "2024-12-31",
7+ "min_sessions_total": 250,
8+ "sample_sizes": [
9+ 1,
10+ 10,
11+ 100,
12+ 1000
13+ ],
14+ "seed": 20261102,
15+ "symbols_per_export": 50,
16+ "exclude_delisted_suffix": true
17+ },
18+ "n_coverage": 14600,
19+ "n_active": 6046,
20+ "samples": {
21+ "1": [
22+ "FIVN"
23+ ],
24+ "10": [
25+ "FIVN",
26+ "FISV",
27+ "POET",
28+ "CRNC",
29+ "SIBN",
30+ "PIPR",
31+ "W",
32+ "VNDA",
33+ "DNN",
34+ "BAC.E"
35+ ],
36+ "100": [
37+ "FIVN",
38+ "FISV",
39+ "POET",
40+ "CRNC",
41+ "SIBN",
42+ "PIPR",
43+ "W",
44+ "VNDA",
45+ "DNN",
46+ "BAC.E",
47+ "GM",
48+ "SACH",
49+ "PKG",
50+ "RLJ.A",
51+ "SPWR",
52+ "NTR",
53+ "TSCO",
54+ "PLNT",
55+ "AXR",
56+ "TEI",
57+ "BAC.N",
58+ "YHGJ",
59+ "DMRC",
60+ "NAN",
61+ "GSIT",
62+ "EAD",
63+ "BLDR",
64+ "USB.R",
65+ "JXN.A",
66+ "ZNTL",
67+ "EFR",
68+ "IGTA",
69+ "FENC",
70+ "AVBH",
71+ "FFBW",
72+ "DRMA",
73+ "SLMT",
74+ "DTIL",
75+ "XPOF",
76+ "AZTR",
77+ "TRVG",
78+ "ORKA",
79+ "SCL",
80+ "FBNC",
81+ "DHCNI",
82+ "PCT",
83+ "SWK",
84+ "HYFT",
85+ "FCUV",
86+ "LPTX",
87+ "CAN",
88+ "ANVS",
89+ "NFJ",
90+ "ARMK",
91+ "RCI",
92+ "SUPV",
93+ "SPRC",
94+ "VCV",
95+ "LITE",
96+ "BHFAP",
97+ "ROP",
98+ "ATMCR",
99+ "WETH",
100+ "FUBO",
101+ "CLBT",
102+ "AVAH",
103+ "WWW",
104+ "WHR",
105+ "BTMD",
106+ "AHH.A",
107+ "VOR",
108+ "IBCP",
109+ "NA",
110+ "BEAT",
111+ "PEB.G",
112+ "PUK",
113+ "TRGP",
114+ "DGICA",
115+ "UCL",
116+ "NNI",
117+ "SF.D",
118+ "NUE",
119+ "UMBF",
120+ "STZ",
121+ "ARQQW",
122+ "AIR",
123+ "CHAI",
124+ "PAYX",
125+ "AKAM",
126+ "AAP",
127+ "CZNC",
128+ "LTH",
129+ "AME",
130+ "SVVC",
131+ "CXW",
132+ "MNSO",
133+ "MMLP",
134+ "SPNT",
135+ "FORL",
136+ "JKHY"
137+ ],
138+ "1000": [
139+ "FIVN",
140+ "FISV",
141+ "POET",
142+ "CRNC",
143+ "SIBN",
144+ "PIPR",
145+ "W",
146+ "VNDA",
147+ "DNN",
148+ "BAC.E",
149+ "GM",
150+ "SACH",
151+ "PKG",
152+ "RLJ.A",
153+ "SPWR",
154+ "NTR",
155+ "TSCO",
156+ "PLNT",
157+ "AXR",
158+ "TEI",
159+ "BAC.N",
160+ "YHGJ",
161+ "DMRC",
162+ "NAN",
163+ "GSIT",
164+ "EAD",
165+ "BLDR",
166+ "USB.R",
167+ "JXN.A",
168+ "ZNTL",
169+ "EFR",
170+ "IGTA",
171+ "FENC",
172+ "AVBH",
173+ "FFBW",
174+ "DRMA",
175+ "SLMT",
176+ "DTIL",
177+ "XPOF",
178+ "AZTR",
179+ "TRVG",
180+ "ORKA",
181+ "SCL",
182+ "FBNC",
183+ "DHCNI",
184+ "PCT",
185+ "SWK",
186+ "HYFT",
187+ "FCUV",
188+ "LPTX",
189+ "CAN",
190+ "ANVS",
191+ "NFJ",
192+ "ARMK",
193+ "RCI",
194+ "SUPV",
195+ "SPRC",
196+ "VCV",
197+ "LITE",
198+ "BHFAP",
199+ "ROP",
200+ "ATMCR",
201+ "WETH",
202+ "FUBO",
203+ "CLBT",
204+ "AVAH",
205+ "WWW",
206+ "WHR",
207+ "BTMD",
208+ "AHH.A",
209+ "VOR",
210+ "IBCP",
211+ "NA",
212+ "BEAT",
213+ "PEB.G",
214+ "PUK",
215+ "TRGP",
216+ "DGICA",
217+ "UCL",
218+ "NNI",
219+ "SF.D",
220+ "NUE",
221+ "UMBF",
222+ "STZ",
223+ "ARQQW",
224+ "AIR",
225+ "CHAI",
226+ "PAYX",
227+ "AKAM",
228+ "AAP",
229+ "CZNC",
230+ "LTH",
231+ "AME",
232+ "SVVC",
233+ "CXW",
234+ "MNSO",
235+ "MMLP",
236+ "SPNT",
237+ "FORL",
238+ "JKHY",
239+ "AEM",
240+ "STE",
241+ "ISPOW",
242+ "SDOT",
243+ "CRDO",
244+ "PCYO",
245+ "XOM",
246+ "KIO",
247+ "REGCO",
248+ "BLX",
249+ "OCCI",
250+ "ZAPPW",
251+ "MUSA",
252+ "RDCM",
253+ "RCKT",
254+ "FAMI",
255+ "RILYT",
256+ "IPWR",
257+ "TLSIW",
258+ "IEP",
259+ "SITC",
260+ "CC",
261+ "ORMP",
262+ "DXCM",
263+ "RPT",
264+ "GAP",
265+ "NWG",
266+ "PGP",
267+ "CRCT",
268+ "TAPM",
269+ "AFRM",
270+ "AXIA",
271+ "SHIP",
272+ "XBIO",
273+ "ILAG",
274+ "GBLI",
275+ "FSLR",
276+ "BGM",
277+ "TRUP",
278+ "ADMA",
279+ "OSIS",
280+ "AMOD",
281+ "ISPC",
282+ "CTOS",
283+ "HIMS",
284+ "UONE",
285+ "LAC",
286+ "PK",
287+ "ABR.F",
288+ "BRAG",
289+ "SHFSW",
290+ "HPP.C",
291+ "CHNR",
292+ "SHPH",
293+ "ENTX",
294+ "MFA.B",
295+ "NPCT",
296+ "FINS",
297+ "CZWI",
298+ "CG",
299+ "AU",
300+ "IKT",
301+ "CERT",
302+ "NPO",
303+ "RWAY",
304+ "BBVA",
305+ "TARA",
306+ "DUK.A",
307+ "CRTDW",
308+ "INVZW",
309+ "MS.K",
310+ "CVM",
311+ "WCFB",
312+ "ATOM",
313+ "NOVT",
314+ "SMIT",
315+ "LBTYB",
316+ "ACR",
317+ "EOCN",
318+ "BOC",
319+ "BGX",
320+ "MRT",
321+ "WKC",
322+ "SUAC",
323+ "TV",
324+ "GHG",
325+ "FRPH",
326+ "EVT",
327+ "ASTL",
328+ "MU",
329+ "PTA",
330+ "LPCN",
331+ "INSM",
332+ "PEB.E",
333+ "ABLV",
334+ "ARCT",
335+ "TVC",
336+ "IDXG",
337+ "GSBD",
338+ "TSLX",
339+ "NKE",
340+ "COST",
341+ "ACA",
342+ "NTAP",
343+ "PEBO",
344+ "AEO",
345+ "HWBK",
346+ "GIC",
347+ "BAC.M",
348+ "ECBK",
349+ "RDNT",
350+ "SPCB",
351+ "MDWD",
352+ "ANGHW",
353+ "EPD",
354+ "NEA",
355+ "VRTX",
356+ "BIIB",
357+ "TDY",
358+ "JOB",
359+ "FWRG",
360+ "CPHI",
361+ "DUO",
362+ "SMP",
363+ "EYE",
364+ "BCPC",
365+ "CIM.A",
366+ "CNP",
367+ "BCDS",
368+ "VGASW",
369+ "XPO",
370+ "UAN",
371+ "CWD",
372+ "DRVN",
373+ "HLSQ",
374+ "ATRA",
375+ "ZIVOW",
376+ "LCFYW",
377+ "SMFL",
378+ "LDTCW",
379+ "CCOI",
380+ "NIVF",
381+ "BP",
382+ "SCE.M",
383+ "BUSE",
384+ "TCCO",
385+ "RGCO",
386+ "MIDD",
387+ "RDW",
388+ "CMT",
389+ "ENX",
390+ "UBS",
391+ "OSPN",
392+ "KGC",
393+ "LKFT",
394+ "STM",
395+ "AOGO",
396+ "HTD",
397+ "GOOS",
398+ "VRMEW",
399+ "BBIO",
400+ "HRZN",
401+ "PSA.K",
402+ "NXGL",
403+ "SCYX",
404+ "KMI",
405+ "NXP",
406+ "MGM",
407+ "HYFM",
408+ "UOKA",
409+ "FBYDW",
410+ "GUT",
411+ "FSTR",
412+ "SAJ",
413+ "MCI",
414+ "DGICB",
415+ "CMP",
416+ "AAPL",
417+ "OFED",
418+ "BBDC",
419+ "WTBA",
420+ "USGO",
421+ "MLKN",
422+ "TRU",
423+ "ARCC",
424+ "TLF",
425+ "GFF",
426+ "RSKD",
427+ "VEL",
428+ "TCRX",
429+ "ALVO",
430+ "GLLIW",
431+ "OSS",
432+ "RMBI",
433+ "RZC",
434+ "KNTK",
435+ "CMRA",
436+ "PAHC",
437+ "TACT",
438+ "QVCD",
439+ "PMCB",
440+ "REAX",
441+ "FFC",
442+ "AIXI",
443+ "FGB",
444+ "HYI",
445+ "SHAK",
446+ "WTMA",
447+ "DBI",
448+ "CLVRW",
449+ "ZION",
450+ "GIB",
451+ "DCOY",
452+ "RCON",
453+ "CANG",
454+ "COFS",
455+ "KNF",
456+ "ZWS",
457+ "DRS",
458+ "CNSY",
459+ "ETJ",
460+ "GEN",
461+ "UCTT",
462+ "ADSE",
463+ "SOWG",
464+ "SLDPW",
465+ "SLVM",
466+ "PHD",
467+ "CCEP",
468+ "KULR",
469+ "TMP",
470+ "TAC",
471+ "PNI",
472+ "MHLA",
473+ "REI",
474+ "TSBK",
475+ "NVNO",
476+ "DLR.L",
477+ "STNE",
478+ "INFU",
479+ "MBIN",
480+ "AGL",
481+ "RITM",
482+ "MAT",
483+ "OGCP",
484+ "BOWN",
485+ "ZYME",
486+ "BEN",
487+ "KMT",
488+ "AEG",
489+ "FMBH",
490+ "ZDGE",
491+ "GEL",
492+ "BIRK",
493+ "EXFY",
494+ "VSSYW",
495+ "MSAIW",
496+ "VKQ",
497+ "FLYX",
498+ "XELB",
499+ "DOUG",
500+ "SOHON",
501+ "INDB",
502+ "INVE",
503+ "GJT",
504+ "GTX",
505+ "CASH",
506+ "ARBK",
507+ "BEPC",
508+ "CALA",
509+ "OBE",
510+ "LEU",
511+ "ASA",
512+ "WINA",
513+ "HLIO",
514+ "SHFS",
515+ "MOH",
516+ "PGYWW",
517+ "NGL",
518+ "BKN",
519+ "BBAR",
520+ "RDNW",
521+ "YCBD.A",
522+ "MO",
523+ "BGT",
524+ "VUZI",
525+ "FBIOP",
526+ "COLD",
527+ "BOKF",
528+ "EFT",
529+ "NBSTU",
530+ "YETI",
531+ "MCOMW",
532+ "VLY",
533+ "DBRG.J",
534+ "KUKE",
535+ "GTN.A",
536+ "LIQT",
537+ "RDIB",
538+ "BF.B",
539+ "CMC",
540+ "OGN",
541+ "MCB",
542+ "TSQ",
543+ "AEMD",
544+ "NEOVW",
545+ "KLRS",
546+ "CIG",
547+ "GECC",
548+ "DLNG.A",
549+ "IMPP",
550+ "MHK",
551+ "BIDU",
552+ "CBSH",
553+ "MTRN",
554+ "BKU",
555+ "CELUW",
556+ "OLB",
557+ "YOTAR",
558+ "NOA",
559+ "IKNA",
560+ "U",
561+ "MLEC",
562+ "IOR",
563+ "TNET",
564+ "RTB",
565+ "GRI",
566+ "MLM",
567+ "SEI",
568+ "MITI",
569+ "HPE",
570+ "KRO",
571+ "OESX",
572+ "PETS",
573+ "NEWTZ",
574+ "GNW",
575+ "HSCSW",
576+ "SNDR",
577+ "LWLG",
578+ "RLJ",
579+ "SBAC",
580+ "ZIM",
581+ "CETXP",
582+ "PPTA",
583+ "ALL.B",
584+ "MESO",
585+ "MDBH",
586+ "CWST",
587+ "JWEL",
588+ "RRX",
589+ "CRTO",
590+ "PCG.I",
591+ "PSQH",
592+ "SOJC",
593+ "CHCO",
594+ "FUTU",
595+ "PFBC",
596+ "IH",
597+ "SEVN",
598+ "BHFAL",
599+ "IESC",
600+ "INDP",
601+ "HAIN",
602+ "NBBK",
603+ "INTT",
604+ "GRBK",
605+ "STC",
606+ "BALL",
607+ "XEL",
608+ "NKX",
609+ "MBNKP",
610+ "DIT",
611+ "CERS",
612+ "GTEC",
613+ "BBWI",
614+ "ENLV",
615+ "RL",
616+ "MPAA",
617+ "NEUP",
618+ "UMH.D",
619+ "RS",
620+ "CARS",
621+ "FENG",
622+ "CCM",
623+ "MSEX",
624+ "SYTAW",
625+ "SGLY",
626+ "DWSN",
627+ "LESL",
628+ "JMIA",
629+ "DKNG",
630+ "HOLOW",
631+ "FNUC",
632+ "OMC",
633+ "OCEAW",
634+ "OR",
635+ "GEGGL",
636+ "GGR",
637+ "TCRT",
638+ "FTAIN",
639+ "SAN",
640+ "LRN",
641+ "FTII",
642+ "ABSI",
643+ "SF",
644+ "AVO",
645+ "MKC.V",
646+ "MCAGR",
647+ "TC",
648+ "CATY",
649+ "IGTAR",
650+ "PDYN",
651+ "BFLY",
652+ "XNET",
653+ "FGI",
654+ "PPSI",
655+ "TILE",
656+ "MXF",
657+ "OXLCN",
658+ "NTWK",
659+ "HR",
660+ "SONY",
661+ "AURE",
662+ "RIG",
663+ "PACB",
664+ "BGC",
665+ "MIRA",
666+ "NRIM",
667+ "DMB",
668+ "OPY",
669+ "MIO",
670+ "E",
671+ "IMTE",
672+ "FOSL",
673+ "VIAV",
674+ "DB",
675+ "ARWR",
676+ "JILL",
677+ "LPL",
678+ "BURL",
679+ "STRO",
680+ "ATGL",
681+ "BML.L",
682+ "GNFT",
683+ "VOD",
684+ "HYT",
685+ "MHH",
686+ "KMDA",
687+ "CTNT",
688+ "KEY.L",
689+ "RILYL",
690+ "NEE.R",
691+ "CNF",
692+ "LNSR",
693+ "PNBK",
694+ "ENB",
695+ "OVLY",
696+ "ALMU",
697+ "HTH",
698+ "ATEC",
699+ "APPN",
700+ "MAN",
701+ "AMBP",
702+ "CRIS",
703+ "ELVA",
704+ "FPI",
705+ "ORC",
706+ "GWW",
707+ "RF.E",
708+ "SFST",
709+ "TAK",
710+ "COO",
711+ "USCB",
712+ "WAL",
713+ "WTFCP",
714+ "HLGN",
715+ "HCVIW",
716+ "EXK",
717+ "OPCH",
718+ "BMBL",
719+ "GECCO",
720+ "SOND",
721+ "HPS",
722+ "MXE",
723+ "HPK",
724+ "IDT",
725+ "NRC",
726+ "DDS",
727+ "GDV.H",
728+ "QUAD",
729+ "MITT.B",
730+ "GAM",
731+ "USB.Q",
732+ "TAYD",
733+ "TCBX",
734+ "ARES",
735+ "DTSS",
736+ "FGN",
737+ "LNAI",
738+ "BZUN",
739+ "BFS.D",
740+ "SMRT",
741+ "ARE",
742+ "BNY",
743+ "TPR",
744+ "BFS.E",
745+ "NXDT",
746+ "PBYI",
747+ "GLAD",
748+ "NERV",
749+ "CHSCM",
750+ "ACN",
751+ "OUT",
752+ "NLY.I",
753+ "MDB",
754+ "CLST",
755+ "ACT",
756+ "PRKS",
757+ "ERAS",
758+ "RDVT",
759+ "WFCF",
760+ "QFIN",
761+ "NXPLW",
762+ "OMH",
763+ "BVFL",
764+ "UVSP",
765+ "LCID",
766+ "NOV",
767+ "RLAY",
768+ "BNTC",
769+ "ALLY",
770+ "DSL",
771+ "OABIW",
772+ "ETW",
773+ "KMPR",
774+ "SUZ",
775+ "FFBC",
776+ "ETN",
777+ "PW.A",
778+ "NVNI",
779+ "TDOC",
780+ "NAMSW",
781+ "STWD",
782+ "ACNB",
783+ "FNWB",
784+ "BAOS",
785+ "BPOP",
786+ "DNTH",
787+ "FAX",
788+ "NWN",
789+ "UPXI",
790+ "BTCS",
791+ "LMNR",
792+ "HOOD",
793+ "RMCO",
794+ "GBX",
795+ "DVLT",
796+ "XTLB",
797+ "EME",
798+ "KUST",
799+ "KITTW",
800+ "NSA.A",
801+ "RCUS",
802+ "HBANM",
803+ "JCE",
804+ "LDTC",
805+ "UL",
806+ "AMRN",
807+ "ELF",
808+ "BL",
809+ "MUE",
810+ "UP",
811+ "HASI",
812+ "BEKE",
813+ "BTAI",
814+ "NESR",
815+ "PJT",
816+ "HTCR",
817+ "CCSI",
818+ "ABTS",
819+ "SKYW",
820+ "FTIIW",
821+ "EPR.G",
822+ "IQI",
823+ "MGA",
824+ "HIND",
825+ "CRVS",
826+ "OZ",
827+ "ALNY",
828+ "MRM",
829+ "INTEW",
830+ "TXG",
831+ "NE",
832+ "AORT",
833+ "KARO",
834+ "MI",
835+ "TARS",
836+ "BFS",
837+ "NOMD",
838+ "BMA",
839+ "NYMTL",
840+ "IHG",
841+ "CPOP",
842+ "CGTX",
843+ "OLLI",
844+ "CIB",
845+ "ABCL",
846+ "LHX",
847+ "BBUC",
848+ "ACRS",
849+ "AISP",
850+ "COHN",
851+ "HOMB",
852+ "FDBC",
853+ "ELA",
854+ "OCUL",
855+ "BAP",
856+ "CNX",
857+ "NET",
858+ "WBS.F",
859+ "TXN",
860+ "DYNT",
861+ "AMPL",
862+ "BCV.A",
863+ "CHRW",
864+ "GDL",
865+ "FORM",
866+ "IVCAW",
867+ "LBRT",
868+ "BJRI",
869+ "CLM",
870+ "BYSI",
871+ "FITB",
872+ "BXMT",
873+ "BROG",
874+ "BFRG",
875+ "OCFC",
876+ "AEAE",
877+ "THQ",
878+ "INTE",
879+ "VMD",
880+ "SVV",
881+ "ATLC",
882+ "KVUE",
883+ "RH",
884+ "GGT",
885+ "UPST",
886+ "CDTTW",
887+ "ANIK",
888+ "PYT",
889+ "THO",
890+ "CDR.B",
891+ "OI",
892+ "MCS",
893+ "HBANL",
894+ "DRD",
895+ "WPM",
896+ "AWF",
897+ "MQT",
898+ "MARA",
899+ "FOXA",
900+ "GIS",
901+ "DCOM",
902+ "KXIN",
903+ "LTSH",
904+ "ULCC",
905+ "NOAH",
906+ "MDAIW",
907+ "IIPR",
908+ "NNDM",
909+ "HUM",
910+ "FLNT",
911+ "FAF",
912+ "GAB.K",
913+ "NVCR",
914+ "ATO",
915+ "TPC",
916+ "GALT",
917+ "TDS",
918+ "OSBC",
919+ "MYO",
920+ "NVGS",
921+ "DAR",
922+ "VGAS",
923+ "XMAX",
924+ "CASY",
925+ "CHMI.A",
926+ "CLDT.A",
927+ "HTHT",
928+ "ALDX",
929+ "OCCIO",
930+ "CNXN",
931+ "SDHY",
932+ "SLE",
933+ "SNAP",
934+ "TISI",
935+ "LUCD",
936+ "RVPHW",
937+ "MAQC",
938+ "PLGO",
939+ "TMH",
940+ "MWA",
941+ "TENB",
942+ "CLAR",
943+ "URI",
944+ "AKO.B",
945+ "CAH",
946+ "BHVN",
947+ "AZZ",
948+ "YCBD",
949+ "SACH.A",
950+ "ADPT",
951+ "DX",
952+ "CIFRW",
953+ "DLNG",
954+ "NXTC",
955+ "CVLT",
956+ "EMPD",
957+ "PRFX",
958+ "BLKB",
959+ "CACC",
960+ "LSBK",
961+ "MOVE",
962+ "SR.A",
963+ "CRVL",
964+ "CGBDL",
965+ "HBT",
966+ "MAYS",
967+ "NVAC",
968+ "BNED",
969+ "VPG",
970+ "RILYN",
971+ "ALL.H",
972+ "CZR",
973+ "ACGL",
974+ "NCNA",
975+ "ONBPP",
976+ "OBK",
977+ "FHI",
978+ "ZCARW",
979+ "HOUR",
980+ "EQH.C",
981+ "TEN.F",
982+ "AXTA",
983+ "UNP",
984+ "DARE",
985+ "NVRI",
986+ "FDX",
987+ "NVVEW",
988+ "NYXH",
989+ "SWKHL",
990+ "NMS",
991+ "LXU",
992+ "PALI",
993+ "MTZ",
994+ "TITN",
995+ "NEXT",
996+ "SAP",
997+ "BON",
998+ "SHO.I",
999+ "PRCT",
1000+ "RBLX",
1001+ "YSG",
1002+ "MODD",
1003+ "TEL",
1004+ "PFXNZ",
1005+ "BUR",
1006+ "NXE",
1007+ "ECC",
1008+ "AFRI",
1009+ "RCKTW",
1010+ "ARAY",
1011+ "FRHC",
1012+ "STKS",
1013+ "SRCE",
1014+ "STEW",
1015+ "MYFW",
1016+ "CNQ",
1017+ "HAL",
1018+ "SIMO",
1019+ "KRUS",
1020+ "ABG",
1021+ "APT",
1022+ "MHNC",
1023+ "PTIXW",
1024+ "CLPR",
1025+ "SLN",
1026+ "HROWL",
1027+ "AMSF",
1028+ "SNWV",
1029+ "SCHW.J",
1030+ "MYRG",
1031+ "BBSI",
1032+ "VABK",
1033+ "NBTB",
1034+ "GRFS",
1035+ "LINK",
1036+ "PSFE",
1037+ "AVNW",
1038+ "LFT",
1039+ "DKL",
1040+ "NXRT",
1041+ "SXI",
1042+ "TUYA",
1043+ "ALNT",
1044+ "AWP",
1045+ "RACE",
1046+ "PDFS",
1047+ "BCDA",
1048+ "EOD",
1049+ "PWR",
1050+ "YAYO",
1051+ "KLTR",
1052+ "AGCO",
1053+ "AA",
1054+ "SAR",
1055+ "GNE",
1056+ "PAA",
1057+ "PVH",
1058+ "JAKK",
1059+ "XENE",
1060+ "BGR",
1061+ "SQNS",
1062+ "WAVE",
1063+ "PKX",
1064+ "VNO.L",
1065+ "DFLI",
1066+ "LTRN",
1067+ "BYND",
1068+ "PCSA",
1069+ "DDD",
1070+ "LCII",
1071+ "FTF",
1072+ "AGYS",
1073+ "SBC",
1074+ "GEVO",
1075+ "GLP",
1076+ "TTWO",
1077+ "JOBY",
1078+ "USLM",
1079+ "MCHB",
1080+ "MD",
1081+ "KODK",
1082+ "TSSI",
1083+ "VHC",
1084+ "LBTYK",
1085+ "IDCC",
1086+ "FMAO",
1087+ "UTG",
1088+ "GLBS",
1089+ "CMSC",
1090+ "FOR",
1091+ "AGNT",
1092+ "HEI",
1093+ "DHT",
1094+ "TLIS",
1095+ "ECVT",
1096+ "AEF",
1097+ "NFE",
1098+ "DCBO",
1099+ "LEGH",
1100+ "USAR",
1101+ "EVG",
1102+ "CRI",
1103+ "XNCR",
1104+ "BIP.A",
1105+ "DRH",
1106+ "DC",
1107+ "GL",
1108+ "NTLA",
1109+ "OPTT",
1110+ "OPP",
1111+ "CHGG",
1112+ "CETX",
1113+ "TRNS",
1114+ "BIO",
1115+ "PCTTW",
1116+ "LIND",
1117+ "GFR",
1118+ "AMPG",
1119+ "TTD",
1120+ "SSL",
1121+ "BML.J",
1122+ "PKE",
1123+ "PROV",
1124+ "UGP",
1125+ "CPHC",
1126+ "GOLF",
1127+ "DAVEW",
1128+ "API",
1129+ "GITS",
1130+ "NXJ",
1131+ "BKR",
1132+ "VCIG",
1133+ "MANH",
1134+ "NTGR",
1135+ "BLE",
1136+ "EP",
1137+ "LYB",
1138+ "USEA"
1139+ ]
1140+ },
1141+ "exports": [
1142+ {
1143+ "symbols": [
1144+ "FIVN",
1145+ "FISV",
1146+ "POET",
1147+ "CRNC",
1148+ "SIBN",
1149+ "PIPR",
1150+ "W",
1151+ "VNDA",
1152+ "DNN",
1153+ "BAC.E",
1154+ "GM",
1155+ "SACH",
1156+ "PKG",
1157+ "RLJ.A",
1158+ "SPWR",
1159+ "NTR",
1160+ "TSCO",
1161+ "PLNT",
1162+ "AXR",
1163+ "TEI",
1164+ "BAC.N",
1165+ "YHGJ",
1166+ "DMRC",
1167+ "NAN",
1168+ "GSIT",
1169+ "EAD",
1170+ "BLDR",
1171+ "USB.R",
1172+ "JXN.A",
1173+ "ZNTL",
1174+ "EFR",
1175+ "IGTA",
1176+ "FENC",
1177+ "AVBH",
1178+ "FFBW",
1179+ "DRMA",
1180+ "SLMT",
1181+ "DTIL",
1182+ "XPOF",
1183+ "AZTR",
1184+ "TRVG",
1185+ "ORKA",
1186+ "SCL",
1187+ "FBNC",
1188+ "DHCNI",
1189+ "PCT",
1190+ "SWK",
1191+ "HYFT",
1192+ "FCUV",
1193+ "LPTX"
1194+ ],
1195+ "export_id": "ff7b8315-9297-4498-8dbb-83c13cb7074e",
1196+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_db5c479a3c20b01a243d6f45.parquet",
1197+ "sha256": "755daf1350f1871164e71f026a7738804f1ec8728303c49e7390a5fb33f8bdbd",
1198+ "dataset_version": 17375,
1199+ "rows": 2279595,
1200+ "bytes": 34559646,
1201+ "from_cache": false
1202+ },
1203+ {
1204+ "symbols": [
1205+ "CAN",
1206+ "ANVS",
1207+ "NFJ",
1208+ "ARMK",
1209+ "RCI",
1210+ "SUPV",
1211+ "SPRC",
1212+ "VCV",
1213+ "LITE",
1214+ "BHFAP",
1215+ "ROP",
1216+ "ATMCR",
1217+ "WETH",
1218+ "FUBO",
1219+ "CLBT",
1220+ "AVAH",
1221+ "WWW",
1222+ "WHR",
1223+ "BTMD",
1224+ "AHH.A",
1225+ "VOR",
1226+ "IBCP",
1227+ "NA",
1228+ "BEAT",
1229+ "PEB.G",
1230+ "PUK",
1231+ "TRGP",
1232+ "DGICA",
1233+ "UCL",
1234+ "NNI",
1235+ "SF.D",
1236+ "NUE",
1237+ "UMBF",
1238+ "STZ",
1239+ "ARQQW",
1240+ "AIR",
1241+ "CHAI",
1242+ "PAYX",
1243+ "AKAM",
1244+ "AAP",
1245+ "CZNC",
1246+ "LTH",
1247+ "AME",
1248+ "SVVC",
1249+ "CXW",
1250+ "MNSO",
1251+ "MMLP",
1252+ "SPNT",
1253+ "FORL",
1254+ "JKHY"
1255+ ],
1256+ "export_id": "94535bf4-175a-4106-ba96-41c8e5ea6356",
1257+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_6e10d3eeb4070c46771c8e7e.parquet",
1258+ "sha256": "57c5062299272cbdde7a8acb1ef913e8c0a251da9885146a8d00bd020d5c7326",
1259+ "dataset_version": 17375,
1260+ "rows": 2646870,
1261+ "bytes": 37052282,
1262+ "from_cache": false
1263+ },
1264+ {
1265+ "symbols": [
1266+ "AEM",
1267+ "STE",
1268+ "ISPOW",
1269+ "SDOT",
1270+ "CRDO",
1271+ "PCYO",
1272+ "XOM",
1273+ "KIO",
1274+ "REGCO",
1275+ "BLX",
1276+ "OCCI",
1277+ "ZAPPW",
1278+ "MUSA",
1279+ "RDCM",
1280+ "RCKT",
1281+ "FAMI",
1282+ "RILYT",
1283+ "IPWR",
1284+ "TLSIW",
1285+ "IEP",
1286+ "SITC",
1287+ "CC",
1288+ "ORMP",
1289+ "DXCM",
1290+ "RPT",
1291+ "GAP",
1292+ "NWG",
1293+ "PGP",
1294+ "CRCT",
1295+ "TAPM",
1296+ "AFRM",
1297+ "AXIA",
1298+ "SHIP",
1299+ "XBIO",
1300+ "ILAG",
1301+ "GBLI",
1302+ "FSLR",
1303+ "BGM",
1304+ "TRUP",
1305+ "ADMA",
1306+ "OSIS",
1307+ "AMOD",
1308+ "ISPC",
1309+ "CTOS",
1310+ "HIMS",
1311+ "UONE",
1312+ "LAC",
1313+ "PK",
1314+ "ABR.F",
1315+ "BRAG"
1316+ ],
1317+ "export_id": "4d925a6b-b33c-4e7d-918d-4c6dc759b053",
1318+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_4ecd58196ea76a9d9819eb6f.parquet",
1319+ "sha256": "4819149854e69624c0fe4b52c3f45818fe254c167a972d6685aaeb321e823514",
1320+ "dataset_version": 17375,
1321+ "rows": 2455926,
1322+ "bytes": 39331060,
1323+ "from_cache": false
1324+ },
1325+ {
1326+ "symbols": [
1327+ "SHFSW",
1328+ "HPP.C",
1329+ "CHNR",
1330+ "SHPH",
1331+ "ENTX",
1332+ "MFA.B",
1333+ "NPCT",
1334+ "FINS",
1335+ "CZWI",
1336+ "CG",
1337+ "AU",
1338+ "IKT",
1339+ "CERT",
1340+ "NPO",
1341+ "RWAY",
1342+ "BBVA",
1343+ "TARA",
1344+ "DUK.A",
1345+ "CRTDW",
1346+ "INVZW",
1347+ "MS.K",
1348+ "CVM",
1349+ "WCFB",
1350+ "ATOM",
1351+ "NOVT",
1352+ "SMIT",
1353+ "LBTYB",
1354+ "ACR",
1355+ "EOCN",
1356+ "BOC",
1357+ "BGX",
1358+ "MRT",
1359+ "WKC",
1360+ "SUAC",
1361+ "TV",
1362+ "GHG",
1363+ "FRPH",
1364+ "EVT",
1365+ "ASTL",
1366+ "MU",
1367+ "PTA",
1368+ "LPCN",
1369+ "INSM",
1370+ "PEB.E",
1371+ "ABLV",
1372+ "ARCT",
1373+ "TVC",
1374+ "IDXG",
1375+ "GSBD",
1376+ "TSLX"
1377+ ],
1378+ "export_id": "07686daf-6ff7-4ca5-a165-cc89e129502b",
1379+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_a7c81a7e7ec116afedefebe8.parquet",
1380+ "sha256": "8ee5541f62e4f7d37ba3afcd6716a8a60493c66b67c227df6bf2c295ab3998b8",
1381+ "dataset_version": 17375,
1382+ "rows": 1643285,
1383+ "bytes": 24381135,
1384+ "from_cache": false
1385+ },
1386+ {
1387+ "symbols": [
1388+ "NKE",
1389+ "COST",
1390+ "ACA",
1391+ "NTAP",
1392+ "PEBO",
1393+ "AEO",
1394+ "HWBK",
1395+ "GIC",
1396+ "BAC.M",
1397+ "ECBK",
1398+ "RDNT",
1399+ "SPCB",
1400+ "MDWD",
1401+ "ANGHW",
1402+ "EPD",
1403+ "NEA",
1404+ "VRTX",
1405+ "BIIB",
1406+ "TDY",
1407+ "JOB",
1408+ "FWRG",
1409+ "CPHI",
1410+ "DUO",
1411+ "SMP",
1412+ "EYE",
1413+ "BCPC",
1414+ "CIM.A",
1415+ "CNP",
1416+ "BCDS",
1417+ "VGASW",
1418+ "XPO",
1419+ "UAN",
1420+ "CWD",
1421+ "DRVN",
1422+ "HLSQ",
1423+ "ATRA",
1424+ "ZIVOW",
1425+ "LCFYW",
1426+ "SMFL",
1427+ "LDTCW",
1428+ "CCOI",
1429+ "NIVF",
1430+ "BP",
1431+ "SCE.M",
1432+ "BUSE",
1433+ "TCCO",
1434+ "RGCO",
1435+ "MIDD",
1436+ "RDW",
1437+ "CMT"
1438+ ],
1439+ "export_id": "4533db20-60f3-4ff4-9f8f-48586a7ea6a1",
1440+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_2b6409690b25bbb655f8d498.parquet",
1441+ "sha256": "376513326c8461fd257dfb5dcb4965e9a5289355e49877d59e55724a358f429a",
1442+ "dataset_version": 17375,
1443+ "rows": 2228644,
1444+ "bytes": 34432027,
1445+ "from_cache": false
1446+ },
1447+ {
1448+ "symbols": [
1449+ "ENX",
1450+ "UBS",
1451+ "OSPN",
1452+ "KGC",
1453+ "LKFT",
1454+ "STM",
1455+ "AOGO",
1456+ "HTD",
1457+ "GOOS",
1458+ "VRMEW",
1459+ "BBIO",
1460+ "HRZN",
1461+ "PSA.K",
1462+ "NXGL",
1463+ "SCYX",
1464+ "KMI",
1465+ "NXP",
1466+ "MGM",
1467+ "HYFM",
1468+ "UOKA",
1469+ "FBYDW",
1470+ "GUT",
1471+ "FSTR",
1472+ "SAJ",
1473+ "MCI",
1474+ "DGICB",
1475+ "CMP",
1476+ "AAPL",
1477+ "OFED",
1478+ "BBDC",
1479+ "WTBA",
1480+ "USGO",
1481+ "MLKN",
1482+ "TRU",
1483+ "ARCC",
1484+ "TLF",
1485+ "GFF",
1486+ "RSKD",
1487+ "VEL",
1488+ "TCRX",
1489+ "ALVO",
1490+ "GLLIW",
1491+ "OSS",
1492+ "RMBI",
1493+ "RZC",
1494+ "KNTK",
1495+ "CMRA",
1496+ "PAHC",
1497+ "TACT",
1498+ "QVCD"
1499+ ],
1500+ "export_id": "5e0c0d2f-d16a-4277-ac1f-81052fba679b",
1501+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_9ff1f18b7282fbfb0b305fab.parquet",
1502+ "sha256": "320cfe75b04520722f86ea33ee240db680df83e4a56634b26af4efb026a8a232",
1503+ "dataset_version": 17375,
1504+ "rows": 2018147,
1505+ "bytes": 30334351,
1506+ "from_cache": false
1507+ },
1508+ {
1509+ "symbols": [
1510+ "PMCB",
1511+ "REAX",
1512+ "FFC",
1513+ "AIXI",
1514+ "FGB",
1515+ "HYI",
1516+ "SHAK",
1517+ "WTMA",
1518+ "DBI",
1519+ "CLVRW",
1520+ "ZION",
1521+ "GIB",
1522+ "DCOY",
1523+ "RCON",
1524+ "CANG",
1525+ "COFS",
1526+ "KNF",
1527+ "ZWS",
1528+ "DRS",
1529+ "CNSY",
1530+ "ETJ",
1531+ "GEN",
1532+ "UCTT",
1533+ "ADSE",
1534+ "SOWG",
1535+ "SLDPW",
1536+ "SLVM",
1537+ "PHD",
1538+ "CCEP",
1539+ "KULR",
1540+ "TMP",
1541+ "TAC",
1542+ "PNI",
1543+ "MHLA",
1544+ "REI",
1545+ "TSBK",
1546+ "NVNO",
1547+ "DLR.L",
1548+ "STNE",
1549+ "INFU",
1550+ "MBIN",
1551+ "AGL",
1552+ "RITM",
1553+ "MAT",
1554+ "OGCP",
1555+ "BOWN",
1556+ "ZYME",
1557+ "BEN",
1558+ "KMT",
1559+ "AEG"
1560+ ],
1561+ "export_id": "53c783d6-8455-4e9f-acb2-d2824f1fcd5d",
1562+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_4f02a8077e748295842fe6b9.parquet",
1563+ "sha256": "3692206bb7c4460f6547e46060a6b2e8205304c604ba58121e0ac1cb762f9f1a",
1564+ "dataset_version": 17375,
1565+ "rows": 2244970,
1566+ "bytes": 30554594,
1567+ "from_cache": false
1568+ },
1569+ {
1570+ "symbols": [
1571+ "FMBH",
1572+ "ZDGE",
1573+ "GEL",
1574+ "BIRK",
1575+ "EXFY",
1576+ "VSSYW",
1577+ "MSAIW",
1578+ "VKQ",
1579+ "FLYX",
1580+ "XELB",
1581+ "DOUG",
1582+ "SOHON",
1583+ "INDB",
1584+ "INVE",
1585+ "GJT",
1586+ "GTX",
1587+ "CASH",
1588+ "ARBK",
1589+ "BEPC",
1590+ "CALA",
1591+ "OBE",
1592+ "LEU",
1593+ "ASA",
1594+ "WINA",
1595+ "HLIO",
1596+ "SHFS",
1597+ "MOH",
1598+ "PGYWW",
1599+ "NGL",
1600+ "BKN",
1601+ "BBAR",
1602+ "RDNW",
1603+ "YCBD.A",
1604+ "MO",
1605+ "BGT",
1606+ "VUZI",
1607+ "FBIOP",
1608+ "COLD",
1609+ "BOKF",
1610+ "EFT",
1611+ "NBSTU",
1612+ "YETI",
1613+ "MCOMW",
1614+ "VLY",
1615+ "DBRG.J",
1616+ "KUKE",
1617+ "GTN.A",
1618+ "LIQT",
1619+ "RDIB",
1620+ "BF.B"
1621+ ],
1622+ "export_id": "7c6689bc-c605-4317-8ba3-60e1c3779fe6",
1623+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_db826ea8ec7a82d980bfac15.parquet",
1624+ "sha256": "050f13fff0a1159aa21e3a223323ca8b86ab131b616b320f27b9463981c3fd97",
1625+ "dataset_version": 17375,
1626+ "rows": 1781515,
1627+ "bytes": 23103560,
1628+ "from_cache": false
1629+ },
1630+ {
1631+ "symbols": [
1632+ "CMC",
1633+ "OGN",
1634+ "MCB",
1635+ "TSQ",
1636+ "AEMD",
1637+ "NEOVW",
1638+ "KLRS",
1639+ "CIG",
1640+ "GECC",
1641+ "DLNG.A",
1642+ "IMPP",
1643+ "MHK",
1644+ "BIDU",
1645+ "CBSH",
1646+ "MTRN",
1647+ "BKU",
1648+ "CELUW",
1649+ "OLB",
1650+ "YOTAR",
1651+ "NOA",
1652+ "IKNA",
1653+ "U",
1654+ "MLEC",
1655+ "IOR",
1656+ "TNET",
1657+ "RTB",
1658+ "GRI",
1659+ "MLM",
1660+ "SEI",
1661+ "MITI",
1662+ "HPE",
1663+ "KRO",
1664+ "OESX",
1665+ "PETS",
1666+ "NEWTZ",
1667+ "GNW",
1668+ "HSCSW",
1669+ "SNDR",
1670+ "LWLG",
1671+ "RLJ",
1672+ "SBAC",
1673+ "ZIM",
1674+ "CETXP",
1675+ "PPTA",
1676+ "ALL.B",
1677+ "MESO",
1678+ "MDBH",
1679+ "CWST",
1680+ "JWEL",
1681+ "RRX"
1682+ ],
1683+ "export_id": "4e4079ce-2340-44f8-b691-b872c54095e6",
1684+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_eb502a5875286564c2c43029.parquet",
1685+ "sha256": "cb2121c3cddf54d877c26550b06d696923b8616c68344469eecfec04189f9e00",
1686+ "dataset_version": 17375,
1687+ "rows": 2216009,
1688+ "bytes": 33180257,
1689+ "from_cache": false
1690+ },
1691+ {
1692+ "symbols": [
1693+ "CRTO",
1694+ "PCG.I",
1695+ "PSQH",
1696+ "SOJC",
1697+ "CHCO",
1698+ "FUTU",
1699+ "PFBC",
1700+ "IH",
1701+ "SEVN",
1702+ "BHFAL",
1703+ "IESC",
1704+ "INDP",
1705+ "HAIN",
1706+ "NBBK",
1707+ "INTT",
1708+ "GRBK",
1709+ "STC",
1710+ "BALL",
1711+ "XEL",
1712+ "NKX",
1713+ "MBNKP",
1714+ "DIT",
1715+ "CERS",
1716+ "GTEC",
1717+ "BBWI",
1718+ "ENLV",
1719+ "RL",
1720+ "MPAA",
1721+ "NEUP",
1722+ "UMH.D",
1723+ "RS",
1724+ "CARS",
1725+ "FENG",
1726+ "CCM",
1727+ "MSEX",
1728+ "SYTAW",
1729+ "SGLY",
1730+ "DWSN",
1731+ "LESL",
1732+ "JMIA",
1733+ "DKNG",
1734+ "HOLOW",
1735+ "FNUC",
1736+ "OMC",
1737+ "OCEAW",
1738+ "OR",
1739+ "GEGGL",
1740+ "GGR",
1741+ "TCRT",
1742+ "FTAIN"
1743+ ],
1744+ "export_id": "34c4b9e7-9287-4f5a-b58a-a9b47e795958",
1745+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_ed214fbbeed76807492dcc77.parquet",
1746+ "sha256": "fc7b2c613b9aa8902463d972af075719cae6446ad47d1674179160a4332c436e",
1747+ "dataset_version": 17375,
1748+ "rows": 1901146,
1749+ "bytes": 27430472,
1750+ "from_cache": false
1751+ },
1752+ {
1753+ "symbols": [
1754+ "SAN",
1755+ "LRN",
1756+ "FTII",
1757+ "ABSI",
1758+ "SF",
1759+ "AVO",
1760+ "MKC.V",
1761+ "MCAGR",
1762+ "TC",
1763+ "CATY",
1764+ "IGTAR",
1765+ "PDYN",
1766+ "BFLY",
1767+ "XNET",
1768+ "FGI",
1769+ "PPSI",
1770+ "TILE",
1771+ "MXF",
1772+ "OXLCN",
1773+ "NTWK",
1774+ "HR",
1775+ "SONY",
1776+ "AURE",
1777+ "RIG",
1778+ "PACB",
1779+ "BGC",
1780+ "MIRA",
1781+ "NRIM",
1782+ "DMB",
1783+ "OPY",
1784+ "MIO",
1785+ "E",
1786+ "IMTE",
1787+ "FOSL",
1788+ "VIAV",
1789+ "DB",
1790+ "ARWR",
1791+ "JILL",
1792+ "LPL",
1793+ "BURL",
1794+ "STRO",
1795+ "ATGL",
1796+ "BML.L",
1797+ "GNFT",
1798+ "VOD",
1799+ "HYT",
1800+ "MHH",
1801+ "KMDA",
1802+ "CTNT",
1803+ "KEY.L"
1804+ ],
1805+ "export_id": "e7fb8726-edb7-480a-b546-fb3161802f9a",
1806+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_7c497c90af9e8e5dd49bae05.parquet",
1807+ "sha256": "9117a234bfdfaa8c88a2280b57e0f3dc6eafa2c3b898b0cebcaea965ce3efbb8",
1808+ "dataset_version": 17375,
1809+ "rows": 2206793,
1810+ "bytes": 32016067,
1811+ "from_cache": false
1812+ },
1813+ {
1814+ "symbols": [
1815+ "RILYL",
1816+ "NEE.R",
1817+ "CNF",
1818+ "LNSR",
1819+ "PNBK",
1820+ "ENB",
1821+ "OVLY",
1822+ "ALMU",
1823+ "HTH",
1824+ "ATEC",
1825+ "APPN",
1826+ "MAN",
1827+ "AMBP",
1828+ "CRIS",
1829+ "ELVA",
1830+ "FPI",
1831+ "ORC",
1832+ "GWW",
1833+ "RF.E",
1834+ "SFST",
1835+ "TAK",
1836+ "COO",
1837+ "USCB",
1838+ "WAL",
1839+ "WTFCP",
1840+ "HLGN",
1841+ "HCVIW",
1842+ "EXK",
1843+ "OPCH",
1844+ "BMBL",
1845+ "GECCO",
1846+ "SOND",
1847+ "HPS",
1848+ "MXE",
1849+ "HPK",
1850+ "IDT",
1851+ "NRC",
1852+ "DDS",
1853+ "GDV.H",
1854+ "QUAD",
1855+ "MITT.B",
1856+ "GAM",
1857+ "USB.Q",
1858+ "TAYD",
1859+ "TCBX",
1860+ "ARES",
1861+ "DTSS",
1862+ "FGN",
1863+ "LNAI",
1864+ "BZUN"
1865+ ],
1866+ "export_id": "32982034-0321-4cfe-9a00-5bccfe47966c",
1867+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_d259cf4eeaed9c09a8097268.parquet",
1868+ "sha256": "94b186ff59e7faa951575300d8867ddfed7e09222feed05914fe7b6420ce8d8f",
1869+ "dataset_version": 17375,
1870+ "rows": 1775606,
1871+ "bytes": 22769290,
1872+ "from_cache": false
1873+ },
1874+ {
1875+ "symbols": [
1876+ "BFS.D",
1877+ "SMRT",
1878+ "ARE",
1879+ "BNY",
1880+ "TPR",
1881+ "BFS.E",
1882+ "NXDT",
1883+ "PBYI",
1884+ "GLAD",
1885+ "NERV",
1886+ "CHSCM",
1887+ "ACN",
1888+ "OUT",
1889+ "NLY.I",
1890+ "MDB",
1891+ "CLST",
1892+ "ACT",
1893+ "PRKS",
1894+ "ERAS",
1895+ "RDVT",
1896+ "WFCF",
1897+ "QFIN",
1898+ "NXPLW",
1899+ "OMH",
1900+ "BVFL",
1901+ "UVSP",
1902+ "LCID",
1903+ "NOV",
1904+ "RLAY",
1905+ "BNTC",
1906+ "ALLY",
1907+ "DSL",
1908+ "OABIW",
1909+ "ETW",
1910+ "KMPR",
1911+ "SUZ",
1912+ "FFBC",
1913+ "ETN",
1914+ "PW.A",
1915+ "NVNI",
1916+ "TDOC",
1917+ "NAMSW",
1918+ "STWD",
1919+ "ACNB",
1920+ "FNWB",
1921+ "BAOS",
1922+ "BPOP",
1923+ "DNTH",
1924+ "FAX",
1925+ "NWN"
1926+ ],
1927+ "export_id": "f80fe9db-6b55-44ad-becf-a476bc75a582",
1928+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_57d01cf19407543052931f50.parquet",
1929+ "sha256": "09f19cf83d11eef99757e6d29a9d2549d21e99e1223a7a3ea40c82fe8d2864e5",
1930+ "dataset_version": 17375,
1931+ "rows": 2508240,
1932+ "bytes": 36562068,
1933+ "from_cache": false
1934+ },
1935+ {
1936+ "symbols": [
1937+ "UPXI",
1938+ "BTCS",
1939+ "LMNR",
1940+ "HOOD",
1941+ "RMCO",
1942+ "GBX",
1943+ "DVLT",
1944+ "XTLB",
1945+ "EME",
1946+ "KUST",
1947+ "KITTW",
1948+ "NSA.A",
1949+ "RCUS",
1950+ "HBANM",
1951+ "JCE",
1952+ "LDTC",
1953+ "UL",
1954+ "AMRN",
1955+ "ELF",
1956+ "BL",
1957+ "MUE",
1958+ "UP",
1959+ "HASI",
1960+ "BEKE",
1961+ "BTAI",
1962+ "NESR",
1963+ "PJT",
1964+ "HTCR",
1965+ "CCSI",
1966+ "ABTS",
1967+ "SKYW",
1968+ "FTIIW",
1969+ "EPR.G",
1970+ "IQI",
1971+ "MGA",
1972+ "HIND",
1973+ "CRVS",
1974+ "OZ",
1975+ "ALNY",
1976+ "MRM",
1977+ "INTEW",
1978+ "TXG",
1979+ "NE",
1980+ "AORT",
1981+ "KARO",
1982+ "MI",
1983+ "TARS",
1984+ "BFS",
1985+ "NOMD",
1986+ "BMA"
1987+ ],
1988+ "export_id": "9d03b718-06ac-4480-8783-de1f45fbaa41",
1989+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_95a8875666f26f2c85f5bd9f.parquet",
1990+ "sha256": "cc647b735d62771b1afd06ef8be4a94d54f776b3be1221e0236f3c520d7c2350",
1991+ "dataset_version": 17375,
1992+ "rows": 2212439,
1993+ "bytes": 35249161,
1994+ "from_cache": false
1995+ },
1996+ {
1997+ "symbols": [
1998+ "NYMTL",
1999+ "IHG",
2000+ "CPOP",
2001+ "CGTX",
2002+ "OLLI",
2003+ "CIB",
2004+ "ABCL",
2005+ "LHX",
2006+ "BBUC",
2007+ "ACRS",
2008+ "AISP",
2009+ "COHN",
2010+ "HOMB",
2011+ "FDBC",
2012+ "ELA",
2013+ "OCUL",
2014+ "BAP",
2015+ "CNX",
2016+ "NET",
2017+ "WBS.F",
2018+ "TXN",
2019+ "DYNT",
2020+ "AMPL",
2021+ "BCV.A",
2022+ "CHRW",
2023+ "GDL",
2024+ "FORM",
2025+ "IVCAW",
2026+ "LBRT",
2027+ "BJRI",
2028+ "CLM",
2029+ "BYSI",
2030+ "FITB",
2031+ "BXMT",
2032+ "BROG",
2033+ "BFRG",
2034+ "OCFC",
2035+ "AEAE",
2036+ "THQ",
2037+ "INTE",
2038+ "VMD",
2039+ "SVV",
2040+ "ATLC",
2041+ "KVUE",
2042+ "RH",
2043+ "GGT",
2044+ "UPST",
2045+ "CDTTW",
2046+ "ANIK",
2047+ "PYT"
2048+ ],
2049+ "export_id": "3fcf6fda-ccc9-4375-be69-76378242e584",
2050+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_b07bf2301b002c71658b7f3d.parquet",
2051+ "sha256": "6432c0376e3529fc6a166e13b0d46ae8b365a9d64475e2f7bb011e14ecfec3ea",
2052+ "dataset_version": 17375,
2053+ "rows": 2397304,
2054+ "bytes": 34744464,
2055+ "from_cache": false
2056+ },
2057+ {
2058+ "symbols": [
2059+ "THO",
2060+ "CDR.B",
2061+ "OI",
2062+ "MCS",
2063+ "HBANL",
2064+ "DRD",
2065+ "WPM",
2066+ "AWF",
2067+ "MQT",
2068+ "MARA",
2069+ "FOXA",
2070+ "GIS",
2071+ "DCOM",
2072+ "KXIN",
2073+ "LTSH",
2074+ "ULCC",
2075+ "NOAH",
2076+ "MDAIW",
2077+ "IIPR",
2078+ "NNDM",
2079+ "HUM",
2080+ "FLNT",
2081+ "FAF",
2082+ "GAB.K",
2083+ "NVCR",
2084+ "ATO",
2085+ "TPC",
2086+ "GALT",
2087+ "TDS",
2088+ "OSBC",
2089+ "MYO",
2090+ "NVGS",
2091+ "DAR",
2092+ "VGAS",
2093+ "XMAX",
2094+ "CASY",
2095+ "CHMI.A",
2096+ "CLDT.A",
2097+ "HTHT",
2098+ "ALDX",
2099+ "OCCIO",
2100+ "CNXN",
2101+ "SDHY",
2102+ "SLE",
2103+ "SNAP",
2104+ "TISI",
2105+ "LUCD",
2106+ "RVPHW",
2107+ "MAQC",
2108+ "PLGO"
2109+ ],
2110+ "export_id": "7035008a-b2ad-4fff-ae74-9fa7a12484da",
2111+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_c389264f39cfcaffe8afcb4f.parquet",
2112+ "sha256": "e50d7bc8c83fcf157479ee49a7d5af231adbaad470ca90b3d857bf610104cfaa",
2113+ "dataset_version": 17375,
2114+ "rows": 2484704,
2115+ "bytes": 36346568,
2116+ "from_cache": false
2117+ },
2118+ {
2119+ "symbols": [
2120+ "TMH",
2121+ "MWA",
2122+ "TENB",
2123+ "CLAR",
2124+ "URI",
2125+ "AKO.B",
2126+ "CAH",
2127+ "BHVN",
2128+ "AZZ",
2129+ "YCBD",
2130+ "SACH.A",
2131+ "ADPT",
2132+ "DX",
2133+ "CIFRW",
2134+ "DLNG",
2135+ "NXTC",
2136+ "CVLT",
2137+ "EMPD",
2138+ "PRFX",
2139+ "BLKB",
2140+ "CACC",
2141+ "LSBK",
2142+ "MOVE",
2143+ "SR.A",
2144+ "CRVL",
2145+ "CGBDL",
2146+ "HBT",
2147+ "MAYS",
2148+ "NVAC",
2149+ "BNED",
2150+ "VPG",
2151+ "RILYN",
2152+ "ALL.H",
2153+ "CZR",
2154+ "ACGL",
2155+ "NCNA",
2156+ "ONBPP",
2157+ "OBK",
2158+ "FHI",
2159+ "ZCARW",
2160+ "HOUR",
2161+ "EQH.C",
2162+ "TEN.F",
2163+ "AXTA",
2164+ "UNP",
2165+ "DARE",
2166+ "NVRI",
2167+ "FDX",
2168+ "NVVEW",
2169+ "NYXH"
2170+ ],
2171+ "export_id": "103fd471-da5c-4efc-acbb-cfd147a6be06",
2172+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_48da5e8fc289146c3ea9b3a2.parquet",
2173+ "sha256": "184bf83ca70d487174e4db35c714b297a3aff82ac0eb6a63bd9f0a16cc3b8ac9",
2174+ "dataset_version": 17375,
2175+ "rows": 1861331,
2176+ "bytes": 25731878,
2177+ "from_cache": false
2178+ },
2179+ {
2180+ "symbols": [
2181+ "SWKHL",
2182+ "NMS",
2183+ "LXU",
2184+ "PALI",
2185+ "MTZ",
2186+ "TITN",
2187+ "NEXT",
2188+ "SAP",
2189+ "BON",
2190+ "SHO.I",
2191+ "PRCT",
2192+ "RBLX",
2193+ "YSG",
2194+ "MODD",
2195+ "TEL",
2196+ "PFXNZ",
2197+ "BUR",
2198+ "NXE",
2199+ "ECC",
2200+ "AFRI",
2201+ "RCKTW",
2202+ "ARAY",
2203+ "FRHC",
2204+ "STKS",
2205+ "SRCE",
2206+ "STEW",
2207+ "MYFW",
2208+ "CNQ",
2209+ "HAL",
2210+ "SIMO",
2211+ "KRUS",
2212+ "ABG",
2213+ "APT",
2214+ "MHNC",
2215+ "PTIXW",
2216+ "CLPR",
2217+ "SLN",
2218+ "HROWL",
2219+ "AMSF",
2220+ "SNWV",
2221+ "SCHW.J",
2222+ "MYRG",
2223+ "BBSI",
2224+ "VABK",
2225+ "NBTB",
2226+ "GRFS",
2227+ "LINK",
2228+ "PSFE",
2229+ "AVNW",
2230+ "LFT"
2231+ ],
2232+ "export_id": "c6181dcd-2782-4c1f-857e-d09167170d0b",
2233+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_e206ca0bd1dcea5aecc41b8e.parquet",
2234+ "sha256": "15e5e4fe33df0ff45fc9bc072d706456a6380d48a988fa4cecd90a58f1b3c716",
2235+ "dataset_version": 17375,
2236+ "rows": 1915426,
2237+ "bytes": 25629225,
2238+ "from_cache": false
2239+ },
2240+ {
2241+ "symbols": [
2242+ "DKL",
2243+ "NXRT",
2244+ "SXI",
2245+ "TUYA",
2246+ "ALNT",
2247+ "AWP",
2248+ "RACE",
2249+ "PDFS",
2250+ "BCDA",
2251+ "EOD",
2252+ "PWR",
2253+ "YAYO",
2254+ "KLTR",
2255+ "AGCO",
2256+ "AA",
2257+ "SAR",
2258+ "GNE",
2259+ "PAA",
2260+ "PVH",
2261+ "JAKK",
2262+ "XENE",
2263+ "BGR",
2264+ "SQNS",
2265+ "WAVE",
2266+ "PKX",
2267+ "VNO.L",
2268+ "DFLI",
2269+ "LTRN",
2270+ "BYND",
2271+ "PCSA",
2272+ "DDD",
2273+ "LCII",
2274+ "FTF",
2275+ "AGYS",
2276+ "SBC",
2277+ "GEVO",
2278+ "GLP",
2279+ "TTWO",
2280+ "JOBY",
2281+ "USLM",
2282+ "MCHB",
2283+ "MD",
2284+ "KODK",
2285+ "TSSI",
2286+ "VHC",
2287+ "LBTYK",
2288+ "IDCC",
2289+ "FMAO",
2290+ "UTG",
2291+ "GLBS"
2292+ ],
2293+ "export_id": "5ad85b56-b6be-43f9-8ec9-1a2a03e95894",
2294+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_ffd7d5ae2fa139e1ae2ed531.parquet",
2295+ "sha256": "c42b4b7f4c0ca2eb1098fd3b2473ca5485da9112878b08f642d4e8ed802b5718",
2296+ "dataset_version": 17375,
2297+ "rows": 2304298,
2298+ "bytes": 34032188,
2299+ "from_cache": false
2300+ },
2301+ {
2302+ "symbols": [
2303+ "CMSC",
2304+ "FOR",
2305+ "AGNT",
2306+ "HEI",
2307+ "DHT",
2308+ "TLIS",
2309+ "ECVT",
2310+ "AEF",
2311+ "NFE",
2312+ "DCBO",
2313+ "LEGH",
2314+ "USAR",
2315+ "EVG",
2316+ "CRI",
2317+ "XNCR",
2318+ "BIP.A",
2319+ "DRH",
2320+ "DC",
2321+ "GL",
2322+ "NTLA",
2323+ "OPTT",
2324+ "OPP",
2325+ "CHGG",
2326+ "CETX",
2327+ "TRNS",
2328+ "BIO",
2329+ "PCTTW",
2330+ "LIND",
2331+ "GFR",
2332+ "AMPG",
2333+ "TTD",
2334+ "SSL",
2335+ "BML.J",
2336+ "PKE",
2337+ "PROV",
2338+ "UGP",
2339+ "CPHC",
2340+ "GOLF",
2341+ "DAVEW",
2342+ "API",
2343+ "GITS",
2344+ "NXJ",
2345+ "BKR",
2346+ "VCIG",
2347+ "MANH",
2348+ "NTGR",
2349+ "BLE",
2350+ "EP",
2351+ "LYB",
2352+ "USEA"
2353+ ],
2354+ "export_id": "78f33b59-7d1e-47c7-aebf-25615aaf23ab",
2355+ "path": "/Users/simon-pierreboucher/Desktop/UQO/Recherche/Recherche-UQO/finance/wp40_raid/datasets/cache/export_f24b8f3dd4b752a87becf611.parquet",
2356+ "sha256": "ddd2b98657d05fd8ddefe3969464e3d2c48720e378393c2a2ee07df5d1b670f8",
2357+ "dataset_version": 17375,
2358+ "rows": 2264638,
2359+ "bytes": 33457115,
2360+ "from_cache": false
2361+ }
2362+ ],
2363+ "dataset_versions": [
2364+ 17375
2365+ ],
2366+ "total_rows": 43346886,
2367+ "total_bytes": 630897408,
2368+ "seconds": 436.9614591598511,
2369+ "universe_sha256": "94688f576be6371146f57184d1f9ab85d5a478cbaa5233d06225063a70b41548"
2370+}
\ No newline at end of file
added experiments/results/e7_summary.csv +12 −0
@@ -0,0 +1,12 @@
1+chip,cpu_threads,gpu_cores,macos,mem_gb,node,cold_compile_s,cold_first_call_s,garch_nll_P64@1000x390_cpu1_ms,garch_nll_P64@1000x390_cpuMT_ms,garch_nll_P64@1000x390_metal_ms,garch_nll_P64@1000x390_speedup_MT,garch_nll_P64@100x3900_cpu1_ms,garch_nll_P64@100x3900_cpuMT_ms,garch_nll_P64@100x3900_metal_ms,garch_nll_P64@100x3900_speedup_MT,library,n_bench_records,realized_fused@1000x3900_cpu1_ms,realized_fused@1000x3900_cpuMT_ms,realized_fused@1000x3900_metal_ms,realized_fused@1000x3900_speedup_MT,realized_fused@100x39000_cpu1_ms,realized_fused@100x39000_cpuMT_ms,realized_fused@100x39000_metal_ms,realized_fused@100x39000_speedup_MT,regression_stats@1000x3900_cpu1_ms,regression_stats@1000x3900_cpuMT_ms,regression_stats@1000x3900_metal_ms,regression_stats@1000x3900_speedup_MT,rolling_sumsq@1000x3900_cpu1_ms,rolling_sumsq@1000x3900_cpuMT_ms,rolling_sumsq@1000x3900_metal_ms,rolling_sumsq@1000x3900_speedup_MT,tests_metallib,tests_runtime_msl,warm_compile_s
2+Apple M2 Max,12,30,26.5.1,32,M2M32c,0.048325125,0.0498165,124.73270844202489,14.9338124319911,1.9055624725297093,7.836957668549106,122.93493747711182,14.713853946886957,2.7148124063387513,5.419841869195797,runtime,1242,28.88922893907875,3.611000021919608,1.0015630396082997,3.6053646941003636,28.890353976748884,3.802749910391867,1.1218334548175335,3.3897633325709524,47.923104488290846,5.630020517855883,4.155708011239767,1.35476806903387,9.976478992030025,1.405874965712428,2.717687515541911,0.5173055981132895,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.000524916
3+Apple M2 Ultra,24,60,26.5,64,M2U64,0.049152792,0.051035459,124.76091645658016,7.946583558805287,1.6135419718921185,4.924931422444954,122.93499964289367,8.019687607884407,2.407687483355403,3.330867341930941,runtime,1242,28.897770447656512,2.279437379911542,1.0434375144541264,2.1845461259882226,28.89868791680783,2.103875041939318,1.1007915018126369,1.9112384484027511,47.90822905488312,3.968646051362157,3.6643960047513247,1.0830287027429175,10.034603998064995,0.9129793616011739,2.838708576746285,0.32161785435813445,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.000613
4+Apple M3,8,10,26.5.1,24,M3BA24,0.043905667,0.04613775,107.70181193947792,21.04887505993247,3.3908747136592865,6.207505979251421,106.21335497125983,20.496458280831575,3.9809374138712883,5.148651222049648,runtime,1242,25.151999667286873,4.603916313499212,1.7131036147475243,2.687471016852494,25.133228860795498,4.742853809148073,2.1543754264712334,2.20149828617227,41.52868688106537,10.003979317843914,5.957312881946564,1.6792771365359433,8.691520430147648,2.0735212601721287,5.833750125020742,0.3554353915980856,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.000421292
5+Apple M3 Ultra,28,60,26.4,96,M3U96b,0.047089167,0.053993666,100.92091700062156,5.491103976964951,1.7272288678213954,3.179140922934574,98.59843761660159,5.446937517262995,2.5334999663755298,2.1499654981466136,runtime,1242,23.458520998246968,2.304041408933699,1.370021142065525,1.6817560971796317,23.477750015445054,2.210604608990252,1.3697290560230613,1.613899186316913,40.60522955842316,2.809292054735124,3.616687492467463,0.7767583073146588,7.585395942442119,0.6446875631809235,2.651687478646636,0.24312350847240793,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.000531084
6+Apple M4 Max,16,40,26.4,64,M4M64c,0.040168875,0.044207083,79.52589588239789,7.422207971103489,1.5402500284835696,4.8188331984067,78.29858351033181,7.520229439251125,1.5180624322965741,4.953834097504329,runtime,1242,20.198437036015093,2.066000597551465,0.7389584789052606,2.79582771769825,20.19377041142434,2.0329373655840755,0.6558125605806708,3.09987561656957,30.77616647351533,3.5077084321528673,2.94706248678267,1.1902389066688093,6.132583483122289,0.787562457844615,1.6471249982714653,0.4781437102048132,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.0004675
7+Apple M5 Max,18,32,27.0,36,M5M36,0.037059042,0.040020542,77.77429150883108,6.631562486290932,3.09193751309067,2.1447918847693943,79.65574995614588,6.037042010575533,3.4854585537686944,1.7320653559480452,runtime,1242,20.459166960790753,1.6108546406030655,1.4359585475176573,1.1217974525711423,19.205792108550668,1.6643749549984932,1.4845620607957244,1.1211218439102433,28.204479021951556,2.881812513805926,4.790271050296724,0.6015969625826116,6.14762504119426,0.6659789942204952,2.902582986280322,0.22944356711535452,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.000456708
8+Apple M2,8,10,26.5.1,8,m2m8a,0.109846416,0.111059292,124.81114594265819,26.51604195125401,3.975166939198971,6.670422238065105,123.06604196783155,28.19958352483809,4.337312420830131,6.501626073650671,runtime,1242,28.90385454520583,5.524458014406264,1.3844374334439635,3.990399191000979,28.902563033625484,5.802188068628311,1.4303125208243728,4.0565876227414766,48.694312339648604,10.649729054421186,6.6006670240312815,1.6134322509601442,9.78158344514668,2.4727500276640058,3.793541924096644,0.6518314749487951,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.000537584
9+Apple M4,10,10,26.6.2,16,m4md,0.042053541,0.044052875,85.11762507259846,15.866832924075425,3.7722085835412145,4.206244849053445,89.96483404189348,15.40029130410403,4.2256665183231235,3.644464426458183,runtime,1242,24.37687444034964,3.558958414942026,1.3962920056656003,2.548863991558486,20.8127920050174,3.346604062244296,1.6341664595529437,2.047896677037308,31.550520565360785,7.527812034823,5.624479614198208,1.338401514661036,7.056104484945536,1.5508129727095366,4.117187927477062,0.37666800739402895,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.000386541
10+Apple M4 Pro,12,16,26.5.1,48,m4mm,0.038549083,0.041100125,82.38412498030812,10.105208493769169,4.723895923234522,2.1391683174192333,82.38689589779824,9.782104520127177,2.7961665764451027,3.4983983438367336,runtime,1242,20.243937498889863,2.68670788500458,1.6523334197700024,1.6260083182113196,20.3015620354563,2.815646003000438,1.6293750377371907,1.728052742793146,31.50135395117104,3.711103927344084,4.070708528161049,0.91166043986465,6.384750013239682,0.90329151134938,3.7826255429536104,0.23880014056164212,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.000449708
11+Apple M5 Pro,15,16,27.0,24,m5ma,0.043711542,0.046221459,76.39527041465044,7.461854023858905,4.080208367668092,1.8287923928070076,84.06835445202887,7.236291537992656,2.4006880121305585,3.0142573718150927,runtime,1242,21.05324948206544,2.040499937720597,1.8081666203215718,1.1284910996519257,19.319791463203728,1.8705830443650484,1.7046460416167974,1.0973439639063518,28.90241635031998,3.107396070845425,5.662208539433777,0.5487957656812417,6.243103998713195,0.767791410908103,3.9311664877459407,0.19530880040350074,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.000386292
12+Apple M6,12,12,27.0,24,m6ma,0.039953334,0.041169,73.43687547836453,11.244291323237121,3.022104036062956,3.7206830701585027,73.3108960557729,10.704978951252997,3.263645456172526,3.2800679776679456,runtime,1242,17.909875023178756,2.4681249633431435,1.5113543486222625,1.6330551240965197,17.88749999832362,2.598750521428883,1.4539581025019288,1.7873627286488027,27.72541716694832,4.481896059587598,5.708645912818611,0.7851066834472289,6.109478999860585,1.1178544955328107,3.2437919871881604,0.34461349554716936,All tests passed (6411 assertions in 6 test cases),All tests passed (6405 assertions in 5 test cases),0.000306458
added experiments/results/e7_summary.json +431 −0
@@ -0,0 +1,431 @@
1+[
2+ {
3+ "node": "M2M32c",
4+ "chip": "Apple M2 Max",
5+ "gpu_cores": 30,
6+ "cpu_threads": "12",
7+ "mem_gb": 32,
8+ "macos": "26.5.1",
9+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
10+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
11+ "cold_compile_s": 0.048325125,
12+ "cold_first_call_s": 0.0498165,
13+ "warm_compile_s": 0.000524916,
14+ "library": "runtime",
15+ "n_bench_records": 1242,
16+ "realized_fused@1000x3900_cpu1_ms": 28.88922893907875,
17+ "realized_fused@1000x3900_cpuMT_ms": 3.611000021919608,
18+ "realized_fused@1000x3900_metal_ms": 1.0015630396082997,
19+ "realized_fused@1000x3900_speedup_MT": 3.6053646941003636,
20+ "realized_fused@100x39000_cpu1_ms": 28.890353976748884,
21+ "realized_fused@100x39000_cpuMT_ms": 3.802749910391867,
22+ "realized_fused@100x39000_metal_ms": 1.1218334548175335,
23+ "realized_fused@100x39000_speedup_MT": 3.3897633325709524,
24+ "regression_stats@1000x3900_cpu1_ms": 47.923104488290846,
25+ "regression_stats@1000x3900_cpuMT_ms": 5.630020517855883,
26+ "regression_stats@1000x3900_metal_ms": 4.155708011239767,
27+ "regression_stats@1000x3900_speedup_MT": 1.35476806903387,
28+ "garch_nll_P64@1000x390_cpu1_ms": 124.73270844202489,
29+ "garch_nll_P64@1000x390_cpuMT_ms": 14.9338124319911,
30+ "garch_nll_P64@1000x390_metal_ms": 1.9055624725297093,
31+ "garch_nll_P64@1000x390_speedup_MT": 7.836957668549106,
32+ "garch_nll_P64@100x3900_cpu1_ms": 122.93493747711182,
33+ "garch_nll_P64@100x3900_cpuMT_ms": 14.713853946886957,
34+ "garch_nll_P64@100x3900_metal_ms": 2.7148124063387513,
35+ "garch_nll_P64@100x3900_speedup_MT": 5.419841869195797,
36+ "rolling_sumsq@1000x3900_cpu1_ms": 9.976478992030025,
37+ "rolling_sumsq@1000x3900_cpuMT_ms": 1.405874965712428,
38+ "rolling_sumsq@1000x3900_metal_ms": 2.717687515541911,
39+ "rolling_sumsq@1000x3900_speedup_MT": 0.5173055981132895
40+ },
41+ {
42+ "node": "M2U64",
43+ "chip": "Apple M2 Ultra",
44+ "gpu_cores": 60,
45+ "cpu_threads": "24",
46+ "mem_gb": 64,
47+ "macos": "26.5",
48+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
49+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
50+ "cold_compile_s": 0.049152792,
51+ "cold_first_call_s": 0.051035459,
52+ "warm_compile_s": 0.000613,
53+ "library": "runtime",
54+ "n_bench_records": 1242,
55+ "realized_fused@1000x3900_cpu1_ms": 28.897770447656512,
56+ "realized_fused@1000x3900_cpuMT_ms": 2.279437379911542,
57+ "realized_fused@1000x3900_metal_ms": 1.0434375144541264,
58+ "realized_fused@1000x3900_speedup_MT": 2.1845461259882226,
59+ "realized_fused@100x39000_cpu1_ms": 28.89868791680783,
60+ "realized_fused@100x39000_cpuMT_ms": 2.103875041939318,
61+ "realized_fused@100x39000_metal_ms": 1.1007915018126369,
62+ "realized_fused@100x39000_speedup_MT": 1.9112384484027511,
63+ "regression_stats@1000x3900_cpu1_ms": 47.90822905488312,
64+ "regression_stats@1000x3900_cpuMT_ms": 3.968646051362157,
65+ "regression_stats@1000x3900_metal_ms": 3.6643960047513247,
66+ "regression_stats@1000x3900_speedup_MT": 1.0830287027429175,
67+ "garch_nll_P64@1000x390_cpu1_ms": 124.76091645658016,
68+ "garch_nll_P64@1000x390_cpuMT_ms": 7.946583558805287,
69+ "garch_nll_P64@1000x390_metal_ms": 1.6135419718921185,
70+ "garch_nll_P64@1000x390_speedup_MT": 4.924931422444954,
71+ "garch_nll_P64@100x3900_cpu1_ms": 122.93499964289367,
72+ "garch_nll_P64@100x3900_cpuMT_ms": 8.019687607884407,
73+ "garch_nll_P64@100x3900_metal_ms": 2.407687483355403,
74+ "garch_nll_P64@100x3900_speedup_MT": 3.330867341930941,
75+ "rolling_sumsq@1000x3900_cpu1_ms": 10.034603998064995,
76+ "rolling_sumsq@1000x3900_cpuMT_ms": 0.9129793616011739,
77+ "rolling_sumsq@1000x3900_metal_ms": 2.838708576746285,
78+ "rolling_sumsq@1000x3900_speedup_MT": 0.32161785435813445
79+ },
80+ {
81+ "node": "M3BA24",
82+ "chip": "Apple M3",
83+ "gpu_cores": 10,
84+ "cpu_threads": "8",
85+ "mem_gb": 24,
86+ "macos": "26.5.1",
87+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
88+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
89+ "cold_compile_s": 0.043905667,
90+ "cold_first_call_s": 0.04613775,
91+ "warm_compile_s": 0.000421292,
92+ "library": "runtime",
93+ "n_bench_records": 1242,
94+ "realized_fused@1000x3900_cpu1_ms": 25.151999667286873,
95+ "realized_fused@1000x3900_cpuMT_ms": 4.603916313499212,
96+ "realized_fused@1000x3900_metal_ms": 1.7131036147475243,
97+ "realized_fused@1000x3900_speedup_MT": 2.687471016852494,
98+ "realized_fused@100x39000_cpu1_ms": 25.133228860795498,
99+ "realized_fused@100x39000_cpuMT_ms": 4.742853809148073,
100+ "realized_fused@100x39000_metal_ms": 2.1543754264712334,
101+ "realized_fused@100x39000_speedup_MT": 2.20149828617227,
102+ "regression_stats@1000x3900_cpu1_ms": 41.52868688106537,
103+ "regression_stats@1000x3900_cpuMT_ms": 10.003979317843914,
104+ "regression_stats@1000x3900_metal_ms": 5.957312881946564,
105+ "regression_stats@1000x3900_speedup_MT": 1.6792771365359433,
106+ "garch_nll_P64@1000x390_cpu1_ms": 107.70181193947792,
107+ "garch_nll_P64@1000x390_cpuMT_ms": 21.04887505993247,
108+ "garch_nll_P64@1000x390_metal_ms": 3.3908747136592865,
109+ "garch_nll_P64@1000x390_speedup_MT": 6.207505979251421,
110+ "garch_nll_P64@100x3900_cpu1_ms": 106.21335497125983,
111+ "garch_nll_P64@100x3900_cpuMT_ms": 20.496458280831575,
112+ "garch_nll_P64@100x3900_metal_ms": 3.9809374138712883,
113+ "garch_nll_P64@100x3900_speedup_MT": 5.148651222049648,
114+ "rolling_sumsq@1000x3900_cpu1_ms": 8.691520430147648,
115+ "rolling_sumsq@1000x3900_cpuMT_ms": 2.0735212601721287,
116+ "rolling_sumsq@1000x3900_metal_ms": 5.833750125020742,
117+ "rolling_sumsq@1000x3900_speedup_MT": 0.3554353915980856
118+ },
119+ {
120+ "node": "M3U96b",
121+ "chip": "Apple M3 Ultra",
122+ "gpu_cores": 60,
123+ "cpu_threads": "28",
124+ "mem_gb": 96,
125+ "macos": "26.4",
126+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
127+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
128+ "cold_compile_s": 0.047089167,
129+ "cold_first_call_s": 0.053993666,
130+ "warm_compile_s": 0.000531084,
131+ "library": "runtime",
132+ "n_bench_records": 1242,
133+ "realized_fused@1000x3900_cpu1_ms": 23.458520998246968,
134+ "realized_fused@1000x3900_cpuMT_ms": 2.304041408933699,
135+ "realized_fused@1000x3900_metal_ms": 1.370021142065525,
136+ "realized_fused@1000x3900_speedup_MT": 1.6817560971796317,
137+ "realized_fused@100x39000_cpu1_ms": 23.477750015445054,
138+ "realized_fused@100x39000_cpuMT_ms": 2.210604608990252,
139+ "realized_fused@100x39000_metal_ms": 1.3697290560230613,
140+ "realized_fused@100x39000_speedup_MT": 1.613899186316913,
141+ "regression_stats@1000x3900_cpu1_ms": 40.60522955842316,
142+ "regression_stats@1000x3900_cpuMT_ms": 2.809292054735124,
143+ "regression_stats@1000x3900_metal_ms": 3.616687492467463,
144+ "regression_stats@1000x3900_speedup_MT": 0.7767583073146588,
145+ "garch_nll_P64@1000x390_cpu1_ms": 100.92091700062156,
146+ "garch_nll_P64@1000x390_cpuMT_ms": 5.491103976964951,
147+ "garch_nll_P64@1000x390_metal_ms": 1.7272288678213954,
148+ "garch_nll_P64@1000x390_speedup_MT": 3.179140922934574,
149+ "garch_nll_P64@100x3900_cpu1_ms": 98.59843761660159,
150+ "garch_nll_P64@100x3900_cpuMT_ms": 5.446937517262995,
151+ "garch_nll_P64@100x3900_metal_ms": 2.5334999663755298,
152+ "garch_nll_P64@100x3900_speedup_MT": 2.1499654981466136,
153+ "rolling_sumsq@1000x3900_cpu1_ms": 7.585395942442119,
154+ "rolling_sumsq@1000x3900_cpuMT_ms": 0.6446875631809235,
155+ "rolling_sumsq@1000x3900_metal_ms": 2.651687478646636,
156+ "rolling_sumsq@1000x3900_speedup_MT": 0.24312350847240793
157+ },
158+ {
159+ "node": "M4M64c",
160+ "chip": "Apple M4 Max",
161+ "gpu_cores": 40,
162+ "cpu_threads": "16",
163+ "mem_gb": 64,
164+ "macos": "26.4",
165+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
166+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
167+ "cold_compile_s": 0.040168875,
168+ "cold_first_call_s": 0.044207083,
169+ "warm_compile_s": 0.0004675,
170+ "library": "runtime",
171+ "n_bench_records": 1242,
172+ "realized_fused@1000x3900_cpu1_ms": 20.198437036015093,
173+ "realized_fused@1000x3900_cpuMT_ms": 2.066000597551465,
174+ "realized_fused@1000x3900_metal_ms": 0.7389584789052606,
175+ "realized_fused@1000x3900_speedup_MT": 2.79582771769825,
176+ "realized_fused@100x39000_cpu1_ms": 20.19377041142434,
177+ "realized_fused@100x39000_cpuMT_ms": 2.0329373655840755,
178+ "realized_fused@100x39000_metal_ms": 0.6558125605806708,
179+ "realized_fused@100x39000_speedup_MT": 3.09987561656957,
180+ "regression_stats@1000x3900_cpu1_ms": 30.77616647351533,
181+ "regression_stats@1000x3900_cpuMT_ms": 3.5077084321528673,
182+ "regression_stats@1000x3900_metal_ms": 2.94706248678267,
183+ "regression_stats@1000x3900_speedup_MT": 1.1902389066688093,
184+ "garch_nll_P64@1000x390_cpu1_ms": 79.52589588239789,
185+ "garch_nll_P64@1000x390_cpuMT_ms": 7.422207971103489,
186+ "garch_nll_P64@1000x390_metal_ms": 1.5402500284835696,
187+ "garch_nll_P64@1000x390_speedup_MT": 4.8188331984067,
188+ "garch_nll_P64@100x3900_cpu1_ms": 78.29858351033181,
189+ "garch_nll_P64@100x3900_cpuMT_ms": 7.520229439251125,
190+ "garch_nll_P64@100x3900_metal_ms": 1.5180624322965741,
191+ "garch_nll_P64@100x3900_speedup_MT": 4.953834097504329,
192+ "rolling_sumsq@1000x3900_cpu1_ms": 6.132583483122289,
193+ "rolling_sumsq@1000x3900_cpuMT_ms": 0.787562457844615,
194+ "rolling_sumsq@1000x3900_metal_ms": 1.6471249982714653,
195+ "rolling_sumsq@1000x3900_speedup_MT": 0.4781437102048132
196+ },
197+ {
198+ "node": "M5M36",
199+ "chip": "Apple M5 Max",
200+ "gpu_cores": 32,
201+ "cpu_threads": "18",
202+ "mem_gb": 36,
203+ "macos": "27.0",
204+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
205+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
206+ "cold_compile_s": 0.037059042,
207+ "cold_first_call_s": 0.040020542,
208+ "warm_compile_s": 0.000456708,
209+ "library": "runtime",
210+ "n_bench_records": 1242,
211+ "realized_fused@1000x3900_cpu1_ms": 20.459166960790753,
212+ "realized_fused@1000x3900_cpuMT_ms": 1.6108546406030655,
213+ "realized_fused@1000x3900_metal_ms": 1.4359585475176573,
214+ "realized_fused@1000x3900_speedup_MT": 1.1217974525711423,
215+ "realized_fused@100x39000_cpu1_ms": 19.205792108550668,
216+ "realized_fused@100x39000_cpuMT_ms": 1.6643749549984932,
217+ "realized_fused@100x39000_metal_ms": 1.4845620607957244,
218+ "realized_fused@100x39000_speedup_MT": 1.1211218439102433,
219+ "regression_stats@1000x3900_cpu1_ms": 28.204479021951556,
220+ "regression_stats@1000x3900_cpuMT_ms": 2.881812513805926,
221+ "regression_stats@1000x3900_metal_ms": 4.790271050296724,
222+ "regression_stats@1000x3900_speedup_MT": 0.6015969625826116,
223+ "garch_nll_P64@1000x390_cpu1_ms": 77.77429150883108,
224+ "garch_nll_P64@1000x390_cpuMT_ms": 6.631562486290932,
225+ "garch_nll_P64@1000x390_metal_ms": 3.09193751309067,
226+ "garch_nll_P64@1000x390_speedup_MT": 2.1447918847693943,
227+ "garch_nll_P64@100x3900_cpu1_ms": 79.65574995614588,
228+ "garch_nll_P64@100x3900_cpuMT_ms": 6.037042010575533,
229+ "garch_nll_P64@100x3900_metal_ms": 3.4854585537686944,
230+ "garch_nll_P64@100x3900_speedup_MT": 1.7320653559480452,
231+ "rolling_sumsq@1000x3900_cpu1_ms": 6.14762504119426,
232+ "rolling_sumsq@1000x3900_cpuMT_ms": 0.6659789942204952,
233+ "rolling_sumsq@1000x3900_metal_ms": 2.902582986280322,
234+ "rolling_sumsq@1000x3900_speedup_MT": 0.22944356711535452
235+ },
236+ {
237+ "node": "m2m8a",
238+ "chip": "Apple M2",
239+ "gpu_cores": 10,
240+ "cpu_threads": "8",
241+ "mem_gb": 8,
242+ "macos": "26.5.1",
243+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
244+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
245+ "cold_compile_s": 0.109846416,
246+ "cold_first_call_s": 0.111059292,
247+ "warm_compile_s": 0.000537584,
248+ "library": "runtime",
249+ "n_bench_records": 1242,
250+ "realized_fused@1000x3900_cpu1_ms": 28.90385454520583,
251+ "realized_fused@1000x3900_cpuMT_ms": 5.524458014406264,
252+ "realized_fused@1000x3900_metal_ms": 1.3844374334439635,
253+ "realized_fused@1000x3900_speedup_MT": 3.990399191000979,
254+ "realized_fused@100x39000_cpu1_ms": 28.902563033625484,
255+ "realized_fused@100x39000_cpuMT_ms": 5.802188068628311,
256+ "realized_fused@100x39000_metal_ms": 1.4303125208243728,
257+ "realized_fused@100x39000_speedup_MT": 4.0565876227414766,
258+ "regression_stats@1000x3900_cpu1_ms": 48.694312339648604,
259+ "regression_stats@1000x3900_cpuMT_ms": 10.649729054421186,
260+ "regression_stats@1000x3900_metal_ms": 6.6006670240312815,
261+ "regression_stats@1000x3900_speedup_MT": 1.6134322509601442,
262+ "garch_nll_P64@1000x390_cpu1_ms": 124.81114594265819,
263+ "garch_nll_P64@1000x390_cpuMT_ms": 26.51604195125401,
264+ "garch_nll_P64@1000x390_metal_ms": 3.975166939198971,
265+ "garch_nll_P64@1000x390_speedup_MT": 6.670422238065105,
266+ "garch_nll_P64@100x3900_cpu1_ms": 123.06604196783155,
267+ "garch_nll_P64@100x3900_cpuMT_ms": 28.19958352483809,
268+ "garch_nll_P64@100x3900_metal_ms": 4.337312420830131,
269+ "garch_nll_P64@100x3900_speedup_MT": 6.501626073650671,
270+ "rolling_sumsq@1000x3900_cpu1_ms": 9.78158344514668,
271+ "rolling_sumsq@1000x3900_cpuMT_ms": 2.4727500276640058,
272+ "rolling_sumsq@1000x3900_metal_ms": 3.793541924096644,
273+ "rolling_sumsq@1000x3900_speedup_MT": 0.6518314749487951
274+ },
275+ {
276+ "node": "m4md",
277+ "chip": "Apple M4",
278+ "gpu_cores": 10,
279+ "cpu_threads": "10",
280+ "mem_gb": 16,
281+ "macos": "26.6.2",
282+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
283+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
284+ "cold_compile_s": 0.042053541,
285+ "cold_first_call_s": 0.044052875,
286+ "warm_compile_s": 0.000386541,
287+ "library": "runtime",
288+ "n_bench_records": 1242,
289+ "realized_fused@1000x3900_cpu1_ms": 24.37687444034964,
290+ "realized_fused@1000x3900_cpuMT_ms": 3.558958414942026,
291+ "realized_fused@1000x3900_metal_ms": 1.3962920056656003,
292+ "realized_fused@1000x3900_speedup_MT": 2.548863991558486,
293+ "realized_fused@100x39000_cpu1_ms": 20.8127920050174,
294+ "realized_fused@100x39000_cpuMT_ms": 3.346604062244296,
295+ "realized_fused@100x39000_metal_ms": 1.6341664595529437,
296+ "realized_fused@100x39000_speedup_MT": 2.047896677037308,
297+ "regression_stats@1000x3900_cpu1_ms": 31.550520565360785,
298+ "regression_stats@1000x3900_cpuMT_ms": 7.527812034823,
299+ "regression_stats@1000x3900_metal_ms": 5.624479614198208,
300+ "regression_stats@1000x3900_speedup_MT": 1.338401514661036,
301+ "garch_nll_P64@1000x390_cpu1_ms": 85.11762507259846,
302+ "garch_nll_P64@1000x390_cpuMT_ms": 15.866832924075425,
303+ "garch_nll_P64@1000x390_metal_ms": 3.7722085835412145,
304+ "garch_nll_P64@1000x390_speedup_MT": 4.206244849053445,
305+ "garch_nll_P64@100x3900_cpu1_ms": 89.96483404189348,
306+ "garch_nll_P64@100x3900_cpuMT_ms": 15.40029130410403,
307+ "garch_nll_P64@100x3900_metal_ms": 4.2256665183231235,
308+ "garch_nll_P64@100x3900_speedup_MT": 3.644464426458183,
309+ "rolling_sumsq@1000x3900_cpu1_ms": 7.056104484945536,
310+ "rolling_sumsq@1000x3900_cpuMT_ms": 1.5508129727095366,
311+ "rolling_sumsq@1000x3900_metal_ms": 4.117187927477062,
312+ "rolling_sumsq@1000x3900_speedup_MT": 0.37666800739402895
313+ },
314+ {
315+ "node": "m4mm",
316+ "chip": "Apple M4 Pro",
317+ "gpu_cores": 16,
318+ "cpu_threads": "12",
319+ "mem_gb": 48,
320+ "macos": "26.5.1",
321+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
322+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
323+ "cold_compile_s": 0.038549083,
324+ "cold_first_call_s": 0.041100125,
325+ "warm_compile_s": 0.000449708,
326+ "library": "runtime",
327+ "n_bench_records": 1242,
328+ "realized_fused@1000x3900_cpu1_ms": 20.243937498889863,
329+ "realized_fused@1000x3900_cpuMT_ms": 2.68670788500458,
330+ "realized_fused@1000x3900_metal_ms": 1.6523334197700024,
331+ "realized_fused@1000x3900_speedup_MT": 1.6260083182113196,
332+ "realized_fused@100x39000_cpu1_ms": 20.3015620354563,
333+ "realized_fused@100x39000_cpuMT_ms": 2.815646003000438,
334+ "realized_fused@100x39000_metal_ms": 1.6293750377371907,
335+ "realized_fused@100x39000_speedup_MT": 1.728052742793146,
336+ "regression_stats@1000x3900_cpu1_ms": 31.50135395117104,
337+ "regression_stats@1000x3900_cpuMT_ms": 3.711103927344084,
338+ "regression_stats@1000x3900_metal_ms": 4.070708528161049,
339+ "regression_stats@1000x3900_speedup_MT": 0.91166043986465,
340+ "garch_nll_P64@1000x390_cpu1_ms": 82.38412498030812,
341+ "garch_nll_P64@1000x390_cpuMT_ms": 10.105208493769169,
342+ "garch_nll_P64@1000x390_metal_ms": 4.723895923234522,
343+ "garch_nll_P64@1000x390_speedup_MT": 2.1391683174192333,
344+ "garch_nll_P64@100x3900_cpu1_ms": 82.38689589779824,
345+ "garch_nll_P64@100x3900_cpuMT_ms": 9.782104520127177,
346+ "garch_nll_P64@100x3900_metal_ms": 2.7961665764451027,
347+ "garch_nll_P64@100x3900_speedup_MT": 3.4983983438367336,
348+ "rolling_sumsq@1000x3900_cpu1_ms": 6.384750013239682,
349+ "rolling_sumsq@1000x3900_cpuMT_ms": 0.90329151134938,
350+ "rolling_sumsq@1000x3900_metal_ms": 3.7826255429536104,
351+ "rolling_sumsq@1000x3900_speedup_MT": 0.23880014056164212
352+ },
353+ {
354+ "node": "m5ma",
355+ "chip": "Apple M5 Pro",
356+ "gpu_cores": 16,
357+ "cpu_threads": "15",
358+ "mem_gb": 24,
359+ "macos": "27.0",
360+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
361+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
362+ "cold_compile_s": 0.043711542,
363+ "cold_first_call_s": 0.046221459,
364+ "warm_compile_s": 0.000386292,
365+ "library": "runtime",
366+ "n_bench_records": 1242,
367+ "realized_fused@1000x3900_cpu1_ms": 21.05324948206544,
368+ "realized_fused@1000x3900_cpuMT_ms": 2.040499937720597,
369+ "realized_fused@1000x3900_metal_ms": 1.8081666203215718,
370+ "realized_fused@1000x3900_speedup_MT": 1.1284910996519257,
371+ "realized_fused@100x39000_cpu1_ms": 19.319791463203728,
372+ "realized_fused@100x39000_cpuMT_ms": 1.8705830443650484,
373+ "realized_fused@100x39000_metal_ms": 1.7046460416167974,
374+ "realized_fused@100x39000_speedup_MT": 1.0973439639063518,
375+ "regression_stats@1000x3900_cpu1_ms": 28.90241635031998,
376+ "regression_stats@1000x3900_cpuMT_ms": 3.107396070845425,
377+ "regression_stats@1000x3900_metal_ms": 5.662208539433777,
378+ "regression_stats@1000x3900_speedup_MT": 0.5487957656812417,
379+ "garch_nll_P64@1000x390_cpu1_ms": 76.39527041465044,
380+ "garch_nll_P64@1000x390_cpuMT_ms": 7.461854023858905,
381+ "garch_nll_P64@1000x390_metal_ms": 4.080208367668092,
382+ "garch_nll_P64@1000x390_speedup_MT": 1.8287923928070076,
383+ "garch_nll_P64@100x3900_cpu1_ms": 84.06835445202887,
384+ "garch_nll_P64@100x3900_cpuMT_ms": 7.236291537992656,
385+ "garch_nll_P64@100x3900_metal_ms": 2.4006880121305585,
386+ "garch_nll_P64@100x3900_speedup_MT": 3.0142573718150927,
387+ "rolling_sumsq@1000x3900_cpu1_ms": 6.243103998713195,
388+ "rolling_sumsq@1000x3900_cpuMT_ms": 0.767791410908103,
389+ "rolling_sumsq@1000x3900_metal_ms": 3.9311664877459407,
390+ "rolling_sumsq@1000x3900_speedup_MT": 0.19530880040350074
391+ },
392+ {
393+ "node": "m6ma",
394+ "chip": "Apple M6",
395+ "gpu_cores": 12,
396+ "cpu_threads": "12",
397+ "mem_gb": 24,
398+ "macos": "27.0",
399+ "tests_metallib": "All tests passed (6411 assertions in 6 test cases)",
400+ "tests_runtime_msl": "All tests passed (6405 assertions in 5 test cases)",
401+ "cold_compile_s": 0.039953334,
402+ "cold_first_call_s": 0.041169,
403+ "warm_compile_s": 0.000306458,
404+ "library": "runtime",
405+ "n_bench_records": 1242,
406+ "realized_fused@1000x3900_cpu1_ms": 17.909875023178756,
407+ "realized_fused@1000x3900_cpuMT_ms": 2.4681249633431435,
408+ "realized_fused@1000x3900_metal_ms": 1.5113543486222625,
409+ "realized_fused@1000x3900_speedup_MT": 1.6330551240965197,
410+ "realized_fused@100x39000_cpu1_ms": 17.88749999832362,
411+ "realized_fused@100x39000_cpuMT_ms": 2.598750521428883,
412+ "realized_fused@100x39000_metal_ms": 1.4539581025019288,
413+ "realized_fused@100x39000_speedup_MT": 1.7873627286488027,
414+ "regression_stats@1000x3900_cpu1_ms": 27.72541716694832,
415+ "regression_stats@1000x3900_cpuMT_ms": 4.481896059587598,
416+ "regression_stats@1000x3900_metal_ms": 5.708645912818611,
417+ "regression_stats@1000x3900_speedup_MT": 0.7851066834472289,
418+ "garch_nll_P64@1000x390_cpu1_ms": 73.43687547836453,
419+ "garch_nll_P64@1000x390_cpuMT_ms": 11.244291323237121,
420+ "garch_nll_P64@1000x390_metal_ms": 3.022104036062956,
421+ "garch_nll_P64@1000x390_speedup_MT": 3.7206830701585027,
422+ "garch_nll_P64@100x3900_cpu1_ms": 73.3108960557729,
423+ "garch_nll_P64@100x3900_cpuMT_ms": 10.704978951252997,
424+ "garch_nll_P64@100x3900_metal_ms": 3.263645456172526,
425+ "garch_nll_P64@100x3900_speedup_MT": 3.2800679776679456,
426+ "rolling_sumsq@1000x3900_cpu1_ms": 6.109478999860585,
427+ "rolling_sumsq@1000x3900_cpuMT_ms": 1.1178544955328107,
428+ "rolling_sumsq@1000x3900_metal_ms": 3.2437919871881604,
429+ "rolling_sumsq@1000x3900_speedup_MT": 0.34461349554716936
430+ }
431+]
\ No newline at end of file
added experiments/scripts/analyze_e7.py +39 −0
@@ -0,0 +1,39 @@
1+#!/usr/bin/env python3
2+"""E7 analysis: per node — chip, GPU cores, macOS, Metal tests (metallib / runtime MSL), runtime compile time, and
3+primitive benchmark medians (realized_fused and garch_nll_P64 at reference shapes) with Metal/CPU-MT speedups.
4+Writes experiments/results/e7_summary.{json,csv}."""
5+import os, sys, json, glob, re, collections, csv
6+import numpy as np
7+root = os.path.join(os.path.dirname(__file__), "..", "results"); raw = os.path.join(root, "raw", "e7")
8+rows = []
9+for node in sorted(os.listdir(raw)):
10+ d = os.path.join(raw, node)
11+ if not os.path.isdir(d): continue
12+ res = glob.glob(os.path.join(d, "results_*"))
13+ if not res: rows.append({"node": node, "status": "no results"}); continue
14+ r = res[0]; env = json.load(open(os.path.join(r, "environment.json"))) if os.path.exists(os.path.join(r, "environment.json")) else {}
15+ gpu = open(os.path.join(r, "gpu.txt")).read() if os.path.exists(os.path.join(r, "gpu.txt")) else ""
16+ cores = re.search(r"Total Number of Cores: (\d+)", gpu); chip = re.search(r"Chipset Model: (.*)", gpu)
17+ def last(p): return open(p).read().strip().splitlines()[-1] if os.path.exists(p) and open(p).read().strip() else "?"
18+ t_lib = last(os.path.join(r, "tests_metallib.txt")); t_rt = last(os.path.join(r, "tests_runtime_msl.txt"))
19+ def comp_rec(name):
20+ f = os.path.join(r, name); return [json.loads(l) for l in open(f) if '"shader_library_load"' in l] if os.path.exists(f) else []
21+ comp = comp_rec("bench_cold_compile.jsonl"); warm = comp_rec("bench_warm_compile.jsonl")
22+ bench = [json.loads(l) for l in open(os.path.join(r, "bench_primitives.jsonl")) if l.strip() and '"shader_library_load"' not in l] if os.path.exists(os.path.join(r, "bench_primitives.jsonl")) else []
23+ g = collections.defaultdict(list)
24+ for b in bench: g[(b["kernel"], b["S"], b["n"], b["backend"], b["threads"] == 1)].append(b["wall_seconds"])
25+ def med(k, S, n, be, one): v = g.get((k, S, n, be, one)); return float(np.median(v)) if v else None
26+ row = {"node": node, "chip": chip.group(1).strip() if chip else env.get("chip"), "gpu_cores": int(cores.group(1)) if cores else None, "cpu_threads": env.get("ncpu"), "mem_gb": round(int(env.get("mem_bytes", 0)) / 2**30) if str(env.get("mem_bytes", "0")).isdigit() else None,
27+ "macos": env.get("os"), "tests_metallib": t_lib, "tests_runtime_msl": t_rt, "cold_compile_s": comp[0]["seconds"] if comp else None, "cold_first_call_s": comp[0]["wall_first_call"] if comp else None, "warm_compile_s": warm[0]["seconds"] if warm else None, "library": comp[0]["note"].split()[0] if comp else None, "n_bench_records": len(bench)}
28+ for k, S, n in [("realized_fused", 1000, 3900), ("realized_fused", 100, 39000), ("regression_stats", 1000, 3900), ("garch_nll_P64", 1000, 390), ("garch_nll_P64", 100, 3900), ("rolling_sumsq", 1000, 3900)]:
29+ c1, cn, mt = med(k, S, n, "cpu", True), med(k, S, n, "cpu", False), med(k, S, n, "metal", False)
30+ tag = f"{k}@{S}x{n}"; row[tag + "_cpu1_ms"] = None if c1 is None else 1e3 * c1; row[tag + "_cpuMT_ms"] = None if cn is None else 1e3 * cn; row[tag + "_metal_ms"] = None if mt is None else 1e3 * mt; row[tag + "_speedup_MT"] = (cn / mt) if (cn and mt) else None
31+ rows.append(row)
32+json.dump(rows, open(os.path.join(root, "e7_summary.json"), "w"), indent=1)
33+keys = sorted({k for r in rows for k in r.keys()}, key=lambda k: (k not in ("node", "chip", "gpu_cores", "cpu_threads", "mem_gb", "macos"), k))
34+with open(os.path.join(root, "e7_summary.csv"), "w", newline="") as f: w = csv.DictWriter(f, fieldnames=keys); w.writeheader(); [w.writerow(r) for r in rows]
35+print(f"{'node':8s} {'chip':14s} {'gpu':>4s} {'thr':>4s} {'GB':>3s} {'macOS':7s} {'tests(lib)':28s} {'tests(rt)':28s} {'cold/warm_s':>12s} {'RVf 1000x3900 MT/metal ms':>26s} {'spd':>5s} {'garch64 1000x390 spd':>20s} {'roll spd':>8s}")
36+for r in rows:
37+ if "chip" not in r: print(r); continue
38+ f = lambda k: ("%.2f" % r[k]) if r.get(k) is not None else "-"
39+ print(f"{r['node']:8s} {str(r['chip'])[:14]:14s} {str(r['gpu_cores']):>4s} {str(r['cpu_threads']):>4s} {str(r['mem_gb']):>3s} {str(r['macos']):7s} {r['tests_metallib'][:28]:28s} {r['tests_runtime_msl'][:28]:28s} {f('cold_compile_s')+'/'+f('warm_compile_s'):>12s} {f('realized_fused@1000x3900_cpuMT_ms'):>12s}/{f('realized_fused@1000x3900_metal_ms'):<12s} {f('realized_fused@1000x3900_speedup_MT'):>5s} {f('garch_nll_P64@1000x390_speedup_MT'):>20s} {f('rolling_sumsq@1000x3900_speedup_MT'):>8s}")
modified experiments/scripts/e0_universe_and_exports.py +1 −1
@@ -5,7 +5,7 @@ under $RAID_CACHE_DIR (never committed). Requires FINDATA_API_KEY_FILE and the c
5 import os, sys, json, time, yaml, hashlib 5 import os, sys, json, time, yaml, hashlib
6 sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "python")) 6 sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "python"))
7 import numpy as np, raid 7 import numpy as np, raid
8−cfg = yaml.safe_load(open(os.path.join(os.path.dirname(__file__), "..", "configs", "e0_universe.yaml"))) 8+cfg = yaml.safe_load(open(os.path.join(os.path.dirname(__file__), "..", "configs", "e0_universe.yaml"))); cfg["start"] = str(cfg["start"]); cfg["end"] = str(cfg["end"])
9 out_path = os.path.join(os.path.dirname(__file__), "..", "results", "e0_universe.json") 9 out_path = os.path.join(os.path.dirname(__file__), "..", "results", "e0_universe.json")
10 t0 = time.time() 10 t0 = time.time()
11 cov = raid.findata.coverage(cfg["dataset_id"], cfg["min_sessions_total"]) 11 cov = raid.findata.coverage(cfg["dataset_id"], cfg["min_sessions_total"])
added experiments/scripts/e6_baselines.py +40 −0
@@ -0,0 +1,40 @@
1+#!/usr/bin/env python3
2+"""E6 baselines: the same Parquet exports processed with pandas, polars and duckdb (read → regular session filter →
3+log returns within session → per-session RV, BPV, RSV±, RQ). Wall-clock per stage and peak RSS. Usage: e6_baselines.py e0_universe.json out.jsonl [n_files] [reps]"""
4+import sys, json, time, resource, os, math
5+import numpy as np
6+e0 = json.load(open(sys.argv[1])); out = open(sys.argv[2], "a"); nf = int(sys.argv[3]) if len(sys.argv) > 3 else 4; reps = int(sys.argv[4]) if len(sys.argv) > 4 else 3
7+def rss(): return resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
8+import pandas as pd, polars as pl, duckdb, pyarrow, pyarrow.parquet as pq
9+versions = {"pandas": pd.__version__, "polars": pl.__version__, "duckdb": duckdb.__version__, "pyarrow": pyarrow.__version__, "numpy": np.__version__}
10+MU1 = math.sqrt(2 / math.pi)
11+def measures_np(r):
12+ M = r.size; return dict(rv=float(np.sum(r * r)), bpv=float((M / (M - 1)) / MU1 ** 2 * np.sum(np.abs(r[1:]) * np.abs(r[:-1]))) if M > 1 else float("nan"), rsv_neg=float(np.sum(r[r < 0] ** 2)), rsv_pos=float(np.sum(r[r > 0] ** 2)), rq=float(M / 3 * np.sum(r ** 4)))
13+for ex in e0["exports"][:nf]:
14+ path = ex["path"]
15+ for rep in range(reps):
16+ # ---- pandas
17+ t0 = time.perf_counter(); df = pq.read_table(path, columns=["symbol_as_reported", "timestamp_utc", "close"]).to_pandas(); t1 = time.perf_counter()
18+ et = df["timestamp_utc"].dt.tz_convert("America/New_York"); df["session"] = et.dt.date; mins = et.dt.hour * 60 + et.dt.minute
19+ early = et.dt.strftime("%m-%d").isin(["11-29", "07-03", "12-24"]); close_min = np.where(early, 13 * 60, 16 * 60) # approximation of the early-close rule (documented): exact calendar in RAID
20+ reg = df[(mins >= 570) & (mins <= close_min)].sort_values(["symbol_as_reported", "timestamp_utc"]); t2 = time.perf_counter()
21+ reg["lr"] = reg.groupby(["symbol_as_reported", "session"])["close"].transform(lambda s: np.log(s).diff()); reg = reg.dropna(subset=["lr"]); t3 = time.perf_counter()
22+ res = reg.groupby(["symbol_as_reported", "session"])["lr"].apply(lambda s: measures_np(s.to_numpy())); t4 = time.perf_counter()
23+ out.write(json.dumps({"experiment": "E6", "engine": "pandas", "file": path, "rep": rep, "bars": int(len(df)), "sessions": int(len(res)), "read_seconds": t1 - t0, "filter_seconds": t2 - t1, "returns_seconds": t3 - t2, "estimate_seconds": t4 - t3, "total_seconds": t4 - t0, "peak_rss": rss(), "versions": versions}) + "\n")
24+ # ---- polars
25+ t0 = time.perf_counter(); lf = pl.scan_parquet(path).select(["symbol_as_reported", "timestamp_utc", "close"]); dfp = lf.collect(); t1 = time.perf_counter()
26+ dfp = dfp.with_columns(et=pl.col("timestamp_utc").dt.convert_time_zone("America/New_York")).with_columns(session=pl.col("et").dt.date(), mins=pl.col("et").dt.hour() * 60 + pl.col("et").dt.minute(), md=pl.col("et").dt.strftime("%m-%d"))
27+ dfp = dfp.with_columns(close_min=pl.when(pl.col("md").is_in(["11-29", "07-03", "12-24"])).then(13 * 60).otherwise(16 * 60)).filter((pl.col("mins") >= 570) & (pl.col("mins") <= pl.col("close_min"))).sort(["symbol_as_reported", "timestamp_utc"]); t2 = time.perf_counter()
28+ dfp = dfp.with_columns(lr=pl.col("close").log().diff().over(["symbol_as_reported", "session"])).drop_nulls("lr"); t3 = time.perf_counter()
29+ resp = dfp.group_by(["symbol_as_reported", "session"]).agg([(pl.col("lr") ** 2).sum().alias("rv"), (pl.col("lr").abs() * pl.col("lr").abs().shift(1)).sum().alias("adj"), pl.len().alias("M"), (pl.col("lr") ** 4).sum().alias("s4"), pl.when(pl.col("lr") < 0).then(pl.col("lr") ** 2).otherwise(0.0).sum().alias("rsv_neg")]); t4 = time.perf_counter()
30+ out.write(json.dumps({"experiment": "E6", "engine": "polars", "file": path, "rep": rep, "bars": int(dfp.height), "sessions": int(resp.height), "read_seconds": t1 - t0, "filter_seconds": t2 - t1, "returns_seconds": t3 - t2, "estimate_seconds": t4 - t3, "total_seconds": t4 - t0, "peak_rss": rss(), "versions": versions}) + "\n")
31+ # ---- duckdb
32+ t0 = time.perf_counter(); con = duckdb.connect()
33+ q = f"""WITH b AS (SELECT symbol_as_reported s, timestamp_utc AT TIME ZONE 'America/New_York' et, close FROM read_parquet('{path}')),
34+ r AS (SELECT s, CAST(et AS DATE) session, et, close, hour(et)*60+minute(et) mins, strftime(et, '%m-%d') md FROM b),
35+ f AS (SELECT * FROM r WHERE mins >= 570 AND mins <= CASE WHEN md IN ('11-29','07-03','12-24') THEN 780 ELSE 960 END),
36+ l AS (SELECT s, session, ln(close) - lag(ln(close)) OVER (PARTITION BY s, session ORDER BY et) lr FROM f)
37+ SELECT s, session, sum(lr*lr) rv, count(*) M, sum(lr*lr*lr*lr) s4, sum(CASE WHEN lr<0 THEN lr*lr ELSE 0 END) rsv_neg FROM l WHERE lr IS NOT NULL GROUP BY s, session"""
38+ resd = con.execute(q).fetch_arrow_table(); t4 = time.perf_counter(); con.close()
39+ out.write(json.dumps({"experiment": "E6", "engine": "duckdb", "file": path, "rep": rep, "sessions": int(resd.num_rows), "total_seconds": t4 - t0, "peak_rss": rss(), "versions": versions}) + "\n")
40+ out.flush(); print(f"{os.path.basename(path)} rep {rep}: pandas {res.shape[0]} sessions, polars {resp.height}, duckdb {resd.num_rows}", flush=True)
added experiments/scripts/run_e1_e6.sh +13 −0
@@ -0,0 +1,13 @@
1+#!/bin/bash
2+# Sequential run of the data-dependent experiments (timing integrity: one at a time, nothing else heavy on the laptop).
3+set -uo pipefail
4+cd "$(dirname "$0")/../.."
5+R=experiments/results/raw; E0=experiments/results/e0_universe.json; mkdir -p $R
6+export FINDATA_API_KEY_FILE=$HOME/Desktop/Cluster/secrets/findata/api-key-claude-code.txt RAID_CACHE_DIR=$PWD/datasets/cache
7+echo "== E1 $(date)"; ./build/macos-release/bench_bench_e1_batched_rv $E0 $R/e1_batched_rv.jsonl 5 2> $R/e1.log; echo "E1 exit=$?"
8+echo "== E6 $(date)"; ./build/macos-release/bench_bench_e6_pipeline $E0 $R/e6_pipeline.jsonl 4 3 2> $R/e6.log; echo "E6 exit=$?"
9+echo "== E6 baselines $(date)"; .venv/bin/python experiments/scripts/e6_baselines.py $E0 $R/e6_baselines.jsonl 4 3 > $R/e6_baselines.log 2>&1; echo "E6b exit=$?"
10+echo "== E2 $(date)"; ./build/macos-release/bench_bench_e2_har $E0 $R/e2_har.jsonl 5 2> $R/e2.log; echo "E2 exit=$?"
11+echo "== E3 $(date)"; ./build/macos-release/bench_bench_e3_garch $E0 $R/e3_garch.jsonl 1000 2> $R/e3.log; echo "E3 exit=$?"
12+echo "== E4 $(date)"; ./build/macos-release/bench_bench_e4_connectedness $E0 $R/e4_connectedness.jsonl 2> $R/e4.log; echo "E4 exit=$?"
13+echo "== done $(date)"
added paper/references.bib +99 −0
@@ -0,0 +1,99 @@
1+% references.bib — every entry resolved on Crossref (doi.org content negotiation) on 2026-11-02; software entries below are hand-written with version and URL.
2+
3+@article{AndersenBollerslevDieboldLabys2003, title={Modeling and Forecasting Realized Volatility}, volume={71}, ISSN={1468-0262}, url={http://dx.doi.org/10.1111/1468-0262.00418}, DOI={10.1111/1468-0262.00418}, number={2}, journal={Econometrica}, publisher={The Econometric Society}, author={Andersen, Torben G. and Bollerslev, Tim and Diebold, Francis X. and Labys, Paul}, year={2003}, month=Mar, pages={579–625} }
4+
5+@article{BarndorffNielsenShephard2004, title={Power and Bipower Variation with Stochastic Volatility and Jumps}, volume={2}, ISSN={1479-8417}, url={http://dx.doi.org/10.1093/jjfinec/nbh001}, DOI={10.1093/jjfinec/nbh001}, number={1}, journal={Journal of Financial Econometrics}, publisher={Oxford University Press (OUP)}, author={Barndorff-Nielsen, O. E.}, year={2004}, month=Dec, pages={1–37} }
6+
7+@article{BarndorffNielsenShephard2006, title={Econometrics of Testing for Jumps in Financial Economics Using Bipower Variation}, volume={4}, ISSN={1479-8417}, url={http://dx.doi.org/10.1093/jjfinec/nbi022}, DOI={10.1093/jjfinec/nbi022}, number={1}, journal={Journal of Financial Econometrics}, publisher={Oxford University Press (OUP)}, author={Barndorff-Nielsen, O. E.}, year={2005}, month=Aug, pages={1–30} }
8+
9+@article{Corsi2009, title={A Simple Approximate Long-Memory Model of Realized Volatility}, volume={7}, ISSN={1479-8417}, url={http://dx.doi.org/10.1093/jjfinec/nbp001}, DOI={10.1093/jjfinec/nbp001}, number={2}, journal={Journal of Financial Econometrics}, publisher={Oxford University Press (OUP)}, author={Corsi, F.}, year={2008}, month=Nov, pages={174–196} }
10+
11+@article{Bollerslev1986, title={Generalized autoregressive conditional heteroskedasticity}, volume={31}, ISSN={0304-4076}, url={http://dx.doi.org/10.1016/0304-4076(86)90063-1}, DOI={10.1016/0304-4076(86)90063-1}, number={3}, journal={Journal of Econometrics}, publisher={Elsevier BV}, author={Bollerslev, Tim}, year={1986}, month=Apr, pages={307–327} }
12+
13+@article{Engle1982, title={Autoregressive Conditional Heteroscedasticity with Estimates of the Variance of United Kingdom Inflation}, volume={50}, ISSN={0012-9682}, url={http://dx.doi.org/10.2307/1912773}, DOI={10.2307/1912773}, number={4}, journal={Econometrica}, publisher={JSTOR}, author={Engle, Robert F.}, year={1982}, month=July, pages={987} }
14+
15+@article{GlostenJagannathanRunkle1993, title={On the Relation between the Expected Value and the Volatility of the Nominal Excess Return on Stocks}, volume={48}, ISSN={1540-6261}, url={http://dx.doi.org/10.1111/j.1540-6261.1993.tb05128.x}, DOI={10.1111/j.1540-6261.1993.tb05128.x}, number={5}, journal={The Journal of Finance}, publisher={Wiley}, author={GLOSTEN, LAWRENCE R. and JAGANNATHAN, RAVI and RUNKLE, DAVID E.}, year={1993}, month=Dec, pages={1779–1801} }
16+
17+@article{Nelson1991, title={Conditional Heteroskedasticity in Asset Returns: A New Approach}, volume={59}, ISSN={0012-9682}, url={http://dx.doi.org/10.2307/2938260}, DOI={10.2307/2938260}, number={2}, journal={Econometrica}, publisher={JSTOR}, author={Nelson, Daniel B.}, year={1991}, month=Mar, pages={347} }
18+
19+@article{NeweyWest1987, title={A Simple, Positive Semi-Definite, Heteroskedasticity and Autocorrelation Consistent Covariance Matrix}, volume={55}, ISSN={0012-9682}, url={http://dx.doi.org/10.2307/1913610}, DOI={10.2307/1913610}, number={3}, journal={Econometrica}, publisher={JSTOR}, author={Newey, Whitney K. and West, Kenneth D.}, year={1987}, month=May, pages={703} }
20+
21+@article{White1980, title={A Heteroskedasticity-Consistent Covariance Matrix Estimator and a Direct Test for Heteroskedasticity}, volume={48}, ISSN={0012-9682}, url={http://dx.doi.org/10.2307/1912934}, DOI={10.2307/1912934}, number={4}, journal={Econometrica}, publisher={JSTOR}, author={White, Halbert}, year={1980}, month=May, pages={817} }
22+
23+@article{BollerslevPattonQuaedvlieg2016, title={Exploiting the errors: A simple approach for improved volatility forecasting}, volume={192}, ISSN={0304-4076}, url={http://dx.doi.org/10.1016/j.jeconom.2015.10.007}, DOI={10.1016/j.jeconom.2015.10.007}, number={1}, journal={Journal of Econometrics}, publisher={Elsevier BV}, author={Bollerslev, Tim and Patton, Andrew J. and Quaedvlieg, Rogier}, year={2016}, month=May, pages={1–18} }
24+
25+@article{HansenHuangShek2012, title={Realized GARCH: a joint model for returns and realized measures of volatility}, volume={27}, ISSN={1099-1255}, url={http://dx.doi.org/10.1002/jae.1234}, DOI={10.1002/jae.1234}, number={6}, journal={Journal of Applied Econometrics}, publisher={Wiley}, author={Hansen, Peter Reinhard and Huang, Zhuo and Shek, Howard Howan}, year={2011}, month=Mar, pages={877–906} }
26+
27+@article{DieboldYilmaz2012, title={Better to give than to receive: Predictive directional measurement of volatility spillovers}, volume={28}, ISSN={0169-2070}, url={http://dx.doi.org/10.1016/j.ijforecast.2011.02.006}, DOI={10.1016/j.ijforecast.2011.02.006}, number={1}, journal={International Journal of Forecasting}, publisher={Elsevier BV}, author={Diebold, Francis X. and Yilmaz, Kamil}, year={2012}, month=Jan, pages={57–66} }
28+
29+@article{DieboldYilmaz2014, title={On the network topology of variance decompositions: Measuring the connectedness of financial firms}, volume={182}, ISSN={0304-4076}, url={http://dx.doi.org/10.1016/j.jeconom.2014.04.012}, DOI={10.1016/j.jeconom.2014.04.012}, number={1}, journal={Journal of Econometrics}, publisher={Elsevier BV}, author={Diebold, Francis X. and Yılmaz, Kamil}, year={2014}, month=Sept, pages={119–134} }
30+
31+@article{Patton2011, title={Volatility forecast comparison using imperfect volatility proxies}, volume={160}, ISSN={0304-4076}, url={http://dx.doi.org/10.1016/j.jeconom.2010.03.034}, DOI={10.1016/j.jeconom.2010.03.034}, number={1}, journal={Journal of Econometrics}, publisher={Elsevier BV}, author={Patton, Andrew J.}, year={2011}, month=Jan, pages={246–256} }
32+
33+@article{PolitisRomano1994, title={The Stationary Bootstrap}, volume={89}, ISSN={1537-274X}, url={http://dx.doi.org/10.1080/01621459.1994.10476870}, DOI={10.1080/01621459.1994.10476870}, number={428}, journal={Journal of the American Statistical Association}, publisher={Informa UK Limited}, author={Politis, Dimitris N. and Romano, Joseph P.}, year={1994}, month=Dec, pages={1303–1313} }
34+
35+@article{ZhangMyklandAitSahalia2005, title={A Tale of Two Time Scales: Determining Integrated Volatility With Noisy High-Frequency Data}, volume={100}, ISSN={1537-274X}, url={http://dx.doi.org/10.1198/016214505000000169}, DOI={10.1198/016214505000000169}, number={472}, journal={Journal of the American Statistical Association}, publisher={Informa UK Limited}, author={Zhang, Lan and Mykland, Per A and Aït-Sahalia, Yacine}, year={2005}, month=Dec, pages={1394–1411} }
36+
37+@article{BarndorffNielsenHansenLundeShephard2008, volume={76}, ISSN={0012-9682}, url={http://dx.doi.org/10.3982/ecta6495}, DOI={10.3982/ecta6495}, number={6}, journal={Econometrica}, publisher={The Econometric Society}, year={2008}, pages={1481–1536} }
38+
39+@article{JacodLiMyklandPodolskijVetter2009, title={Microstructure noise in the continuous case: The pre-averaging approach}, volume={119}, ISSN={0304-4149}, url={http://dx.doi.org/10.1016/j.spa.2008.11.004}, DOI={10.1016/j.spa.2008.11.004}, number={7}, journal={Stochastic Processes and their Applications}, publisher={Elsevier BV}, author={Jacod, Jean and Li, Yingying and Mykland, Per A. and Podolskij, Mark and Vetter, Mathias}, year={2009}, month=July, pages={2249–2276} }
40+
41+@article{Engle2002, title={Dynamic Conditional Correlation: A Simple Class of Multivariate Generalized Autoregressive Conditional Heteroskedasticity Models}, volume={20}, ISSN={1537-2707}, url={http://dx.doi.org/10.1198/073500102288618487}, DOI={10.1198/073500102288618487}, number={3}, journal={Journal of Business &amp; Economic Statistics}, publisher={Informa UK Limited}, author={Engle, Robert}, year={2002}, month=July, pages={339–350} }
42+
43+@article{NoureldinShephardSheppard2012, title={Multivariate high‐frequency‐based volatility (HEAVY) models}, volume={27}, ISSN={1099-1255}, url={http://dx.doi.org/10.1002/jae.1260}, DOI={10.1002/jae.1260}, number={6}, journal={Journal of Applied Econometrics}, publisher={Wiley}, author={Noureldin, Diaa and Shephard, Neil and Sheppard, Kevin}, year={2011}, month=Aug, pages={907–933} }
44+
45+@article{EngleGhyselsSohn2013, title={Stock Market Volatility and Macroeconomic Fundamentals}, volume={95}, ISSN={1530-9142}, url={http://dx.doi.org/10.1162/rest_a_00300}, DOI={10.1162/rest_a_00300}, number={3}, journal={Review of Economics and Statistics}, publisher={MIT Press}, author={Engle, Robert F. and Ghysels, Eric and Sohn, Bumjean}, year={2013}, month=July, pages={776–797} }
46+
47+@article{HansenLunde2005, title={A forecast comparison of volatility models: does anything beat a GARCH(1,1)?}, volume={20}, ISSN={1099-1255}, url={http://dx.doi.org/10.1002/jae.800}, DOI={10.1002/jae.800}, number={7}, journal={Journal of Applied Econometrics}, publisher={Wiley}, author={Hansen, Peter R. and Lunde, Asger}, year={2005}, month=Mar, pages={873–889} }
48+
49+@article{LiuPattonSheppard2015, title={Does anything beat 5-minute RV? A comparison of realized measures across multiple asset classes}, volume={187}, ISSN={0304-4076}, url={http://dx.doi.org/10.1016/j.jeconom.2015.02.008}, DOI={10.1016/j.jeconom.2015.02.008}, number={1}, journal={Journal of Econometrics}, publisher={Elsevier BV}, author={Liu, Lily Y. and Patton, Andrew J. and Sheppard, Kevin}, year={2015}, month=July, pages={293–311} }
50+
51+@article{BoudtKleenSjorup2022, title={Analyzing Intraday Financial Data in <i>R</i>: The <b>highfrequency</b> Package}, volume={104}, ISSN={1548-7660}, url={http://dx.doi.org/10.18637/jss.v104.i08}, DOI={10.18637/jss.v104.i08}, number={8}, journal={Journal of Statistical Software}, publisher={Foundation for Open Access Statistic}, author={Boudt, Kris and Kleen, Onno and Sjørup, Emil}, year={2022} }
52+
53+@article{DieboldMariano2002, title={Comparing Predictive Accuracy}, volume={20}, ISSN={1537-2707}, url={http://dx.doi.org/10.1198/073500102753410444}, DOI={10.1198/073500102753410444}, number={1}, journal={Journal of Business &amp; Economic Statistics}, publisher={Informa UK Limited}, author={Diebold, Francis X and Mariano, Robert S}, year={2002}, month=Jan, pages={134–144} }
54+
55+@article{HansenLundeNason2003, title={Choosing the Best Volatility Models: The Model Confidence Set Approach*}, volume={65}, ISSN={1468-0084}, url={http://dx.doi.org/10.1046/j.0305-9049.2003.00086.x}, DOI={10.1046/j.0305-9049.2003.00086.x}, number={s1}, journal={Oxford Bulletin of Economics and Statistics}, publisher={Wiley}, author={Hansen, Peter Reinhard and Lunde, Asger and Nason, James M.}, year={2003}, month=Dec, pages={839–861} }
56+
57+@article{CameronGelbachMiller2011, title={Robust Inference With Multiway Clustering}, volume={29}, ISSN={1537-2707}, url={http://dx.doi.org/10.1198/jbes.2010.07136}, DOI={10.1198/jbes.2010.07136}, number={2}, journal={Journal of Business &amp; Economic Statistics}, publisher={Informa UK Limited}, author={Cameron, A. Colin and Gelbach, Jonah B. and Miller, Douglas L.}, year={2011}, month=Apr, pages={238–249} }
58+
59+@article{AldrichFernandezVillaverdeGallantRubioRamirez2011, title={Tapping the supercomputer under your desk: Solving dynamic equilibrium models with graphics processors}, volume={35}, ISSN={0165-1889}, url={http://dx.doi.org/10.1016/j.jedc.2010.10.001}, DOI={10.1016/j.jedc.2010.10.001}, number={3}, journal={Journal of Economic Dynamics and Control}, publisher={Elsevier BV}, author={Aldrich, Eric M. and Fernández-Villaverde, Jesús and Ronald Gallant, A. and Rubio-Ramírez, Juan F.}, year={2011}, month=Mar, pages={386–393} }
60+
61+@article{PattonSheppard2015, title={Good Volatility, Bad Volatility: Signed Jumps and The Persistence of Volatility}, volume={97}, ISSN={1530-9142}, url={http://dx.doi.org/10.1162/rest_a_00503}, DOI={10.1162/rest_a_00503}, number={3}, journal={Review of Economics and Statistics}, publisher={MIT Press - Journals}, author={Patton, Andrew J. and Sheppard, Kevin}, year={2015}, month=July, pages={683–697} }
62+
63+@inbook{BarndorffNielsenKinnebrockShephard2010, title={Measuring Downside Risk – Realized Semivariance*}, ISBN={9780199549498}, url={http://dx.doi.org/10.1093/acprof:oso/9780199549498.003.0007}, DOI={10.1093/acprof:oso/9780199549498.003.0007}, booktitle={Volatility and Time Series Econometrics}, publisher={Oxford University Press}, author={Barndorff‐Nielsen, Ole E. and Kinnebrock, Silja and Shephard, Neil}, year={2010}, month=Mar, pages={117–136} }
64+
65+@article{AndersenBollerslevDiebold2007, title={Roughing It Up: Including Jump Components in the Measurement, Modeling, and Forecasting of Return Volatility}, volume={89}, ISSN={1530-9142}, url={http://dx.doi.org/10.1162/rest.89.4.701}, DOI={10.1162/rest.89.4.701}, number={4}, journal={Review of Economics and Statistics}, publisher={MIT Press}, author={Andersen, Torben G. and Bollerslev, Tim and Diebold, Francis X.}, year={2007}, month=Nov, pages={701–720} }
66+
67+@article{HuangTauchen2005, title={The Relative Contribution of Jumps to Total Price Variance}, volume={3}, ISSN={1479-8417}, url={http://dx.doi.org/10.1093/jjfinec/nbi025}, DOI={10.1093/jjfinec/nbi025}, number={4}, journal={Journal of Financial Econometrics}, publisher={Oxford University Press (OUP)}, author={Huang, X.}, year={2005}, month=Aug, pages={456–499} }
68+
69+@article{PesaranShin1998, title={Generalized impulse response analysis in linear multivariate models}, volume={58}, ISSN={0165-1765}, url={http://dx.doi.org/10.1016/s0165-1765(97)00214-0}, DOI={10.1016/s0165-1765(97)00214-0}, number={1}, journal={Economics Letters}, publisher={Elsevier BV}, author={Pesaran, H.Hashem and Shin, Yongcheol}, year={1998}, month=Jan, pages={17–29} }
70+
71+@article{Kahan1965, title={Pracniques: further remarks on reducing truncation errors}, volume={8}, ISSN={1557-7317}, url={http://dx.doi.org/10.1145/363707.363723}, DOI={10.1145/363707.363723}, number={1}, journal={Communications of the ACM}, publisher={Association for Computing Machinery (ACM)}, author={Kahan, W.}, year={1965}, month=Jan, pages={40} }
72+
73+@article{Blackford2002, volume={28}, ISSN={1557-7295}, url={http://dx.doi.org/10.1145/567806.567807}, DOI={10.1145/567806.567807}, number={2}, journal={ACM Transactions on Mathematical Software}, publisher={Association for Computing Machinery (ACM)}, year={2002}, month=June, pages={135–151} }
74+
75+@article{FiorentiniCalzolariPanattoni1996, title={Analytic derivatives and the computation of GARCH estimates}, volume={11}, ISSN={1099-1255}, url={http://dx.doi.org/10.1002/(sici)1099-1255(199607)11:4<399::aid-jae401>3.0.co;2-r}, DOI={10.1002/(sici)1099-1255(199607)11:4<399::aid-jae401>3.0.co;2-r}, number={4}, journal={Journal of Applied Econometrics}, publisher={Wiley}, author={Fiorentini, Gabriele and Calzolari, Giorgio and Panattoni, Lorenzo}, year={1996}, month=July, pages={399–417} }
76+
77+@article{BollerslevWooldridge1992, title={Quasi-maximum likelihood estimation and inference in dynamic models with time-varying covariances}, volume={11}, ISSN={1532-4168}, url={http://dx.doi.org/10.1080/07474939208800229}, DOI={10.1080/07474939208800229}, number={2}, journal={Econometric Reviews}, publisher={Informa UK Limited}, author={Bollerslev, Tim and Wooldridge, Jeffrey M.}, year={1992}, month=Jan, pages={143–172} }
78+
79+@misc{Ghalanos2024rugarch, title={rugarch: Univariate GARCH Models}, url={http://dx.doi.org/10.32614/cran.package.rugarch}, DOI={10.32614/cran.package.rugarch}, journal={CRAN: Contributed Packages}, publisher={The R Foundation}, author={Galanos, Alexios}, year={2011}, month=Sept }
80+
81+
82+@misc{Arrow2025, title={Apache Arrow: a cross-language development platform for in-memory analytics, C++ library version 26.0.0}, author={{Apache Software Foundation}}, year={2025}, howpublished={\url{https://arrow.apache.org/}}, note={Accessed 2026-11-02}}
83+@misc{Eigen2025, title={Eigen v5.0.1: a C++ template library for linear algebra}, author={Guennebaud, Ga{\"e}l and Jacob, Beno{\^i}t and others}, year={2025}, howpublished={\url{https://eigen.tuxfamily.org}}, note={Accessed 2026-11-02}}
84+@misc{Nanobind2025, title={nanobind 3.1.0: tiny and efficient C++/Python bindings}, author={Jakob, Wenzel}, year={2025}, howpublished={\url{https://github.com/wjakob/nanobind}}, note={Accessed 2026-11-02}}
85+@misc{AppleMetal2026, title={Metal Shading Language Specification, version 4}, author={{Apple Inc.}}, year={2026}, howpublished={\url{https://developer.apple.com/metal/}}, note={Accessed 2026-11-02; Metal does not define a 64-bit floating-point type}}
86+@misc{Sheppard2025arch, title={arch 8.0.0: ARCH models in Python}, author={Sheppard, Kevin}, year={2025}, howpublished={\url{https://github.com/bashtage/arch}}, note={Version 8.0.0, accessed 2026-11-02}}
87+@inproceedings{Seabold2010, title={statsmodels: Econometric and statistical modeling with Python}, author={Seabold, Skipper and Perktold, Josef}, booktitle={Proceedings of the 9th Python in Science Conference}, pages={92--96}, year={2010}, doi={10.25080/Majora-92bf1922-011}}
88+@article{Harris2020, title={Array programming with {NumPy}}, author={Harris, Charles R. and Millman, K. Jarrod and van der Walt, St{\'e}fan J. and others}, journal={Nature}, volume={585}, pages={357--362}, year={2020}, doi={10.1038/s41586-020-2649-2}}
89+@article{Virtanen2020, title={{SciPy} 1.0: fundamental algorithms for scientific computing in Python}, author={Virtanen, Pauli and Gommers, Ralf and Oliphant, Travis E. and others}, journal={Nature Methods}, volume={17}, pages={261--272}, year={2020}, doi={10.1038/s41592-019-0686-2}}
90+@misc{ExchangeCalendars2025, title={exchange\_calendars 4.13.2: calendars for securities exchanges}, author={Gerrard, Marcus and others}, year={2025}, howpublished={\url{https://github.com/gerrymanoim/exchange_calendars}}, note={Accessed 2026-11-02}}
91+@article{Dekker1971, title={A floating-point technique for extending the available precision}, author={Dekker, T. J.}, journal={Numerische Mathematik}, volume={18}, pages={224--242}, year={1971}, doi={10.1007/BF01397083}}
92+@article{LedoitWolf2004, title={A well-conditioned estimator for large-dimensional covariance matrices}, author={Ledoit, Olivier and Wolf, Michael}, journal={Journal of Multivariate Analysis}, volume={88}, number={2}, pages={365--411}, year={2004}, doi={10.1016/S0047-259X(03)00096-4}}
93+@article{KoopPesaranPotter1996, title={Impulse response analysis in nonlinear multivariate models}, author={Koop, Gary and Pesaran, M. Hashem and Potter, Simon M.}, journal={Journal of Econometrics}, volume={74}, number={1}, pages={119--147}, year={1996}, doi={10.1016/0304-4076(95)01753-4}}
94+@article{Neumaier1974, title={Rundungsfehleranalyse einiger Verfahren zur Summation endlicher Summen}, author={Neumaier, Arnold}, journal={ZAMM -- Zeitschrift f{\"u}r Angewandte Mathematik und Mechanik}, volume={54}, number={1}, pages={39--51}, year={1974}, doi={10.1002/zamm.19740540106}}
95+@article{Higham1993, title={The accuracy of floating point summation}, author={Higham, Nicholas J.}, journal={SIAM Journal on Scientific Computing}, volume={14}, number={4}, pages={783--799}, year={1993}, doi={10.1137/0914050}}
96+@article{GoncalvesMeddahi2009, title={Bootstrapping realized volatility}, author={Gon{\c{c}}alves, S{\'\i}lvia and Meddahi, Nour}, journal={Econometrica}, volume={77}, number={1}, pages={283--306}, year={2009}, doi={10.3982/ECTA5971}}
97+@article{BarndorffNielsenShephard2002, title={Econometric analysis of realized volatility and its use in estimating stochastic volatility models}, author={Barndorff-Nielsen, Ole E. and Shephard, Neil}, journal={Journal of the Royal Statistical Society: Series B}, volume={64}, number={2}, pages={253--280}, year={2002}, doi={10.1111/1467-9868.00336}}
98+@article{NeweyWest1994, title={Automatic lag selection in covariance matrix estimation}, author={Newey, Whitney K. and West, Kenneth D.}, journal={Review of Economic Studies}, volume={61}, number={4}, pages={631--653}, year={1994}, doi={10.2307/2297912}}
99+@article{HansenLundeNason2011, title={The model confidence set}, author={Hansen, Peter R. and Lunde, Asger and Nason, James M.}, journal={Econometrica}, volume={79}, number={2}, pages={453--497}, year={2011}, doi={10.3982/ECTA5771}}
100
Menu

Theme