1\begin{figure}[t]2\centering3\begin{tikzpicture}[4 font=\sffamily\scriptsize, node distance=3mm,5 layer/.style={draw=black!70, line width=0.4pt, rounded corners=1.5pt, fill=black!3, text width=0.93\textwidth, align=left, inner sep=4pt},6 tag/.style={font=\sffamily\bfseries\scriptsize, text=black!80},7 arr/.style={-{Latex[length=1.6mm]}, line width=0.5pt, black!70}]8\node[layer, fill=black!8] (py) {\textbf{Python (nanobind, GIL released)} \quad \texttt{raid.api}: ols $\cdot$ realized\_measures $\cdot$ har\_fit / har\_rolling / har\_batch $\cdot$ garch\_fit $\cdot$ bootstrap $\cdot$ var\_connectedness \quad \texttt{raid.findata}: bars $\cdot$ export $\cdot$ catalog \hfill \textbf{CLI} \texttt{raid devices $|$ validate $|$ estimate $|$ data}};9\node[layer, below=of py] (est) {\textbf{Estimators and models} \quad reductions (Neumaier, pairwise, Welford) $\cdot$ rolling windows $\cdot$ covariance (classical, HC0--HC3, HAC, cluster) $\cdot$ OLS/WLS/ridge $\cdot$ realized measures (RV, BPV, RSV$^\pm$, RQ, $J$, TriPV, RCov) $\cdot$ HAR family $\cdot$ GARCH family (QML) $\cdot$ block bootstrap $\cdot$ VAR, GFEVD, Diebold--Yilmaz, Ledoit--Wolf};10\node[layer, below=of est] (data) {\textbf{Data} \quad MarketCalendar (XNYS rules, DST, early closes) $\cdot$ BarSeries $+$ QualityReport $\cdot$ session-aware returns $\cdot$ calendar-aware aggregation $\cdot$ Parquet / Arrow IPC reader (column projection) $\cdot$ FinData client (bearer key, token bucket, retries, cursors, exports, checksummed cache, provenance)};11\node[layer, below=of data] (be) {\textbf{Backend contract} \quad Batch $=$ values $+$ CSR offsets $\;\longrightarrow\;$ sum\_squares $\cdot$ sum\_abs\_adjacent $\cdot$ semivariances $\cdot$ sum\_fourth $\cdot$ rolling\_sum\_squares $\cdot$ regression\_stats ($X'X$, $X'y$, $y'y$) $\cdot$ garch\_nll\_batch};12\node[draw=black!70, line width=0.4pt, rounded corners=1.5pt, fill=white, anchor=north west, text width=0.445\textwidth, align=left, inner sep=4pt] (cpu) at ($(be.south west)+(0,-3mm)$) {\textbf{CpuBackend} --- FP64, Neumaier per segment, parallel over segments, deterministic order};13\node[draw=black!70, line width=0.4pt, rounded corners=1.5pt, fill=red!4, anchor=north east, text width=0.445\textwidth, align=left, inner sep=4pt] (metal) at ($(be.south east)+(0,-3mm)$) {\textbf{MetalBackend} --- FP32 double-float (TwoSum), 4\,096-element chunks, tree reductions, FP64 combine on the host; prebuilt metallib or runtime MSL; buffer pool};14\node[layer, anchor=north west] (core) at ($(cpu.south west)+(0,-3mm)$) {\textbf{Core} \quad strong types (Timestamp $\mu$s UTC, Date, Interval) $\cdot$ RaidError $\cdot$ structured log with redaction $\cdot$ counter-seeded RNG streams $\cdot$ ThreadPool $\cdot$ SHA-256 $\cdot$ Estimate / InferenceResult / Convergence / Provenance $\cdot$ ExecutionPlan (auto$\,|\,$cpu$\,|\,$metal, PrecisionPolicy) $\cdot$ ExperimentManifest};15\draw[arr] (py.south) -- (est.north); \draw[arr] (est.south) -- (data.north); \draw[arr] (data.south) -- (be.north);16\draw[arr] (be.south -| cpu.north) -- (cpu.north); \draw[arr] (be.south -| metal.north) -- (metal.north);17\draw[arr, dashed] (metal.west |- cpu.east) -- node[above, font=\sffamily\tiny]{fallback} (cpu.east);18\end{tikzpicture}19\caption{Layers of \raid{}. Estimators consume the backend contract through an \texttt{ExecutionPlan}; every result is an \texttt{Estimate} that carries coefficients, loss, inference, convergence, warnings, runtime, backend, precision and provenance. The Metal backend falls back to the CPU backend when no device is available or a case is unsupported.}20\label{fig:arch}21\end{figure}22