SPB Git forge

spb/wp13_uqo

Public
2commits 1branches 1releases
576.0 KBsize
maindefault branch
57 min agolast push
TeX 99.9%

harmonisation standard UQO WP (2026-10-17)

WP 13 (ex WP 10) : LaTeX déplacé dans paper/, page titre canonique, date June 2026, README et .gitignore standard.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed 2 h ago (Oct 17, 2026)

27 changed files +1,946 −0

added .gitignore +35 −0
@@ -0,0 +1,35 @@
1 +# Raw & processed data — never committed (see data/raw/README.md for provenance)
2 +data/raw/*
3 +!data/raw/README.md
4 +data/processed/*
5 +!data/processed/.gitkeep
6 +
7 +# Python
8 +__pycache__/
9 +*.pyc
10 +.pytest_cache/
11 +.venv/
12 +*.egg-info/
13 +
14 +# LaTeX build artifacts (paper/main.pdf IS committed)
15 +paper/*.aux
16 +paper/*.log
17 +paper/*.out
18 +paper/*.toc
19 +paper/*.lof
20 +paper/*.lot
21 +paper/*.fls
22 +paper/*.fdb_latexmk
23 +paper/*.bbl
24 +paper/*.blg
25 +paper/*.spl
26 +paper/*.synctex.gz
27 +paper/*.run.xml
28 +paper/*.bcf
29 +
30 +# Logs
31 +logs/
32 +*.log
33 +
34 +# macOS
35 +.DS_Store
added README.md +139 −0
@@ -0,0 +1,139 @@
1 +<!-- Author: Simon-Pierre Boucher — simon-pierre.boucher@uqo.ca -->
2 +# 🤖 VQuant: An Agentic Large Language Model Architecture for Automated Quantitative Financial Analysis and Document Generation
3 +
4 +**UQO Working Paper No. 13** — *Reasoning-Augmented Tool Orchestration, In-Loop Numerical Computation, and Multi-Format Reporting*
5 +
6 +[![Paper](https://img.shields.io/badge/paper-PDF%20(28%20p.)-b31b1b?logo=latex&logoColor=white)](paper/main.pdf)
7 +[![Type](https://img.shields.io/badge/type-system%20%2F%20methodology%20paper-4051b5)](paper/main.tex)
8 +[![Platform](https://img.shields.io/badge/platform-VQuant%20(spbgit%20vquant.git)-4051b5)](#-data)
9 +[![Institution](https://img.shields.io/badge/UQO-D%C3%A9pt.%20des%20sciences%20administratives-16365c)](https://uqo.ca)
10 +[![Author](https://img.shields.io/badge/author-Simon--Pierre%20Boucher-16365c)](mailto:simon-pierre.boucher@uqo.ca)
11 +
12 +> **TL;DR** — VQuant is a production web platform that turns a natural-language request into a
13 +> complete, reproducible quantitative financial report. A reasoning-augmented LLM acts as planner
14 +> and synthesizer; all numerical work is delegated to a deterministic execution substrate: an
15 +> agentic orchestration loop over 200+ tools (265+ market-data endpoints, four web-research
16 +> services, a 17-library Python sandbox), a two-stage context-management algorithm for unbounded
17 +> conversations, a single-call computation paradigm (data → estimation → figures in one sandboxed
18 +> execution), and a unified document pipeline emitting PDF, DOCX, Beamer and spreadsheets with live
19 +> formulas from one Markdown artifact. The paper documents each mechanism as implemented so the
20 +> design can be reproduced.
21 +
22 +---
23 +
24 +## 📌 Status
25 +
26 +| Item | Value |
27 +|---|---|
28 +| Version | 1.0 (June 2026) |
29 +| SSRN | not yet submitted |
30 +| Journal | — |
31 +| Code & data | methodology / system paper — no empirical pipeline; the platform's source code lives in the spbgit repository `vquant.git` |
32 +
33 +## 🎯 What this paper does
34 +
35 +Large language models are fluent in financial discourse, but fluency does not guarantee
36 +numerically rigorous, reproducible or citable analysis. This paper describes the **architecture**
37 +of VQuant, a platform that couples a reasoning-augmented LLM with a deterministic execution
38 +substrate, and argues that the resulting design pattern — *the model plans and synthesizes, auditable
39 +code computes* — is reusable beyond finance.
40 +
41 +Four mechanisms are documented at implementation level:
42 +
43 +1. an **agentic orchestration loop** exposing 200+ financial and analytical tools through a
44 + constrained function-calling protocol (recursive tool-calling loop, tool-use/tool-result
45 + invariant, batched-execution throttle);
46 +2. a **context-management algorithm** preserving coherence over effectively unbounded histories
47 + via adaptive summarization under a token budget (two-stage machinery, token-accounting correction);
48 +3. a **single-call computation paradigm** that consolidates data acquisition, estimation and figure
49 + rendering into one sandboxed Python execution (inter-process sandbox that exec's model-authored
50 + code and captures its figures);
51 +4. a **unified document pipeline** emitting PDF, DOCX, LaTeX Beamer decks and spreadsheet workbooks
52 + with live formulas from a single Markdown artifact, streamed through a Server-Sent-Event protocol
53 + with eight-way event dispatch.
54 +
55 +The classical quantitative methods the platform automates are conventional and relegated to the appendix.
56 +
57 +## 🏆 Headline results
58 +
59 +| Object | Value |
60 +|---|---|
61 +| Tools exposed to the model | 200+ (265+ market-data endpoints, 4 web-research services, Python sandbox) |
62 +| Scientific libraries in the sandbox | 17 |
63 +| Model round trips per computation | 1 (single-call paradigm) vs. several in a naïve agent |
64 +| Output formats from one artifact | PDF, DOCX, Beamer, XLSX (live formulas) |
65 +| Streaming protocol | SSE, 8 event types |
66 +
67 +## 🗂 Repository layout
68 +
69 +```
70 +vquant-llm-quant-platform/
71 +└── paper/ # main.tex + sections/ + figures/ (TikZ diagrams) + tables/ + appendix/ → main.pdf
72 + ├── figures/ # architecture, loop, context, sandbox, streaming, docpipeline (TikZ)
73 + └── tables/ # tools, models, events, robustness
74 +```
75 +
76 +No `src/`, `scripts/` or `data/`: the paper has no empirical pipeline.
77 +
78 +## 🚀 Quick start
79 +
80 +```bash
81 +cd paper && make # latexmk → main.pdf (pdflatex + bibtex, TikZ diagrams compiled inline)
82 +```
83 +
84 +## 🗃 Data
85 +
86 +Not applicable. The paper describes a software system; the platform itself (TypeScript/Python)
87 +is maintained in the spbgit repository `vquant.git` and deployed on the MacLustr cluster.
88 +
89 +## 🔬 Methodology
90 +
91 +1. **Architecture description** — components, invariants and protocols are specified as implemented (§3–§4).
92 +2. **Mechanism walkthroughs** — orchestration loop, context management, single-call computation, document pipeline (§4).
93 +3. **Design evaluation** — qualitative robustness discussion of failure modes and mitigations (§6).
94 +4. **Appendix** — the conventional quantitative methods automated by the platform.
95 +
96 +## 🖼 Figures & tables inventory
97 +
98 +| Figure (TikZ) | Content |
99 +|---|---|
100 +| `figures/architecture.tex` | end-to-end platform architecture |
101 +| `figures/loop.tex` | recursive tool-calling loop |
102 +| `figures/context.tex` | two-stage context management |
103 +| `figures/sandbox.tex` | inter-process Python sandbox |
104 +| `figures/streaming.tex` | SSE event dispatch |
105 +| `figures/docpipeline.tex` | unified document pipeline |
106 +
107 +Tables (`paper/tables/*.tex`): tool catalogue, models, streaming events, robustness.
108 +
109 +## ⚠️ Limitations
110 +
111 +- Descriptive system paper: no benchmark against alternative agent frameworks is reported.
112 +- Tool counts and endpoint inventories reflect the platform as of June 2026.
113 +- Reproducibility of the *design* is documented; reproducing the *platform* requires the private `vquant.git` code base and API keys.
114 +
115 +## 📝 Citation
116 +
117 +```bibtex
118 +@techreport{boucher2026vquant,
119 + author = {Boucher, Simon-Pierre},
120 + title = {VQuant: An Agentic Large Language Model Architecture for Automated Quantitative Financial Analysis and Document Generation},
121 + institution = {Universit\'e du Qu\'ebec en Outaouais, D\'epartement des sciences administratives},
122 + type = {Working Paper},
123 + number = {13},
124 + year = {2026},
125 + month = {June}
126 +}
127 +```
128 +
129 +## 👤 Author & contact
130 +
131 +**Simon-Pierre Boucher** — Département des sciences administratives,
132 +Université du Québec en Outaouais (UQO), Gatineau, QC.
133 +📧 [simon-pierre.boucher@uqo.ca](mailto:simon-pierre.boucher@uqo.ca)
134 +
135 +## 🗒 Notes
136 +
137 +- Numbering: first circulated as “Working Paper No. 10” (June 2026); renumbered **13** on 2026-10-17 because No. 10 is *The Assessment Gap in Quebec* (see `Recherche-UQO/HARMONISATION.md`).
138 +- Cover date normalised from “June 13, 2026” to “June 2026”.
139 +- The VQuant platform code is not in this repository (spbgit `vquant.git`).
added paper/.latexmkrc +5 −0
@@ -0,0 +1,5 @@
1 +$pdf_mode = 1;
2 +$pdflatex = 'pdflatex -interaction=nonstopmode -halt-on-error -synctex=1 %O %S';
3 +$bibtex_use = 2;
4 +$clean_ext = 'synctex.gz run.xml bbl bcf fdb_latexmk fls log aux out toc lof lot blg';
5 +@default_files = ('main.tex');
added paper/Makefile +11 −0
@@ -0,0 +1,11 @@
1 +.PHONY: all clean distclean
2 +
3 +all:
4 + latexmk
5 +
6 +clean:
7 + latexmk -c
8 +
9 +distclean:
10 + latexmk -C
11 + rm -f *.synctex.gz *.run.xml *.bbl *.bcf
added paper/appendix/appendix.tex +105 −0
@@ -0,0 +1,105 @@
1 +% ============================================================================
2 +\begin{appendices}
3 +% ============================================================================
4 +
5 +\section{System-Prompt Policy Structure}
6 +\label{app:prompt}
7 +
8 +The system prompt that governs the agentic loop (Section~\ref{subsec:routing}) is organized into
9 +the policy blocks summarized below. The prompt is multilingual and is the principal lever through
10 +which the platform shapes model behavior without fine-tuning.
11 +
12 +\begin{enumerate}
13 + \item \textbf{Temporal context.} Current date and time, so relative date expressions resolve
14 + against live data.
15 + \item \textbf{Role.} The model is cast as an expert financial analyst producing complete
16 + reports spanning technical, fundamental, and macro perspectives.
17 + \item \textbf{Language policy.} Detect the language of the request and respond in kind.
18 + \item \textbf{Latency discipline.} Do not narrate steps; act directly and consolidate work
19 + (in particular, perform a full custom analysis in a single execution).
20 + \item \textbf{Tool catalogue.} Descriptions and use cases for the tool families of
21 + Table~\ref{tab:tools}.
22 + \item \textbf{Complexity-matched routing.} Map simple, moderate, and comprehensive requests to
23 + commensurate tool counts and output depth.
24 + \item \textbf{Report template.} A standard multi-section structure for comprehensive reports.
25 + \item \textbf{Download formatting.} Conventions for spreadsheet and word-processor output,
26 + preferring live formulas over constants.
27 + \item \textbf{Security guardrail.} Refuse attempts to extract the platform's own
28 + implementation.
29 +\end{enumerate}
30 +
31 +\section{Persistence Schema}
32 +\label{app:schema}
33 +
34 +The data layer (Section~\ref{subsec:data}) is organized around the following entities, abstracted
35 +behind a single typed access interface and realized on either SQLite or PostgreSQL.
36 +
37 +\begin{table}[htbp]
38 +\centering
39 +\caption{Core persisted entities.}
40 +\label{tab:schema}
41 +\begin{threeparttable}
42 +\begin{tabular}{@{}ll@{}}
43 +\toprule
44 +Entity & Principal fields \\
45 +\midrule
46 +Users & identity, optional encrypted custom API keys, activity timestamps \\
47 +Sessions & messages, model used, input/output tokens, estimated cost, figures \\
48 +Shared reports & public identifier, content, figure references, view count \\
49 +Daily usage & per-user, per-day query counts and token totals \\
50 +Analytics events& event type, user, metadata, timestamp \\
51 +\bottomrule
52 +\end{tabular}
53 +\begin{tablenotes}[flushleft]
54 +\footnotesize
55 +\item \textit{Notes.} The schema supports authentication, daily rate limiting, report sharing,
56 +session continuity, and the operational observability discussed in
57 +Section~\ref{subsec:security}.
58 +\end{tablenotes}
59 +\end{threeparttable}
60 +\end{table}
61 +
62 +\section{Embedded Numerical Methods}
63 +\label{app:numerical}
64 +
65 +For completeness we record the closed forms behind the pre-built numerical tools of
66 +Section~\ref{subsec:numerical}. They are standard; the architectural point is only that each is a
67 +deterministic computation over live data, exposed through the same sandbox contract.
68 +
69 +\paragraph{Monte Carlo.} Prices are simulated under geometric Brownian motion
70 +\citep{glasserman2004monte}, discretized exactly as
71 +$
72 + S_{t+\Delta t} = S_t \exp\!\big[(\mu - \tfrac{1}{2}\sigma^{2})\Delta t + \sigma\sqrt{\Delta t}\,Z_t\big],
73 +$
74 +with $Z_t \sim \mathcal{N}(0,1)$ and $(\mu,\sigma)$ estimated from historical closes; the default
75 +run generates $10{,}000$ paths over a $252$-day horizon and reports the terminal mean, empirical
76 +confidence intervals, and exceedance probabilities.
77 +
78 +\paragraph{Option pricing.} European options use Black--Scholes--Merton
79 +\citep{black1973pricing,merton1973theory}: with
80 +$d_1 = [\ln(S/K) + (r+\tfrac{1}{2}\sigma^{2})T]/(\sigma\sqrt{T})$ and $d_2 = d_1 - \sigma\sqrt{T}$,
81 +the call price is $C = S\,\Phi(d_1) - Ke^{-rT}\Phi(d_2)$, with the put by parity and the full set
82 +of Greeks ($\Delta,\Gamma,\mathcal{V},\Theta,\rho$) returned analytically.
83 +
84 +\paragraph{Conditional volatility.} A GARCH(1,1) model
85 +\citep{engle1982autoregressive,bollerslev1986generalized} estimates
86 +$h_t = \omega + \alpha\varepsilon_{t-1}^{2} + \beta h_{t-1}$, reporting the parameters,
87 +persistence $\alpha+\beta$, and shock half-life.
88 +
89 +\paragraph{Value-at-Risk.} VaR \citep{jorion2007value} is computed by historical, parametric
90 +($\mu + \sigma\,\Phi^{-1}(1-\alpha)$), and Monte Carlo methods, with expected shortfall and the
91 +Sharpe, Sortino, and Calmar ratios.
92 +
93 +\section{Streaming Event Types}
94 +\label{app:events}
95 +
96 +The client--server channel (Section~\ref{subsec:frontend}) transmits discrete Server-Sent Events,
97 +each dispatched to a dedicated renderer. The principal types are: incremental \emph{text};
98 +reasoning \emph{thinking} summaries; \emph{tools} announcements that drive the progress indicator;
99 +\emph{tool-result} payloads; \emph{sources} for web research; \emph{Python code} that was
100 +executed; \emph{figure} references as images are produced; specialized result objects with bespoke
101 +visualizations; and a terminal \emph{done} event carrying the session identifier and token usage.
102 +This taxonomy is the client-side counterpart to the provider-event dispatch of
103 +Table~\ref{tab:events}.
104 +
105 +\end{appendices}
added paper/figures/architecture.tex +74 −0
@@ -0,0 +1,74 @@
1 +% --- System architecture: layered tiers ---
2 +\begin{figure}[htbp]
3 +\centering
4 +\begin{tikzpicture}[vqfont, node distance=0.95cm and 0.85cm]
5 +
6 +% ---- Client tier ----
7 +\node[vqteal, minimum width=5.2cm] (ui)
8 + {\textbf{Conversational UI}\\[1pt]\vqsmall single-page app; SSE client; figure / table renderers};
9 +
10 +% ---- Server core ----
11 +\node[vqblue, below=of ui, minimum width=5.2cm] (orch)
12 + {\textbf{Orchestration service}\\[1pt]\vqsmall system prompt $\cdot$ token budget $\cdot$ SSE parse};
13 +\node[vqblue, below=of orch, minimum width=5.2cm] (loop)
14 + {\textbf{Recursive tool-calling loop}\\[1pt]\vqsmall batched execution $\cdot$ 5 / batch $\cdot$ 500\,ms};
15 +\node[vqblue, right=1.0cm of loop, minimum width=2.7cm] (db)
16 + {\textbf{Persistence}\\[1pt]\vqsmall sessions $\cdot$ reports\\token ledger $\cdot$ analytics};
17 +
18 +% ---- Executor row ----
19 +\node[vqblue, below left=1.15cm and -0.2cm of loop, minimum width=2.7cm] (fin)
20 + {\textbf{Financial tools}\\[1pt]\vqsmall 265+ endpoints};
21 +\node[vqblue, below=1.15cm of loop, minimum width=2.7cm] (py)
22 + {\textbf{Python sandbox}\\[1pt]\vqsmall 17 libraries};
23 +\node[vqblue, below right=1.15cm and -0.2cm of loop, minimum width=2.7cm] (web)
24 + {\textbf{Web research}\\[1pt]\vqsmall 4 services};
25 +
26 +% ---- External tier ----
27 +\node[vqpurple, below=of fin, minimum width=2.7cm] (fmp)
28 + {\textbf{Market-data API}\\[1pt]\vqsmall live quotes, filings, macro};
29 +\node[vqpurple, below=of py, minimum width=2.7cm] (quant)
30 + {\textbf{Numerical methods}\\[1pt]\vqsmall MC $\cdot$ BSM $\cdot$ GARCH $\cdot$ VaR; figures};
31 +\node[vqpurple, below=of web, minimum width=2.7cm] (search)
32 + {\textbf{Scrape / search}\\[1pt]\vqsmall keyword $\cdot$ semantic};
33 +
34 +% ---- Document pipeline ----
35 +\node[vqorange, below=1.1cm of quant, minimum width=8.6cm] (doc)
36 + {\textbf{Document pipeline} \;\vqsmall PDF $\cdot$ DOCX $\cdot$ Beamer slides $\cdot$ live-formula XLSX};
37 +
38 +% ---- Edges ----
39 +\draw[vqdarr] (ui) -- node[right, vqsmall]{SSE stream} (orch);
40 +\draw[vqarr] (orch) -- (loop);
41 +\draw[vqdarr] (loop) -- (db);
42 +\draw[vqdarr] (loop) -- node[left, vqsmall, pos=0.55]{call} (fin);
43 +\draw[vqdarr] (loop) -- node[right, vqsmall, pos=0.55]{result} (py);
44 +\draw[vqdarr] (loop) -- (web);
45 +\draw[vqdarr] (fin) -- (fmp);
46 +\draw[vqdarr] (py) -- (quant);
47 +\draw[vqdarr] (web) -- (search);
48 +\draw[vqarr] (quant) -- (doc);
49 +% Export path routed along the right margin, clearing the Persistence box
50 +\coordinate (far) at ([xshift=1.15cm]db.east);
51 +\draw[vqflow] (doc.east) to[out=0,in=-90] (far)
52 + to[out=90,in=0] node[right, vqsmall, pos=0.5]{export} (ui.east);
53 +
54 +% ---- Tier bands (background) ----
55 +\begin{scope}[on background layer]
56 + \node[vqband, fill=VQTeal!7, fit=(ui), inner sep=6pt] (bc) {};
57 + \node[vqband, fill=VQBlue!7, fit=(orch)(loop)(db)(fin)(web), inner sep=7pt] (bs) {};
58 + \node[vqband, fill=VQPurple!6, fit=(fmp)(search), inner sep=6pt] (be) {};
59 + \node[vqband, fill=VQOrange!8, fit=(doc), inner sep=6pt] (bd) {};
60 +\end{scope}
61 +\node[vqsmall, rotate=90, text=VQTeal!60!black] at ([xshift=-3pt]bc.west) {CLIENT};
62 +\node[vqsmall, rotate=90, text=VQBlue!60!black] at ([xshift=-3pt]bs.west) {SERVER};
63 +\node[vqsmall, rotate=90, text=VQPurple!55!black] at ([xshift=-3pt]be.west) {EXTERNAL};
64 +
65 +\end{tikzpicture}
66 +\caption{\textbf{Layered system architecture.} The React \emph{client} streams over Server-Sent
67 +Events. The \emph{server} runs the orchestration service and the recursive tool-calling loop,
68 +which routes the model's calls---throttled to five per batch with a 500\,ms spacing---to three
69 +executor families and persists every session. \emph{External} services supply live data,
70 +deterministic numerical results, and web content. On request, the document pipeline renders the
71 +final Markdown into four formats and the result is streamed back to the client. Double-headed
72 +arrows carry a call and its result; the heavy teal arrow is the export path.}
73 +\label{fig:architecture}
74 +\end{figure}
added paper/figures/context.tex +55 −0
@@ -0,0 +1,55 @@
1 +% --- Context-management mechanism: truncation + adaptive summarization ---
2 +\begin{figure}[htbp]
3 +\centering
4 +\begin{tikzpicture}[vqfont,
5 + msg/.style={vqbox, minimum width=0.62cm, minimum height=0.62cm, inner sep=1pt, font=\vqtiny},
6 + oldm/.style={msg, fill=VQInk!8, draw=VQInk!45},
7 + recm/.style={msg, fill=VQTeal!16, draw=VQTeal!70!black},
8 + brace/.style={decorate, decoration={brace, amplitude=4pt}, draw=VQInk!55, line width=0.5pt}]
9 +
10 +% ---- BEFORE row ----
11 +\node[vqsmall, anchor=west, text=VQInk] at (-0.2,2.5) {\textbf{Before} (full message history)};
12 +\foreach \i in {0,1,2,3,4} { \node[oldm] (o\i) at (\i*0.7,1.3) {}; }
13 +\node[recm] (r0) at (3.7,1.3) {};
14 +\node[recm] (r1) at (4.4,1.3) {};
15 +\node[recm] (r2) at (5.1,1.3) {};
16 +\node[recm] (r3) at (5.8,1.3) {};
17 +\node[recm] (r4) at (6.5,1.3) {};
18 +% oversized tool result being capped
19 +\node[vqbox, fill=VQRed!10, draw=VQRed!75!black, minimum width=0.62cm, minimum height=1.15cm,
20 + inner sep=1pt, font=\vqtiny] (big) at (1.4,1.55) {};
21 +\node[vqtag, right=1pt of big, yshift=6pt] {cap at 5000 chars};
22 +
23 +\draw[brace] (-0.25,0.92) -- (2.75,0.92);
24 +\node[vqsmall, anchor=north, text=VQInk!75] at (1.25,0.82) {older turns};
25 +\draw[brace] (3.4,0.92) -- (6.8,0.92);
26 +\node[vqsmall, anchor=north, text=VQTeal!60!black] at (5.1,0.82) {last $k=5$};
27 +
28 +% ---- Transformation gate ----
29 +\node[vqorange, text width=6.0cm] (gate) at (3.2,-0.55)
30 + {\textbf{Estimate} $t \approx \text{chars}/4$. \quad If $t>\tau=10^{5}$:};
31 +\draw[vqarr] (1.25,0.5) -- (gate.north -| 1.25,0);
32 +
33 +% ---- AFTER row ----
34 +\node[vqsmall, anchor=west, text=VQInk] at (-0.2,-2.55) {\textbf{After}};
35 +\node[vqpurple, minimum width=2.75cm, minimum height=0.62cm, font=\vqtiny] (sum) at (1.18,-1.95)
36 + {\textbf{[summary]} (one model call)};
37 +\node[recm] (s0) at (3.7,-1.95) {};
38 +\node[recm] (s1) at (4.4,-1.95) {};
39 +\node[recm] (s2) at (5.1,-1.95) {};
40 +\node[recm] (s3) at (5.8,-1.95) {};
41 +\node[recm] (s4) at (6.5,-1.95) {};
42 +
43 +\draw[vqflow] (gate.west) to[out=180,in=90] node[vqtag,pos=0.6,left]{summarize} (sum.north);
44 +\draw[vqarr] (gate.east) to[out=0,in=90] node[vqtag,pos=0.55,right]{keep} (5.1,-1.63);
45 +
46 +\end{tikzpicture}
47 +\caption{\textbf{Context management.} Before each model call the server caps every individual
48 +tool-result block at a fixed character budget (red), then estimates the total token count with a
49 +cheap chars-per-four heuristic. If the estimate exceeds the threshold $\tau$, the older turns are
50 +compressed by a single dedicated summarization call into one synthetic \texttt{[summary]} message
51 +(purple), while the most recent $k=5$ turns (teal) are kept verbatim. The mechanism makes
52 +conversation length effectively unbounded at the cost of one extra call when the threshold is
53 +crossed.}
54 +\label{fig:context}
55 +\end{figure}
added paper/figures/docpipeline.tex +35 −0
@@ -0,0 +1,35 @@
1 +% --- Document-generation pipeline: single source, many formats ---
2 +\begin{figure}[htbp]
3 +\centering
4 +\begin{tikzpicture}[vqfont]
5 +
6 +\node[vqteal, text width=2.7cm, minimum height=1.7cm] (md) at (0,0)
7 + {\textbf{Markdown report}\\[1pt]\vqsmall streamed text\\$+$ figure refs};
8 +
9 +\node[vqred, text width=4.3cm] (pdf) at (8.2, 3.0)
10 + {\textbf{PDF}\\\vqsmall protect--parse--restore math $\to$ headless browser $\to$ \textit{wait for render}};
11 +\node[vqpurple, text width=4.3cm] (slides) at (8.2, 1.0)
12 + {\textbf{Beamer slides}\\\vqsmall 2nd model call restructures $\to$ branded preamble $\to$ two \LaTeX{} passes};
13 +\node[vqblue, text width=4.3cm] (docx) at (8.2,-0.7)
14 + {\textbf{DOCX}\\\vqsmall document converter preserves tables / structure};
15 +\node[vqgreen, text width=4.3cm] (xlsx) at (8.2,-2.3)
16 + {\textbf{XLSX}\\\vqsmall sandbox \texttt{save\_excel} $\to$ \textit{live} formulas, conditional formats};
17 +\node[vqorange, text width=4.3cm] (share) at (8.2,-3.9)
18 + {\textbf{Share URL}\\\vqsmall store content $+$ figures $\to$ public viewer};
19 +
20 +\draw[vqflow] (md.east) to[out=35,in=180] (pdf.west);
21 +\draw[vqflow] (md.east) to[out=18,in=180] (slides.west);
22 +\draw[vqflow] (md.east) to[out=0,in=180] (docx.west);
23 +\draw[vqflow] (md.east) to[out=-18,in=180] (xlsx.west);
24 +\draw[vqflow] (md.east) to[out=-32,in=180] (share.west);
25 +
26 +\end{tikzpicture}
27 +\caption{\textbf{The unified document pipeline.} A single Markdown artifact is rendered into four
28 +document formats and a shareable view, each by a distinct mechanism. The PDF path protects
29 +mathematics from the Markdown parser with placeholder tokens, renders in a real browser engine,
30 +and waits for the math to appear before capture. The slide path issues a \emph{second} model call
31 +that restructures the report into slide bodies, then compiles a branded Beamer document in two
32 +\LaTeX{} passes. Word uses a document converter; spreadsheets carry live formulas written from the
33 +sandbox; and any report can be published to a stable URL. One source, many auditable deliverables.}
34 +\label{fig:docpipeline}
35 +\end{figure}
added paper/figures/loop.tex +44 −0
@@ -0,0 +1,44 @@
1 +% --- Recursive tool-calling loop flowchart ---
2 +\begin{figure}[htbp]
3 +\centering
4 +\begin{tikzpicture}[vqfont, node distance=0.72cm]
5 +
6 +\node[vqteal, text width=3.2cm] (start)
7 + {\textbf{User query}\\\vqsmall (+ optional image)};
8 +\node[vqblue, below=of start, text width=4.4cm] (stream)
9 + {\textbf{Stream model call}\\\vqsmall system prompt $+$ context $+$ tools};
10 +\node[vqdecision, below=0.95cm of stream, text width=1.9cm] (dec)
11 + {\vqsmall tools\\requested?};
12 +\node[vqgreen, right=2.0cm of dec, text width=3.0cm] (final)
13 + {\textbf{Final report}\\\vqsmall accumulated text $\to$ export};
14 +
15 +\node[vqblue, below=1.0cm of dec, text width=4.6cm] (asst)
16 + {\textbf{Append} assistant \texttt{tool\_use} blocks};
17 +\node[vqblue, below=of asst, text width=6.0cm] (batch)
18 + {\textbf{For each batch ($\leq 5$ tools)}\\\vqsmall execute in batch $\cdot$ stream typed result $\cdot$ \textsc{wait} 500\,ms};
19 +\node[vqblue, below=of batch, text width=4.6cm] (res)
20 + {\textbf{Append} user \texttt{tool\_result} blocks};
21 +
22 +% Edges
23 +\draw[vqarr] (start) -- (stream);
24 +\draw[vqarr] (stream) -- (dec);
25 +\draw[vqarr] (dec) -- node[above, vqsmall]{no} (final);
26 +\draw[vqarr] (dec) -- node[right, vqsmall]{yes} (asst);
27 +\draw[vqarr] (asst) -- (batch);
28 +\draw[vqarr] (batch) -- (res);
29 +
30 +% Recursion arrow (left side, back up to stream)
31 +\draw[vqflow] (res.west) -- ++(-2.55,0)
32 + node[vqtag, midway, above]{recurse}
33 + |- (stream.west);
34 +
35 +\end{tikzpicture}
36 +\caption{\textbf{The recursive tool-calling loop.} A single routine streams one model call. If no
37 +tools are requested, the accumulated text is the report and the recursion unwinds. Otherwise the
38 +server appends the model's \texttt{tool\_use} blocks (as an assistant turn), executes the requested
39 +tools in throttled batches of at most five, appends the matching \texttt{tool\_result} blocks (as
40 +a user turn), and \emph{re-enters} the same routine with the augmented context (heavy teal arrow).
41 +The strict pairing of \texttt{tool\_use} and \texttt{tool\_result} blocks across the recursion is
42 +the loop's central invariant.}
43 +\label{fig:loop}
44 +\end{figure}
added paper/figures/sandbox.tex +50 −0
@@ -0,0 +1,50 @@
1 +% --- Python execution sandbox: isolation boundary + IPC ---
2 +\begin{figure}[htbp]
3 +\centering
4 +\begin{tikzpicture}[vqfont]
5 +
6 +% ---- Server side ----
7 +\node[vqblue, text width=2.6cm, minimum height=2.0cm] (srv) at (0,0)
8 + {\textbf{Server}\\\vqsmall \texttt{spawn} child\\ write stdin\\ read stdout};
9 +
10 +% ---- Child inner stages ----
11 +\node[vqgreen, text width=4.5cm] (ns) at (8.0,2.05)
12 + {\textbf{Build namespace}\\\vqsmall 17 libs $\cdot$ \texttt{save\_excel}/\texttt{save\_word} $\cdot$ \texttt{fmp} client $\cdot$ context vars};
13 +\node[vqorange, text width=4.5cm] (ex) at (8.0,0.35)
14 + {\textbf{\texttt{exec(code, ns)}}\\\vqsmall \texttt{stdout}/\texttt{stderr} $\to$ string buffers $\cdot$ optional \texttt{main()}};
15 +\node[vqpurple, text width=4.5cm] (cap) at (8.0,-1.35)
16 + {\textbf{Figure capture}\\\vqsmall \texttt{get\_fignums} $\to$ PNG @150\,dpi $\to$ base64};
17 +
18 +\draw[vqarr] (ns) -- (ex);
19 +\draw[vqarr] (ex) -- (cap);
20 +
21 +% Child container
22 +\begin{scope}[on background layer]
23 + \node[vqband, fill=VQInk!4, draw=VQInk!35, line width=0.5pt, dashed,
24 + fit=(ns)(ex)(cap), inner sep=10pt] (child) {};
25 +\end{scope}
26 +\node[vqsmall, anchor=north west, text=VQInk!70] at (child.north west)
27 + {\textbf{Child Python process}~~\vqtiny(\texttt{PYTHONUNBUFFERED}, 90\,s timeout, Agg backend)};
28 +
29 +% ---- IPC arrows across the boundary ----
30 +\draw[vqflow] (srv.east) to[out=25,in=180]
31 + node[vqtag, pos=0.5, above]{stdin: \texttt{\{code, context, key\}}} (ns.west);
32 +\draw[vqflow, draw=VQTeal!80!black] (cap.west) to[out=180,in=-25]
33 + node[vqtag, pos=0.5, below]{stdout: \texttt{\{output, figures[], files[]\}}} (srv.east);
34 +
35 +% Isolation boundary marker
36 +\draw[VQRed!70!black, line width=0.7pt, dash pattern=on 3pt off 2pt]
37 + (3.0,2.8) -- (3.0,-2.3);
38 +\node[vqtag, text=VQRed!70!black, fill=white] at (3.0,-2.6) {process isolation};
39 +
40 +\end{tikzpicture}
41 +\caption{\textbf{The Python execution sandbox.} The server runs model-authored code in a separate
42 +interpreter, not in process. It serializes one JSON request to the child's standard input; the
43 +child builds an execution namespace (scientific libraries, artifact helpers, a market-data client,
44 +and any context variables), runs the code with output redirected into string buffers, then sweeps
45 +all live matplotlib figures into base64-encoded PNGs and returns a single JSON response. A
46 +non-zero exit or empty output is surfaced as an error so the model can revise. The dashed boundary
47 +is the process-isolation line; the red marker emphasizes that a crash or timeout cannot reach the
48 +server.}
49 +\label{fig:sandbox}
50 +\end{figure}
added paper/figures/streaming.tex +48 −0
@@ -0,0 +1,48 @@
1 +% --- Streaming SSE parsing and event dispatch ---
2 +\begin{figure}[htbp]
3 +\centering
4 +\begin{tikzpicture}[vqfont]
5 +
6 +% Pipeline backbone
7 +\node[vqpurple, minimum height=1.5cm, text width=2.0cm] (prov) at (0,0)
8 + {\textbf{Provider}\\\vqsmall \texttt{/v1/messages}\\ streaming HTTP};
9 +\node[vqblue, minimum height=1.5cm, text width=2.35cm] (buf) at (3.5,0)
10 + {\textbf{Byte buffer}\\\vqsmall append chunk;\\split on \texttt{\textbackslash n};\\\textit{keep partial line}};
11 +\node[vqblue, minimum height=1.5cm, text width=2.2cm] (disp) at (7.05,0)
12 + {\textbf{Dispatch}\\\vqsmall parse \texttt{data:} line\\$\to$ JSON;\\switch on \texttt{type}};
13 +
14 +% Right-hand output channels
15 +\node[vqgreen, text width=3.0cm] (txt) at (11.0, 2.55)
16 + {\textbf{Answer channel}\\\vqsmall \texttt{text\_delta} $\to$ accumulate $+$ stream};
17 +\node[vqgreen, text width=3.0cm] (think) at (11.0, 1.05)
18 + {\textbf{Reasoning channel}\\\vqsmall \texttt{thinking\_delta} $\to$ separate panel};
19 +\node[vqorange, text width=3.0cm] (tool) at (11.0,-0.65)
20 + {\textbf{Tool assembler}\\\vqsmall \texttt{start} $\cdot$ \texttt{input\_json\_delta}$^\ast$ $\cdot$ \texttt{stop} $\to$ args};
21 +\node[vqred, text width=3.0cm] (tok) at (11.0,-2.35)
22 + {\textbf{Token ledger}\\\vqsmall \texttt{message\_start/delta/stop} $\to$ usage};
23 +
24 +% Backbone arrows
25 +\draw[vqflow] (prov) -- node[vqtag, above]{raw bytes} (buf);
26 +\draw[vqflow] (buf) -- node[vqtag, above]{\texttt{data:} lines} (disp);
27 +
28 +% Fan-out
29 +\draw[vqarr] (disp.east) to[out=20,in=180] (txt.west);
30 +\draw[vqarr] (disp.east) to[out=8,in=180] (think.west);
31 +\draw[vqarr] (disp.east) to[out=-8,in=180] (tool.west);
32 +\draw[vqarr] (disp.east) to[out=-22,in=180] (tok.west);
33 +
34 +% Downstream consequences
35 +\draw[vqdash] (tool.south) to[out=-90,in=-90] node[vqtag, below, pos=0.5]{executable $\to$ loop} (disp.south);
36 +
37 +\end{tikzpicture}
38 +\caption{\textbf{Streaming transport and event dispatch.} The server reads the provider's
39 +Server-Sent Event stream as raw bytes, buffers them, and splits on newlines while \emph{retaining
40 +the trailing partial line} (frames do not align with packet boundaries). Each \texttt{data:} line
41 +is parsed to JSON and dispatched on its \texttt{type} onto four channels: answer text is
42 +accumulated and forwarded; private reasoning is forwarded to a separate panel; a tool call is
43 +assembled from a \texttt{content\_block\_start}, a sequence of \texttt{input\_json\_delta}
44 +fragments ($\ast$), and a closing \texttt{content\_block\_stop}, becoming executable only once the
45 +block closes; and usage events feed the token ledger. Heavy arrows are the byte backbone; thin
46 +arrows are per-event dispatch.}
47 +\label{fig:streaming}
48 +\end{figure}
added paper/main.pdf +0 −0

Binary file not shown.

added paper/main.tex +228 −0
@@ -0,0 +1,228 @@
1 +% ============================================================================
2 +% UQO Working Paper — Economics / Finance
3 +% VQuant: An Agentic LLM Architecture for Quantitative Financial Analysis
4 +% ============================================================================
5 +\documentclass[12pt,letterpaper]{article}
6 +
7 +% --- Encoding & Language ---
8 +\usepackage[utf8]{inputenc}
9 +\usepackage[T1]{fontenc}
10 +\usepackage[english]{babel}
11 +
12 +% --- Page Layout ---
13 +\usepackage[
14 + letterpaper,
15 + top=1in,
16 + bottom=1in,
17 + left=1in,
18 + right=1in
19 +]{geometry}
20 +
21 +% --- Typography ---
22 +\usepackage{mathptmx} % Times-like font (text + math)
23 +\usepackage{microtype} % Improved typographic refinements
24 +\usepackage{setspace}
25 +\onehalfspacing % 1.5 line spacing
26 +
27 +% --- Math ---
28 +\usepackage{amsmath,amssymb,amsthm}
29 +
30 +% --- Algorithms ---
31 +\usepackage{algorithm}
32 +\usepackage{algpseudocode}
33 +
34 +% --- Code Listings ---
35 +\usepackage{listings}
36 +\lstset{
37 + basicstyle=\ttfamily\footnotesize,
38 + breaklines=true,
39 + columns=fullflexible,
40 + keepspaces=true,
41 + frame=single,
42 + rulecolor=\color{black!30},
43 + backgroundcolor=\color{black!3},
44 + showstringspaces=false,
45 + captionpos=b
46 +}
47 +
48 +% --- Tables ---
49 +\usepackage{booktabs}
50 +\usepackage{tabularx}
51 +\usepackage{multirow}
52 +\usepackage{threeparttable}
53 +\usepackage{siunitx}
54 +\sisetup{
55 + input-symbols = {()},
56 + table-format = -1.3,
57 + parse-numbers = false
58 +}
59 +
60 +% --- Figures & Diagrams ---
61 +\usepackage{graphicx}
62 +\usepackage{subcaption}
63 +\usepackage{float}
64 +\usepackage{tikz}
65 +\usetikzlibrary{arrows.meta,positioning,shapes.geometric,shapes.misc,fit,backgrounds,calc,shadows,decorations.pathreplacing}
66 +
67 +% --- Colors & Links ---
68 +\usepackage[dvipsnames]{xcolor}
69 +\usepackage[
70 + colorlinks = true,
71 + linkcolor = NavyBlue,
72 + citecolor = NavyBlue,
73 + urlcolor = NavyBlue,
74 + breaklinks = true,
75 + pdftitle = {VQuant: An Agentic Large Language Model Architecture for Automated Quantitative Financial Analysis and Document Generation},
76 + pdfauthor = {Simon-Pierre Boucher}
77 +]{hyperref}
78 +
79 +% --- Bibliography ---
80 +\usepackage[authoryear,round,semicolon]{natbib}
81 +\bibliographystyle{aer}
82 +
83 +% --- Captions ---
84 +\usepackage[
85 + font = small,
86 + labelfont = bf,
87 + labelsep = period,
88 + justification = justified,
89 + singlelinecheck = false
90 +]{caption}
91 +
92 +% --- Headers & Footers ---
93 +\usepackage{fancyhdr}
94 +\pagestyle{fancy}
95 +\fancyhf{}
96 +\renewcommand{\headrulewidth}{0pt}
97 +\fancyfoot[C]{\thepage}
98 +
99 +% --- Section Formatting ---
100 +\usepackage{titlesec}
101 +\titleformat{\section}{\large\bfseries}{\thesection.}{0.5em}{}
102 +\titleformat{\subsection}{\normalsize\bfseries}{\thesubsection.}{0.5em}{}
103 +\titleformat{\subsubsection}{\normalsize\itshape}{\thesubsubsection.}{0.5em}{}
104 +
105 +% --- Appendix Support ---
106 +\usepackage[toc,page]{appendix}
107 +
108 +% --- Misc ---
109 +\usepackage{enumitem}
110 +\setlist{nosep,leftmargin=*}
111 +
112 +% --- Custom colors (VQuant palette) ---
113 +\definecolor{VQTeal}{HTML}{119993}
114 +\definecolor{VQBlue}{HTML}{2072B2}
115 +\definecolor{VQPurple}{HTML}{652E89}
116 +\definecolor{VQOrange}{HTML}{F49422}
117 +\definecolor{VQGreen}{HTML}{4Fa64B}
118 +\definecolor{VQRed}{HTML}{EF632B}
119 +\definecolor{VQDark}{HTML}{2B2D42}
120 +\definecolor{VQInk}{HTML}{32353F}
121 +
122 +% --- Font macros used inside diagram node text ---
123 +\newcommand{\vqsmall}{\scriptsize}
124 +\newcommand{\vqtiny}{\fontsize{6.4}{7.5}\selectfont}
125 +
126 +% --- Shared TikZ styles for all diagrams ---
127 +\tikzset{
128 + vqfont/.style = {font=\footnotesize},
129 + vqsmall/.style = {font=\scriptsize},
130 + vqtiny/.style = {font=\fontsize{6.4}{7.5}\selectfont},
131 + vqbox/.style = {rectangle, rounded corners=3pt, draw=black!45, line width=0.5pt,
132 + align=center, inner sep=4.5pt, minimum height=0.78cm, fill=white,
133 + drop shadow={shadow xshift=0.6pt, shadow yshift=-0.6pt, opacity=0.18}},
134 + vqteal/.style = {vqbox, draw=VQTeal!75!black, fill=VQTeal!12, text=VQDark},
135 + vqblue/.style = {vqbox, draw=VQBlue!75!black, fill=VQBlue!12, text=VQDark},
136 + vqpurple/.style = {vqbox, draw=VQPurple!75!black, fill=VQPurple!10, text=VQDark},
137 + vqorange/.style = {vqbox, draw=VQOrange!80!black, fill=VQOrange!14, text=VQDark},
138 + vqgreen/.style = {vqbox, draw=VQGreen!75!black, fill=VQGreen!14, text=VQDark},
139 + vqred/.style = {vqbox, draw=VQRed!80!black, fill=VQRed!12, text=VQDark},
140 + vqdecision/.style= {diamond, aspect=1.7, draw=VQOrange!80!black, fill=VQOrange!14,
141 + align=center, inner sep=1pt, line width=0.5pt, text=VQDark},
142 + vqarr/.style = {-{Latex[length=2mm,width=1.6mm]}, line width=0.6pt, draw=VQInk!75},
143 + vqdarr/.style = {{Latex[length=2mm,width=1.6mm]}-{Latex[length=2mm,width=1.6mm]},
144 + line width=0.6pt, draw=VQInk!75},
145 + vqflow/.style = {-{Latex[length=2.2mm,width=1.8mm]}, line width=1.1pt, draw=VQTeal!80!black},
146 + vqdash/.style = {-{Latex[length=2mm,width=1.6mm]}, line width=0.55pt, draw=VQInk!60, dashed},
147 + vqband/.style = {rounded corners=5pt, draw=none, line width=0pt},
148 + vqtag/.style = {rectangle, rounded corners=2pt, inner sep=2pt, font=\vqtiny,
149 + fill=white, draw=black!25}
150 +}
151 +
152 +% ============================================================================
153 +% METADATA
154 +% ============================================================================
155 +\newcommand{\WPnumber}{13}
156 +\newcommand{\WPtitle}{VQuant: An Agentic Large Language Model Architecture for Automated Quantitative Financial Analysis and Document Generation}
157 +\newcommand{\WPsubtitle}{Reasoning-Augmented Tool Orchestration, In-Loop Numerical Computation, and Multi-Format Reporting}
158 +\newcommand{\WPdate}{June 2026}
159 +\newcommand{\WPversion}{1.0}
160 +\newcommand{\WPabstract}{%
161 + Large language models (LLMs) have shown remarkable fluency in financial discourse, yet
162 + conversational fluency alone does not guarantee numerically rigorous, reproducible, or
163 + citable analysis. This paper presents \textbf{VQuant}, a production-grade web platform that
164 + couples a reasoning-augmented LLM with a deterministic execution substrate to transform a
165 + natural-language request into a complete quantitative financial report. We document the
166 + system's methodology and its principal innovations: (i)~an \emph{agentic orchestration loop}
167 + that exposes more than two hundred financial and analytical tools---spanning over 265
168 + market-data endpoints, four web-research services, and an arbitrary-code Python sandbox of
169 + seventeen scientific libraries---to the model through a constrained function-calling protocol;
170 + (ii)~a \emph{context-management algorithm} that preserves conversational coherence over
171 + effectively unbounded histories via adaptive summarization under a token budget;
172 + (iii)~a \emph{single-call computation paradigm} that consolidates data acquisition, numerical
173 + estimation, and figure rendering into one sandboxed Python execution, collapsing what would
174 + otherwise be several model round trips into one; and (iv)~a \emph{unified document pipeline}
175 + that emits publication-ready PDF, DOCX, \LaTeX{}~Beamer slide decks, and spreadsheet workbooks
176 + with live formulas from a single Markdown artifact. We describe each mechanism as it is
177 + implemented---the streaming Server-Sent-Event protocol and its eight-way event dispatch, the
178 + recursive tool-calling loop and its tool-use/tool-result invariant, the batched-execution
179 + throttle, the two-stage context-management machinery, the token-accounting correction, and the
180 + inter-process sandbox that exec's model-authored code and captures its figures---so that the
181 + design can be reproduced. The classical quantitative methods the platform automates are
182 + conventional and relegated to an appendix; our contribution is the \emph{architecture} that
183 + makes them accessible through natural language while preserving reproducibility. We argue that
184 + VQuant illustrates a reusable design pattern in which the language model is positioned as a
185 + planner and synthesizer rather than as a calculator, with all numerical work delegated to
186 + auditable, deterministic code.
187 +}
188 +\newcommand{\WPkeywords}{Large language models, agentic systems, tool use, quantitative finance, automated reporting, retrieval-augmented generation, financial NLP}
189 +\newcommand{\WPjel}{C45, C63, C88, G17}
190 +
191 +% --- Author ---
192 +\newcommand{\WPauthor}{Simon-Pierre Boucher}
193 +\newcommand{\WPaffiliation}{%
194 + Département des sciences administratives\\
195 + Université du Québec en Outaouais%
196 +}
197 +\newcommand{\WPemail}{simon-pierre.boucher@uqo.ca}
198 +\newcommand{\WPaddress}{%
199 + Gatineau -- Pavillon Alexandre-Taché\\
200 + 283, boulevard Alexandre-Taché\\
201 + Gatineau, Québec, Canada J9A 1L8%
202 +}
203 +
204 +% ============================================================================
205 +% DOCUMENT
206 +% ============================================================================
207 +\begin{document}
208 +
209 +% --- Title Page ---
210 +\input{sections/titlepage}
211 +
212 +% --- Main Body ---
213 +\input{sections/introduction}
214 +\input{sections/literature}
215 +\input{sections/data}
216 +\input{sections/methodology}
217 +\input{sections/results}
218 +\input{sections/robustness}
219 +\input{sections/conclusion}
220 +
221 +% --- References ---
222 +\newpage
223 +\bibliography{references}
224 +
225 +% --- Appendix ---
226 +\input{appendix/appendix}
227 +
228 +\end{document}
added paper/references.bib +181 −0
@@ -0,0 +1,181 @@
1 +% ============================================================================
2 +% References — BibTeX Database
3 +% ============================================================================
4 +
5 +% --- Language models and reasoning ---
6 +@inproceedings{vaswani2017attention,
7 + author = {Vaswani, Ashish and Shazeer, Noam and Parmar, Niki and Uszkoreit, Jakob and
8 + Jones, Llion and Gomez, Aidan N. and Kaiser, {\L}ukasz and Polosukhin, Illia},
9 + title = {Attention Is All You Need},
10 + booktitle = {Advances in Neural Information Processing Systems},
11 + volume = {30},
12 + year = {2017}
13 +}
14 +
15 +@inproceedings{brown2020language,
16 + author = {Brown, Tom B. and Mann, Benjamin and Ryder, Nick and Subbiah, Melanie and others},
17 + title = {Language Models Are Few-Shot Learners},
18 + booktitle = {Advances in Neural Information Processing Systems},
19 + volume = {33},
20 + pages = {1877--1901},
21 + year = {2020}
22 +}
23 +
24 +@inproceedings{wei2022chain,
25 + author = {Wei, Jason and Wang, Xuezhi and Schuurmans, Dale and Bosma, Maarten and
26 + Ichter, Brian and Xia, Fei and Chi, Ed H. and Le, Quoc V. and Zhou, Denny},
27 + title = {Chain-of-Thought Prompting Elicits Reasoning in Large Language Models},
28 + booktitle = {Advances in Neural Information Processing Systems},
29 + volume = {35},
30 + pages = {24824--24837},
31 + year = {2022}
32 +}
33 +
34 +@article{bommasani2021opportunities,
35 + author = {Bommasani, Rishi and Hudson, Drew A. and Adeli, Ehsan and Altman, Russ and others},
36 + title = {On the Opportunities and Risks of Foundation Models},
37 + journal = {arXiv preprint arXiv:2108.07258},
38 + year = {2021}
39 +}
40 +
41 +% --- Tool use and agents ---
42 +@inproceedings{schick2023toolformer,
43 + author = {Schick, Timo and Dwivedi-Yu, Jane and Dess{\`i}, Roberto and Raileanu, Roberta and
44 + Lomeli, Maria and Hambro, Eric and Zettlemoyer, Luke and Cancedda, Nicola and
45 + Scialom, Thomas},
46 + title = {Toolformer: Language Models Can Teach Themselves to Use Tools},
47 + booktitle = {Advances in Neural Information Processing Systems},
48 + volume = {36},
49 + year = {2023}
50 +}
51 +
52 +@inproceedings{yao2023react,
53 + author = {Yao, Shunyu and Zhao, Jeffrey and Yu, Dian and Du, Nan and Shafran, Izhak and
54 + Narasimhan, Karthik and Cao, Yuan},
55 + title = {{ReAct}: Synergizing Reasoning and Acting in Language Models},
56 + booktitle = {International Conference on Learning Representations (ICLR)},
57 + year = {2023}
58 +}
59 +
60 +@inproceedings{gao2023pal,
61 + author = {Gao, Luyu and Madaan, Aman and Zhou, Shuyan and Alon, Uri and Liu, Pengfei and
62 + Yang, Yiming and Callan, Jamie and Neubig, Graham},
63 + title = {{PAL}: Program-Aided Language Models},
64 + booktitle = {International Conference on Machine Learning (ICML)},
65 + pages = {10764--10799},
66 + year = {2023}
67 +}
68 +
69 +@misc{anthropic2024tooluse,
70 + author = {{Anthropic}},
71 + title = {Tool Use (Function Calling) with the {Claude} {API}},
72 + howpublished = {Anthropic Documentation},
73 + year = {2024}
74 +}
75 +
76 +% --- Retrieval and grounding ---
77 +@inproceedings{lewis2020retrieval,
78 + author = {Lewis, Patrick and Perez, Ethan and Piktus, Aleksandra and Petroni, Fabio and
79 + Karpukhin, Vladimir and Goyal, Naman and K{\"u}ttler, Heinrich and Lewis, Mike and
80 + Yih, Wen-tau and Rockt{\"a}schel, Tim and Riedel, Sebastian and Kiela, Douwe},
81 + title = {Retrieval-Augmented Generation for Knowledge-Intensive {NLP} Tasks},
82 + booktitle = {Advances in Neural Information Processing Systems},
83 + volume = {33},
84 + pages = {9459--9474},
85 + year = {2020}
86 +}
87 +
88 +@book{lopezdeprado2018advances,
89 + author = {L{\'o}pez de Prado, Marcos},
90 + title = {Advances in Financial Machine Learning},
91 + publisher = {John Wiley \& Sons},
92 + year = {2018}
93 +}
94 +
95 +% --- LLMs in finance ---
96 +@article{wu2023bloomberggpt,
97 + author = {Wu, Shijie and Irsoy, Ozan and Lu, Steven and Dabravolski, Vadim and Dredze, Mark and
98 + Gehrmann, Sebastian and Kambadur, Prabhanjan and Rosenberg, David and Mann, Gideon},
99 + title = {{BloombergGPT}: A Large Language Model for Finance},
100 + journal = {arXiv preprint arXiv:2303.17564},
101 + year = {2023}
102 +}
103 +
104 +@article{yang2023fingpt,
105 + author = {Yang, Hongyang and Liu, Xiao-Yang and Wang, Christina Dan},
106 + title = {{FinGPT}: Open-Source Financial Large Language Models},
107 + journal = {arXiv preprint arXiv:2306.06031},
108 + year = {2023}
109 +}
110 +
111 +@article{lopezlira2023chatgpt,
112 + author = {Lopez-Lira, Alejandro and Tang, Yuehua},
113 + title = {Can {ChatGPT} Forecast Stock Price Movements? Return Predictability and Large
114 + Language Models},
115 + journal = {arXiv preprint arXiv:2304.07619},
116 + year = {2023}
117 +}
118 +
119 +@article{kim2024financial,
120 + author = {Kim, Alex and Muhn, Maximilian and Nikolaev, Valeri},
121 + title = {Financial Statement Analysis with Large Language Models},
122 + journal = {arXiv preprint arXiv:2407.17866},
123 + year = {2024}
124 +}
125 +
126 +% --- Classical quantitative finance ---
127 +@article{black1973pricing,
128 + author = {Black, Fischer and Scholes, Myron},
129 + title = {The Pricing of Options and Corporate Liabilities},
130 + journal = {Journal of Political Economy},
131 + volume = {81},
132 + number = {3},
133 + pages = {637--654},
134 + year = {1973}
135 +}
136 +
137 +@article{merton1973theory,
138 + author = {Merton, Robert C.},
139 + title = {Theory of Rational Option Pricing},
140 + journal = {Bell Journal of Economics and Management Science},
141 + volume = {4},
142 + number = {1},
143 + pages = {141--183},
144 + year = {1973}
145 +}
146 +
147 +@article{engle1982autoregressive,
148 + author = {Engle, Robert F.},
149 + title = {Autoregressive Conditional Heteroscedasticity with Estimates of the Variance of
150 + United Kingdom Inflation},
151 + journal = {Econometrica},
152 + volume = {50},
153 + number = {4},
154 + pages = {987--1007},
155 + year = {1982}
156 +}
157 +
158 +@article{bollerslev1986generalized,
159 + author = {Bollerslev, Tim},
160 + title = {Generalized Autoregressive Conditional Heteroskedasticity},
161 + journal = {Journal of Econometrics},
162 + volume = {31},
163 + number = {3},
164 + pages = {307--327},
165 + year = {1986}
166 +}
167 +
168 +@book{glasserman2004monte,
169 + author = {Glasserman, Paul},
170 + title = {Monte Carlo Methods in Financial Engineering},
171 + publisher = {Springer},
172 + year = {2004}
173 +}
174 +
175 +@book{jorion2007value,
176 + author = {Jorion, Philippe},
177 + title = {Value at Risk: The New Benchmark for Managing Financial Risk},
178 + edition = {3rd},
179 + publisher = {McGraw-Hill},
180 + year = {2007}
181 +}
added paper/sections/conclusion.tex +43 −0
@@ -0,0 +1,43 @@
1 +% ============================================================================
2 +\section{Conclusion}
3 +\label{sec:conclusion}
4 +% ============================================================================
5 +
6 +This paper has documented the methodology and innovations of VQuant, a production-grade platform
7 +that turns a natural-language request into a complete, reproducible quantitative financial
8 +report. The system's organizing principle is a strict division of labor: the large language
9 +model plans and synthesizes, while deterministic code retrieves data and performs computation.
10 +This separation is what allows VQuant to combine the accessibility of a conversational interface
11 +with the rigor demanded by financial analysis.
12 +
13 +We highlighted four methodological contributions. The \emph{agentic orchestration loop}
14 +(Section~\ref{subsec:loop}) exposes a curated catalogue of more than two hundred tools to the
15 +model through a constrained, batched, fully streaming protocol, with a system prompt that routes
16 +requests by complexity. The \emph{context-management algorithm} (Section~\ref{subsec:context})
17 +keeps arbitrarily long conversations within the model's window by adaptively summarizing older
18 +history while preserving recent turns verbatim. The \emph{single-call computation paradigm}
19 +(Section~\ref{subsec:onecall}) consolidates data acquisition, estimation, and visualization into
20 +one sandboxed Python execution, materially reducing latency relative to sequential tool calling.
21 +And the \emph{unified document pipeline} (Section~\ref{subsec:docs}) emits PDF, Word, Beamer
22 +slides, and live-formula spreadsheets from a single Markdown artifact. We described each of these
23 +at the mechanism level---the eight-way event dispatch, the recursive loop and its
24 +tool-use/tool-result invariant, the batching throttle, the two-stage context machinery, the
25 +token-accounting correction, and the inter-process sandbox that exec's model-authored code and
26 +captures its figures---together with the streaming experience, multi-model selection, cost
27 +discipline, and security measures that make the system practical. The classical quantitative
28 +methods the platform automates are conventional and recorded compactly in the appendix; the
29 +contribution is the architecture, not the formulae.
30 +
31 +The natural next step is empirical. A rigorous evaluation would benchmark VQuant against
32 +baseline agentic patterns along three axes: \emph{quality}, via expert assessment of report
33 +accuracy and completeness on a fixed task suite; \emph{efficiency}, via controlled measurement of
34 +latency, token consumption, and dollar cost, isolating the contribution of the single-call
35 +paradigm and the context-management algorithm; and \emph{reliability}, via systematic probing
36 +for numerical and interpretive errors. Methodologically, the design admits several extensions:
37 +incorporating provider-agnostic tool exposure to broaden the model layer; adding a verification
38 +pass in which a second model audits the first model's narrative against the computed numbers; and
39 +generalizing the deterministic-computation substrate beyond finance to any domain where
40 +auditable numbers matter. We offer VQuant as a concrete, reproducible instance of \emph{agentic
41 +financial intelligence}---a design pattern in which the language model is a disciplined
42 +orchestrator of trustworthy tools rather than an unverified oracle---and as a foundation for the
43 +evaluation agenda above.
added paper/sections/data.tex +90 −0
@@ -0,0 +1,90 @@
1 +% ============================================================================
2 +\section{System Architecture and Data Layer}
3 +\label{sec:architecture}
4 +% ============================================================================
5 +
6 +This section describes VQuant's architecture, the data it consumes, and the external services
7 +it integrates. We treat the architecture as the ``setting'' of the paper: the methodology of
8 +Section~\ref{sec:methodology} is a set of algorithms that run \emph{within} the structure
9 +described here.
10 +
11 +\subsection{Overview}
12 +\label{subsec:overview}
13 +
14 +VQuant is a full-stack TypeScript monorepo comprising three cooperating tiers
15 +(Figure~\ref{fig:architecture}). A \textbf{React front end} renders a conversational interface
16 +and streams results to the user as they are produced. A \textbf{modular Express back end}
17 +orchestrates the LLM, executes tool calls, manages context and authentication, and persists
18 +sessions. An \textbf{isolated Python layer} performs numerical computation in a sandboxed
19 +subprocess. The three tiers communicate over HTTP, with the client--server channel using
20 +Server-Sent Events (SSE) to stream incremental output. The data layer is abstracted through an
21 +object-relational mapper that targets SQLite in development and PostgreSQL in production behind
22 +a single typed access interface, so that storage logic is identical across environments.
23 +
24 +\input{figures/architecture}
25 +
26 +\subsection{The front end}
27 +\label{subsec:frontend}
28 +
29 +The client is a single-page application. Its central abstraction is a session hook that owns
30 +the full conversational state---the streaming answer, the model's intermediate reasoning, the
31 +ordered list of tool invocations, retrieved sources, generated figures, and the results of
32 +specialized computations such as Monte Carlo simulations and option-pricing tables. A companion
33 +mutation hook manages the SSE connection: it issues the request, reads the byte stream, decodes
34 +discrete events, and dispatches each to the appropriate state setter. Because state updates are
35 +event-driven, the interface renders the agent's behavior \emph{as it happens}---text appears
36 +token by token, tool calls populate a progress indicator, reasoning expands in a collapsible
37 +panel, and figures materialize as the Python layer emits them. This streaming design is central
38 +to the user experience and is discussed further in Section~\ref{sec:evaluation}.
39 +
40 +\subsection{The back end}
41 +\label{subsec:backend}
42 +
43 +The server is organized into route modules (authentication, administration, analytics,
44 +market-data proxying, report management, and the chat stream) and a set of isolated services
45 +that encapsulate business logic. The most important service mediates all communication with the
46 +LLM: it assembles the system prompt and tool catalogue, enforces the token budget, opens the
47 +streaming connection, parses the provider's event stream, dispatches tool calls, and relays
48 +results back to the client. Document generation, web research, and the quantitative-method
49 +wrappers are each implemented as separate services, so that the orchestration logic remains
50 +decoupled from the mechanics of any single capability. All request bodies are validated against
51 +schemas at the boundary, eliminating untyped inputs and yielding uniform error handling.
52 +
53 +\subsection{The data layer and external integrations}
54 +\label{subsec:data}
55 +
56 +VQuant is grounded in live data; it stores essentially no market data itself. Its primary
57 +financial source is a commercial market-data provider exposing more than 265 endpoints, wrapped
58 +by roughly 230 typed functions on the server and mirrored by a Python client used inside the
59 +sandbox. These endpoints cover company fundamentals (income statements, balance sheets, cash
60 +flows, key metrics and ratios), market data (real-time and historical quotes, intraday series,
61 +market movers), technical indicators (RSI, MACD, moving averages, ADX, stochastics, and
62 +others), analyst data (estimates, price targets, upgrades and downgrades, rating histories),
63 +insider and institutional activity (insider transactions, 13F filings, congressional and
64 +senate trading), macroeconomic series (treasury rates, economic indicators, the economic
65 +calendar, COT reports), foreign exchange and commodities, SEC filings and earnings-call
66 +transcripts, corporate events (earnings, dividends, splits, IPOs), and ESG and alternative-data
67 +signals. Table~\ref{tab:tools} in Section~\ref{sec:methodology} summarizes the resulting tool
68 +taxonomy.
69 +
70 +Beyond structured financial data, VQuant integrates four complementary web-research services---a
71 +web-scraping and extraction service, an AI search service, a neural semantic-search service, and
72 +a general search-engine API---so that the agent can incorporate qualitative and breaking
73 +information that no structured endpoint captures. The persistence layer stores users (with
74 +optional encrypted custom API keys), conversation sessions (including token accounting and cost
75 +estimates), shared reports addressable by a unique public identifier, daily-usage counters, and
76 +analytics events. This schema supports the platform's authentication, rate-limiting,
77 +report-sharing, and observability features, which we revisit in Section~\ref{sec:evaluation}.
78 +
79 +\subsection{Model layer}
80 +\label{subsec:models}
81 +
82 +VQuant is model-agnostic within the Claude family and exposes a user-facing selector
83 +(Table~\ref{tab:models}). The default is a reasoning-augmented model with a very large context
84 +window; users may instead select higher-capability or lower-latency alternatives to trade off
85 +quality, speed, and cost per query. The orchestration service detects which models support
86 +adaptive extended thinking and enables it only for those, so that the same code path serves the
87 +full model range. This abstraction is what allows the methodology of the next section to be
88 +stated independently of any particular model.
89 +
90 +\input{tables/models}
added paper/sections/introduction.tex +84 −0
@@ -0,0 +1,84 @@
1 +% ============================================================================
2 +\section{Introduction}
3 +\label{sec:introduction}
4 +% ============================================================================
5 +
6 +The rapid maturation of large language models (LLMs) has transformed expectations about
7 +what conversational software can accomplish in finance. Models such as the Claude, GPT, and
8 +Gemini families now produce fluent commentary on earnings, valuations, and macroeconomic
9 +conditions, and a growing literature documents their ability to extract signal from financial
10 +text \citep{lopezlira2023chatgpt,kim2024financial,wu2023bloomberggpt}. Yet fluency is not the
11 +same as rigor. A model that \emph{describes} a value-at-risk calculation in prose has not
12 +\emph{computed} one; a model that \emph{recalls} a stale price from pre-training has not
13 +\emph{retrieved} the current quote; and a model that narrates a Monte Carlo experiment has
14 +not run the simulation whose numbers a portfolio manager would act upon. The central
15 +engineering problem in applied financial AI is therefore not generation but
16 +\emph{grounding}: how to bind a probabilistic text generator to live data, deterministic
17 +computation, and reproducible artifacts without sacrificing the conversational interface that
18 +makes the technology accessible.
19 +
20 +This paper documents the methodology and innovations of \textbf{VQuant}, a production-grade
21 +web platform built to address precisely this problem. VQuant accepts a natural-language
22 +request---``analyze NVDA's fundamentals, technicals, and run a Monte Carlo simulation,'' for
23 +example---and returns a complete, multi-section quantitative report containing live data,
24 +computed figures, and downloadable documents. The platform is implemented as a full-stack
25 +TypeScript monorepo: a React front end, a modular Express back end, and an isolated Python
26 +scientific-computing layer. At its core, the system orchestrates a reasoning-augmented LLM
27 +through an \emph{agentic loop} that exposes more than two hundred financial and analytical
28 +tools to the model, executes the model's tool calls deterministically, streams the results
29 +back in real time, and synthesizes a final report that can be exported in five document
30 +formats.
31 +
32 +The motivation for studying this system is fourfold. \emph{First}, VQuant operationalizes a
33 +design philosophy that we believe is the correct one for high-stakes numerical domains: the
34 +LLM is a \emph{planner and synthesizer}, never a calculator. Every number in a VQuant report
35 +originates from a deterministic source---a market-data API, a closed-form pricing formula, or
36 +auditable Python code---so that the analysis is reproducible and the model's well-known
37 +propensity for numerical hallucination is structurally contained. \emph{Second}, the platform
38 +confronts the practical constraints of agentic systems---bounded context windows, tool-call
39 +latency, rate limits, and cost---with concrete algorithmic solutions whose logic generalizes
40 +beyond finance. \emph{Third}, VQuant integrates an unusually broad tool ecosystem (over 265
41 +market-data endpoints, four web-research services, and a seventeen-library Python sandbox)
42 +under a single function-calling protocol, providing a useful case study in tool taxonomy and
43 +prompt-level routing. \emph{Fourth}, the system closes the loop from query to deliverable by
44 +generating publication-ready PDF, Word, \LaTeX{} Beamer, and spreadsheet outputs from a single
45 +internal representation, illustrating a reusable pattern for automated report generation.
46 +
47 +Our contributions are methodological and architectural rather than empirical. We make four
48 +specific contributions. \textbf{(1)~Agentic orchestration with constrained tool use.} We
49 +describe a streaming tool-calling loop (Section~\ref{sec:methodology}) in which a strategically
50 +engineered system prompt routes requests to an appropriate subset of more than two hundred
51 +tools, batches tool execution to respect external rate limits, and surfaces the model's
52 +intermediate reasoning to the user in real time. \textbf{(2)~Context management under a token
53 +budget.} We formalize an adaptive-summarization algorithm that preserves coherence across
54 +effectively unbounded conversation histories by compressing older turns once a token threshold
55 +is crossed, while retaining the most recent exchanges verbatim. \textbf{(3)~A single-call
56 +computation paradigm.} We argue that consolidating data acquisition, numerical estimation, and
57 +visualization into one sandboxed Python execution---rather than the sequential
58 +fetch-then-analyze pattern typical of naive agents---materially reduces end-to-end latency, and
59 +we describe the sandbox and its safety properties (Section~\ref{sec:capabilities}). \textbf{(4)~A
60 +unified multi-format document pipeline.} We detail how a single Markdown artifact is
61 +transformed into PDF (headless-browser rendering with mathematical typesetting), DOCX (document
62 +converter), Beamer slides (model-structured \LaTeX{} compiled to PDF), and spreadsheets with
63 +live formulas.
64 +
65 +Our emphasis throughout is on \emph{mechanism}. We describe each component as it is actually
66 +built---the byte-level streaming protocol, the recursion that drives the loop, the throttle that
67 +batches tool calls, the two-stage machinery that keeps the context within budget, the correction
68 +that keeps token accounting honest, and the inter-process boundary that executes model-authored
69 +code---so that the design is reproducible rather than merely sketched. The classical quantitative
70 +methods the platform automates (option pricing, volatility modeling, simulation, and risk
71 +metrics) are standard and not the contribution of this paper; we record them compactly in an
72 +appendix and otherwise keep the focus on the architecture.
73 +
74 +The remainder of the paper is organized as follows.
75 +Section~\ref{sec:literature} situates VQuant within the literatures on LLM agents, tool use,
76 +retrieval augmentation, and AI in finance.
77 +Section~\ref{sec:architecture} presents the system architecture, data layer, and external
78 +integrations.
79 +Section~\ref{sec:methodology} develops the agentic orchestration methodology, including the
80 +tool taxonomy, context-management algorithm, and single-call execution paradigm.
81 +Section~\ref{sec:capabilities} formalizes the embedded quantitative methods and the
82 +document-generation pipeline.
83 +Section~\ref{sec:evaluation} discusses performance, reliability, security, and limitations.
84 +Section~\ref{sec:conclusion} concludes and outlines directions for evaluation and extension.
added paper/sections/literature.tex +80 −0
@@ -0,0 +1,80 @@
1 +% ============================================================================
2 +\section{Related Work}
3 +\label{sec:literature}
4 +% ============================================================================
5 +
6 +VQuant sits at the intersection of four research strands: (i)~large language models and
7 +reasoning, (ii)~tool-augmented and agentic systems, (iii)~retrieval augmentation and grounding,
8 +and (iv)~the application of LLMs to finance. We review each in turn and position our
9 +contribution accordingly.
10 +
11 +\subsection{Language models and reasoning}
12 +\label{subsec:lit_lms}
13 +
14 +The transformer architecture of \citet{vaswani2017attention} and the demonstration of
15 +in-context, few-shot learning at scale by \citet{brown2020language} established the modern
16 +paradigm of general-purpose language models. A complementary line of work showed that
17 +intermediate ``chain-of-thought'' reasoning improves performance on multi-step problems
18 +\citep{wei2022chain}, motivating a generation of models that allocate explicit computation to
19 +deliberation before answering. VQuant builds directly on this development: it targets
20 +reasoning-augmented models that can ``think'' under an adaptive token budget prior to
21 +responding, and it surfaces this intermediate reasoning to the user. We treat the foundation
22 +model as a fixed, externally provided capability \citep{bommasani2021opportunities} and study
23 +the \emph{system} that must be engineered around it.
24 +
25 +\subsection{Tool use and agentic systems}
26 +\label{subsec:lit_agents}
27 +
28 +A model confined to its parametric memory cannot retrieve live prices or perform exact
29 +arithmetic. The tool-use literature addresses this by teaching models to call external
30 +functions. \citet{schick2023toolformer} showed that models can learn to invoke APIs, while the
31 +ReAct framework of \citet{yao2023react} interleaved reasoning traces with actions in an
32 +observe--think--act loop that has become the template for modern agents. Program-aided
33 +approaches \citep{gao2023pal} delegate computation to a code interpreter, offloading exact
34 +arithmetic from the language model to a deterministic runtime---a principle that VQuant adopts
35 +as a first-class design constraint. Industrial function-calling protocols
36 +\citep{anthropic2024tooluse} standardized the schema-driven invocation of tools, and the Model
37 +Context Protocol generalized tool exposure across providers. VQuant operationalizes these ideas
38 +at scale: rather than a handful of tools, it exposes a curated catalogue of more than two
39 +hundred, and it contributes practical mechanisms---prompt-level routing, execution batching,
40 +and a single-call computation paradigm---for managing the resulting orchestration complexity.
41 +
42 +\subsection{Retrieval augmentation and grounding}
43 +\label{subsec:lit_rag}
44 +
45 +Retrieval-augmented generation \citep{lewis2020retrieval} grounds model outputs in external
46 +documents, mitigating hallucination and staleness. VQuant generalizes grounding beyond text
47 +retrieval: its ``retrieval'' surface includes structured market-data endpoints, semantic and
48 +keyword web search, and on-demand numerical computation. Every quantitative claim in a VQuant
49 +report is traceable to a deterministic source, which we view as the financial-domain analogue
50 +of citation-grounded generation. This emphasis on auditability connects to broader concerns
51 +about reliability and provenance in machine learning for finance \citep{lopezdeprado2018advances}.
52 +
53 +\subsection{Large language models in finance}
54 +\label{subsec:lit_finance}
55 +
56 +Domain-adapted models such as BloombergGPT \citep{wu2023bloomberggpt} and open frameworks such
57 +as FinGPT \citep{yang2023fingpt} demonstrated the value of finance-specific training data.
58 +On the application side, \citet{lopezlira2023chatgpt} found that LLM-derived sentiment from
59 +news headlines predicts subsequent returns, and \citet{kim2024financial} showed that LLMs can
60 +analyze financial statements at a level competitive with human analysts. These studies largely
61 +treat the LLM as a \emph{forecasting or classification} engine operating on text. VQuant takes
62 +a different stance: it uses the LLM as an \emph{orchestrator} that assembles live data,
63 +delegates numerical work to deterministic code, and composes the results into a report. The
64 +classical quantitative methods it automates---option pricing \citep{black1973pricing,
65 +merton1973theory}, conditional-volatility modeling \citep{engle1982autoregressive,
66 +bollerslev1986generalized}, Monte Carlo valuation \citep{glasserman2004monte}, and
67 +Value-at-Risk \citep{jorion2007value}---are well established; the contribution is the
68 +\emph{architecture} that makes them accessible through natural language while preserving
69 +reproducibility.
70 +
71 +\subsection{Positioning}
72 +\label{subsec:lit_positioning}
73 +
74 +Relative to prior work, VQuant is distinctive in three respects. First, it integrates an
75 +unusually broad and heterogeneous tool ecosystem under one protocol, and it contributes
76 +concrete methodology for routing and rate-managing that ecosystem. Second, it enforces a strict
77 +separation between reasoning (performed by the LLM) and computation (performed by deterministic
78 +code), which we argue is the appropriate design for numerically sensitive domains. Third, it
79 +treats the \emph{deliverable}---a citable, exportable, reproducible document---as a primary
80 +artifact rather than an afterthought. The remainder of the paper develops each of these points.
added paper/sections/methodology.tex +239 −0
@@ -0,0 +1,239 @@
1 +% ============================================================================
2 +\section{Methodology: Orchestration Mechanisms}
3 +\label{sec:methodology}
4 +% ============================================================================
5 +
6 +This section is the technical core of the paper. We describe, mechanism by mechanism, how
7 +VQuant drives a language model through a complete analysis: the streaming transport and its
8 +event protocol, the recursive tool-calling loop, the batching policy, the context-management
9 +machinery, and the token-accounting correction. Each mechanism is described as it is actually
10 +implemented, so that the design can be reproduced. Throughout, the guiding principle is a strict
11 +division of labor: the model \emph{plans and synthesizes}, while deterministic server code
12 +\emph{transports, schedules, computes, and accounts}.
13 +
14 +\subsection{The streaming transport and event protocol}
15 +\label{subsec:transport}
16 +
17 +VQuant does not use a model-provider SDK. It opens a raw HTTP connection to the provider's
18 +messages endpoint with a streaming response type, and parses the resulting Server-Sent Event
19 +(SSE) byte stream itself. This choice gives the server full control over how partial output is
20 +interpreted and re-emitted.
21 +
22 +The parser maintains a single growing string buffer. On each network chunk it appends the bytes,
23 +splits the buffer on newlines, and \emph{retains the final, possibly incomplete, line} in the
24 +buffer for the next chunk---a detail that is essential for correctness, because SSE frames do not
25 +align with TCP segment boundaries. Each complete line beginning with the \texttt{data:} prefix is
26 +stripped and parsed as JSON into a typed event. The parser dispatches on the event's
27 +\texttt{type} field; the eight relevant cases are summarized in Table~\ref{tab:events} and the
28 +overall flow is shown in Figure~\ref{fig:streaming}.
29 +
30 +\input{figures/streaming}
31 +
32 +\input{tables/events}
33 +
34 +Three behaviors of this dispatcher deserve emphasis. First, the model's output travels on
35 +\emph{two independent channels}: ordinary answer text arrives as \texttt{text\_delta} events and
36 +is accumulated into the answer while being forwarded to the client, whereas the model's private
37 +reasoning arrives as \texttt{thinking\_delta} events on a separate callback that the client
38 +renders in a distinct panel. Second, a tool call is not delivered atomically: the tool's name
39 +and identifier arrive in a \texttt{content\_block\_start}, but its arguments stream in as a
40 +sequence of \texttt{input\_json\_delta} fragments that the parser concatenates into a partial
41 +JSON string; only at \texttt{content\_block\_stop} is that string parsed into the structured
42 +argument object. The loop must therefore wait for the block to close before a tool becomes
43 +executable. Third, every forwarded event is flushed to the client immediately, so that the
44 +user perceives output token by token rather than in batches.
45 +
46 +\subsection{The recursive tool-calling loop}
47 +\label{subsec:loop}
48 +
49 +The agentic loop is implemented as \emph{recursion} rather than iteration. A single routine
50 +issues one streaming model call, and when that call resolves it either terminates---if the model
51 +requested no tools---or executes the requested tools, appends their results to the conversation,
52 +and \emph{calls itself again}. Algorithm~\ref{alg:loop} states the procedure and
53 +Figure~\ref{fig:loop} depicts it.
54 +
55 +\input{figures/loop}
56 +
57 +\begin{algorithm}[htbp]
58 +\caption{Recursive tool-calling loop (\textsc{ProcessResponse})}
59 +\label{alg:loop}
60 +\begin{algorithmic}[1]
61 +\Require message list $M$ (mutated in place), model $m$, tool catalogue $\mathcal{T}$
62 +\State $(\textit{text}, R, \textit{usage}) \gets \textsc{StreamModel}(m, M, \mathcal{T})$
63 + \Comment{Section~\ref{subsec:transport}}
64 +\State accumulate \textit{usage}; stream \textit{text} and thinking to the client
65 +\If{$R = \varnothing$} \Comment{no tool calls $\Rightarrow$ final answer}
66 + \State \Return
67 +\EndIf
68 +\State append $\langle\text{assistant}: \text{tool\_use blocks of } R\rangle$ to $M$
69 +\ForAll{batch $B$ in $\textsc{Chunk}(R, 5)$} \Comment{Section~\ref{subsec:batching}}
70 + \ForAll{tool call $r \in B$}
71 + \State $\textit{res} \gets \textsc{Execute}(r)$; stream a typed result event to the client
72 + \State collect $\textit{res}$ as a tool\_result block
73 + \EndFor
74 + \State \textsc{Wait}(500\,\text{ms})
75 +\EndFor
76 +\State append $\langle\text{user}: \text{all tool\_result blocks}\rangle$ to $M$
77 +\State \textsc{ProcessResponse}($M, m, \mathcal{T}$) \Comment{recurse with augmented context}
78 +\end{algorithmic}
79 +\end{algorithm}
80 +
81 +The conversation is represented as a list of messages that is mutated as the loop proceeds. When
82 +the model requests tools, the server first appends an \emph{assistant} message containing the
83 +model's tool-use blocks, then---after execution---appends a \emph{user} message whose content is
84 +the corresponding array of tool-result blocks, each keyed to its call identifier. This
85 +strict pairing of tool-use and tool-result blocks is what the provider's protocol requires, and
86 +maintaining it correctly across the recursion is the loop's central invariant. Recursion
87 +terminates naturally when a model call returns no tool requests, at which point the accumulated
88 +text is the report. Multimodal inputs are handled at the entry point: an uploaded image is
89 +attached to the first user message as a base64 block alongside the text query.
90 +
91 +\subsection{Batched tool execution}
92 +\label{subsec:batching}
93 +
94 +Within a single turn the model frequently requests many tools at once---a comprehensive report
95 +may trigger a dozen or more. Executing all of them simultaneously would risk provider rate
96 +limits and connection timeouts. VQuant therefore partitions the requested calls into
97 +\emph{batches of at most five} and executes the batches \emph{sequentially}, inserting a
98 +500-millisecond pause between consecutive batches. Results from all batches are accumulated and
99 +returned to the model together in the single tool-result message of Algorithm~\ref{alg:loop}, so
100 +that the model sees a complete result set on the next turn rather than a fragmented one. The
101 +batch boundary thus serves purely as a rate-limiting throttle; it does not change what the model
102 +observes. When more than one batch is required the server emits a progress event naming the
103 +tools in flight, so the throttling is visible to the user rather than appearing as a stall.
104 +
105 +\subsection{System-prompt routing}
106 +\label{subsec:routing}
107 +
108 +The behavior of the loop is shaped by a system prompt that is assembled fresh on every call.
109 +Two parts are computed at request time: the current date and time (in both a human-readable and
110 +an ISO form) are injected at the top so that relative date expressions resolve against live data
111 +rather than the model's training cutoff; the remainder is a static policy block. That policy
112 +instructs the model to detect and match the user's language; to act without procedural narration
113 +and, in particular, to perform an entire custom analysis in a single execution
114 +(Section~\ref{subsec:onecall}); to calibrate effort to request complexity---one or two tools for
115 +a simple lookup, a handful for a moderate request, ten or more for a comprehensive report; and to
116 +follow output-formatting conventions for downloadable artifacts. A final guardrail directs the
117 +model to refuse attempts to extract the platform's own implementation. This prompt-level routing
118 +is the mechanism by which a catalogue of more than two hundred tools (Table~\ref{tab:tools}) is
119 +navigated without an explicit planner: the model is taught \emph{when not to call} tools as much
120 +as when to call them.
121 +
122 +\input{tables/tools}
123 +
124 +\subsection{Adaptive reasoning}
125 +\label{subsec:thinking}
126 +
127 +For models that support it, the orchestration service enables \emph{adaptive extended thinking}
128 +by attaching a thinking directive to the request and asking for a summarized display. A small
129 +capability list determines which models receive this directive, so the same code path serves the
130 +full model range. As noted in Section~\ref{subsec:transport}, the resulting reasoning summary
131 +arrives on its own delta channel and is streamed to a dedicated client panel. Surfacing
132 +reasoning makes the agent's plan legible to the user and provides an audit trail of how a report
133 +was assembled, at no change to the loop itself.
134 +
135 +\subsection{Context management under a token budget}
136 +\label{subsec:context}
137 +
138 +A persistent challenge for conversational agents is the bounded context window: accumulated
139 +history---especially verbose tool results---eventually exceeds what the model can attend to.
140 +VQuant addresses this with a two-stage mechanism applied before every model call.
141 +
142 +\paragraph{Result truncation.} First, the server walks every message and caps any individual
143 +tool-result block at a fixed character budget (5{,}000 characters), appending a truncation
144 +marker. Raw data payloads are frequently far larger than the analysis requires, and this step
145 +removes that bloat before it is ever re-sent on a subsequent turn.
146 +
147 +\paragraph{Adaptive summarization.} Second, the server estimates the total token count of the
148 +prepared messages. The estimate uses a deliberately cheap heuristic---approximately one token per
149 +four characters, summed over text and tool-result blocks---because it is only a trigger, not an
150 +accounting figure. If the estimate exceeds a conservative threshold (set at $10^{5}$ tokens, well
151 +below the hard context limit to leave room for the response and new tool results), the server
152 +retains the most recent five messages verbatim and replaces the older history with a
153 +model-generated summary, reinserted as a single synthetic user message. Algorithm~\ref{alg:context}
154 +states the procedure and Figure~\ref{fig:context} illustrates the transformation.
155 +
156 +\input{figures/context}
157 +
158 +\begin{algorithm}[htbp]
159 +\caption{Context management via truncation and adaptive summarization}
160 +\label{alg:context}
161 +\begin{algorithmic}[1]
162 +\Require message list $M$, model $m$, threshold $\tau = 10^{5}$, recency $k = 5$, cap $c = 5000$ chars
163 +\State cap every tool-result block in $M$ at $c$ characters
164 +\State $t \gets \textsc{EstimateTokens}(M)$ \Comment{cheap $\approx$ chars$/4$ heuristic}
165 +\If{$t > \tau$}
166 + \State $M_{\text{recent}} \gets$ last $k$ messages of $M$;\quad $M_{\text{old}} \gets$ the rest
167 + \If{$M_{\text{old}} \neq \varnothing$}
168 + \State $T \gets \textsc{ExtractText}(M_{\text{old}})$ \Comment{drop tool-use blocks; keep last 10k chars}
169 + \State $s \gets \textsc{Summarize}(T, m)$ \Comment{separate non-streaming call}
170 + \State $M \gets [\,\langle\text{user: ``[summary]: ''}+s\rangle\,] \mathbin{\Vert} M_{\text{recent}}$
171 + \EndIf
172 +\EndIf
173 +\State \Return $M$
174 +\end{algorithmic}
175 +\end{algorithm}
176 +
177 +The summary is produced by a dedicated, \emph{non-streaming} model call with its own system
178 +prompt, a low temperature, and a tight output cap, instructed to preserve the analytically
179 +relevant context---the instruments under discussion, prior conclusions, and user preferences.
180 +Before summarizing, a helper extracts only the natural-language turns (discarding tool-use
181 +blocks) and keeps at most the last ten thousand characters, bounding the cost of summarization
182 +itself. Should the summarization call fail, the mechanism degrades gracefully to a truncated
183 +literal excerpt rather than aborting the request. The net effect is that conversation length is,
184 +for practical purposes, unbounded, at the cost of one additional model call whenever the
185 +threshold is crossed.
186 +
187 +\subsection{Token accounting and its correction}
188 +\label{subsec:accounting}
189 +
190 +Accurate token accounting matters both for the budget trigger above and for per-session cost
191 +reporting, yet the streaming protocol does not reliably report output-token counts. VQuant
192 +therefore applies a correction mechanism. Input tokens are read from the provider's
193 +\texttt{message\_start} event; output tokens are taken from streaming usage updates \emph{but
194 +reconciled} against a local count obtained by running the accumulated answer text through a
195 +tokenizer at the end of the stream. The system records the \emph{maximum} of the provider's
196 +figure and the local count, guaranteeing that cost is never understated, and falls back to the
197 +provider's figure only if local encoding fails. Cost is then computed from a simple linear
198 +schedule (a fixed price per million input tokens and a higher price per million output tokens)
199 +and accumulated across all calls in a session, including the recursive tool-driven turns and any
200 +summarization calls. This separation---a cheap heuristic for the budget trigger, an exact
201 +tokenizer for billing---keeps the hot path inexpensive while keeping the ledger accurate.
202 +
203 +\subsection{The single-call computation paradigm}
204 +\label{subsec:onecall}
205 +
206 +The final orchestration mechanism concerns \emph{how} numerical work is delegated. A naive agent
207 +decomposes a quantitative task into a sequence of tool calls---fetch data, then in a separate
208 +turn analyze it, then in a third turn plot it---each of which incurs a full recursion through
209 +Algorithm~\ref{alg:loop} and therefore a full model round trip. VQuant instead instructs the
210 +model, through the system prompt, to perform an entire analysis in a \emph{single} execution of
211 +the Python tool: acquire data inside the sandbox, compute, and render all figures in one call
212 +(Listing~\ref{lst:onecall}).
213 +
214 +\begin{lstlisting}[language=Python,caption={Single-call execution: data acquisition,
215 +computation, and visualization are consolidated into one sandboxed run, collapsing what would
216 +otherwise be three recursive model round trips into one.},label={lst:onecall}]
217 +# One tool call performs the whole analysis:
218 +data = fmp.get_historical_prices("NVDA") # live fetch inside the sandbox
219 +df = pd.DataFrame(data["historical"]).sort_values("date")
220 +df["ret"] = df["close"].pct_change()
221 +
222 +plt.figure(figsize=(12, 6)) # figure 1: price path
223 +plt.plot(pd.to_datetime(df["date"]), df["close"]); plt.tight_layout()
224 +
225 +plt.figure(figsize=(12, 6)) # figure 2: return distribution
226 +plt.hist(df["ret"].dropna(), bins=50); plt.tight_layout()
227 +
228 +save_excel(df, "nvda.xlsx") # spreadsheet export in the same run
229 +\end{lstlisting}
230 +
231 +Three rules, enforced through the prompt, make this paradigm effective. First, the model must
232 +\emph{never} hard-code data arrays: inlining hundreds of values both bloats the generated tokens
233 +(which must be streamed and accounted) and defeats reproducibility; data must be fetched
234 +programmatically through the in-process client. Second, each visualization must be a separate
235 +figure rather than a subplot grid, which yields cleanly captionable, individually referenceable
236 +images. Third, all artifacts---figures and spreadsheets---are produced within the same execution.
237 +By collapsing the recursion depth for an analytical task from three or more to one, this paradigm
238 +removes the dominant source of latency in the loop. The substrate that executes this code is the
239 +subject of the next section.
added paper/sections/results.tex +112 −0
@@ -0,0 +1,112 @@
1 +% ============================================================================
2 +\section{Execution Substrate and Document Generation}
3 +\label{sec:capabilities}
4 +% ============================================================================
5 +
6 +Having described how the agent is orchestrated, we now detail the two subsystems that turn its
7 +plans into artifacts: the sandboxed Python substrate that executes arbitrary model-authored code,
8 +and the pipeline that renders the resulting report into multiple document formats. Both are
9 +described at the mechanism level.
10 +
11 +\subsection{The Python execution sandbox}
12 +\label{subsec:sandbox}
13 +
14 +When the model invokes the custom-analysis tool, the server does not evaluate the code in
15 +process. It spawns a separate Python interpreter (resolved to a project virtual environment) as
16 +a child process and communicates with it over standard streams, an isolation boundary that
17 +protects the server from faults in the executed code and bounds its blast radius
18 +(Figure~\ref{fig:sandbox}).
19 +
20 +\input{figures/sandbox}
21 +
22 +\paragraph{Inter-process protocol.} The server serializes a single JSON object---the
23 +model-authored code, an optional context dictionary, and the market-data credential---and writes
24 +it to the child's standard input, then closes the stream. The child reads the entire input,
25 +executes, and writes exactly one JSON object to standard output: a success flag, captured
26 +textual output, a list of base64-encoded figures, a list of generated files, and any error. The
27 +child is launched with output buffering disabled so that nothing is lost, and with a hard
28 +90-second wall-clock timeout. The parent collects standard output and standard error separately;
29 +a non-zero exit code, or error output with no standard output, is treated as failure and the
30 +error is surfaced to the model so that it can revise its code on the next turn. This single
31 +request / single response discipline keeps the boundary simple and makes failures explicit.
32 +
33 +\paragraph{Namespace construction.} Inside the child, execution is performed by building an
34 +\emph{execution namespace}---a dictionary---and calling the interpreter's \texttt{exec} against
35 +it. Into this namespace the runtime injects the scientific libraries (NumPy, pandas, matplotlib,
36 +and the broader set of seventeen), the two artifact helpers (\texttt{save\_excel},
37 +\texttt{save\_word}), and a market-data client constructed from the supplied credential; any
38 +context variables passed by the model are merged in last, so that the model can parameterize a
39 +reusable script without string interpolation. Matplotlib is configured for a non-interactive
40 +backend before any plotting occurs, so that figure rendering requires no display. As a
41 +convenience, if the executed code defines a callable named \texttt{main}, the runtime invokes it
42 +after execution and captures its return value.
43 +
44 +\paragraph{Output and figure capture.} Standard output and standard error produced by the code
45 +are redirected into in-memory string buffers for the duration of execution, so that the model's
46 +\texttt{print} statements become the textual result rather than corrupting the JSON protocol.
47 +Figures are captured \emph{after} execution by a deterministic sweep: the runtime enumerates all
48 +live matplotlib figure numbers, and for each, renders the figure to an in-memory buffer as a
49 +PNG at fixed resolution with tight bounding boxes, then base64-encodes the bytes. This is exactly
50 +why the single-call paradigm of Section~\ref{subsec:onecall} asks the model to emit each chart as
51 +a \emph{separate} figure: the capture sweep turns each one into an individually addressable image
52 +that the report can caption and reference. The encoded figures travel back through the JSON
53 +response, are written to a served directory by the server, and are streamed to the client as
54 +figure events.
55 +
56 +\subsection{Embedded numerical tools}
57 +\label{subsec:numerical}
58 +
59 +Alongside the open-ended sandbox, the platform exposes a small set of pre-built numerical tools
60 +for common tasks, so that routine requests need not regenerate code: a Monte Carlo path simulator
61 +under a standard log-normal price model, a closed-form European option pricer that returns prices
62 +together with the full set of risk sensitivities, a GARCH(1,1) conditional-volatility estimator,
63 +and a Value-at-Risk calculator offering historical, parametric, and simulation-based variants
64 +with companion risk ratios. These tools are conventional in quantitative finance and we do not
65 +elaborate their formulae here; what matters for the architecture is that they share the sandbox's
66 +contract---deterministic computation over live data, returning structured results and figures
67 +through the same channels---so the model can mix them freely with custom code inside a single
68 +analysis. Their detailed inputs and outputs are summarized in Appendix~\ref{app:numerical}.
69 +
70 +\subsection{The document-generation pipeline}
71 +\label{subsec:docs}
72 +
73 +VQuant treats the deliverable as a first-class artifact. From a single Markdown report---the text
74 +the agent streams to the user, with embedded figure references---the platform produces several
75 +output formats, each through a distinct mechanism (Figure~\ref{fig:docpipeline}).
76 +
77 +\input{figures/docpipeline}
78 +
79 +\paragraph{PDF via headless rendering.} The challenge in rendering Markdown that contains
80 +mathematics is that a Markdown parser will mangle mathematical syntax. The pipeline solves this
81 +with a \emph{protect--parse--restore} mechanism: before parsing, every block- and inline-math
82 +span is extracted and replaced by a unique placeholder token; the now math-free Markdown is
83 +parsed to HTML; the placeholders are then restored as spans destined for a client-side math
84 +renderer. The assembled HTML is loaded into a headless browser, which executes the math renderer;
85 +the server explicitly \emph{waits for the rendered output to appear} in the DOM before capturing
86 +the page to PDF with page furniture (headers, footers, pagination). Rendering in a real browser
87 +engine is what lets complex notation and styled tables reproduce faithfully.
88 +
89 +\paragraph{Slides via model restructuring and two-pass \LaTeX.} Presentation output is a
90 +two-phase mechanism. First, the platform issues a \emph{second} model call whose sole task is to
91 +restructure the report into slide content---one idea per slide, special characters escaped, key
92 +quantities emphasized---returning only body \LaTeX{}, not a full document. The server then wraps
93 +that body in a fixed, branded Beamer preamble and compiles it with two sequential passes of the
94 +\LaTeX{} engine, the second pass being required for cross-references and the table of contents to
95 +resolve. When the analysis produced figures, the server additionally synthesizes one slide per
96 +figure, integrating the visual output into the deck without further model involvement.
97 +
98 +\paragraph{Word via document conversion.} For an editable office format, the same Markdown is
99 +handed to a document converter that emits a word-processor file, preserving tables, lists, and
100 +heading structure.
101 +
102 +\paragraph{Spreadsheets with live formulas.} Within the sandbox, the spreadsheet helper writes
103 +multi-sheet workbooks containing \emph{live} formulas---sums, ratios, conditional formats, data
104 +bars---rather than pre-computed constants, so the recipient can audit and modify the calculations.
105 +This mirrors, at the spreadsheet level, the platform's broader commitment to auditable output:
106 +the deliverable carries its own derivation.
107 +
108 +\paragraph{Sharing and persistence.} Finally, any report can be published to a stable, unique URL;
109 +the server stores the report content and its figure references and serves them through a public
110 +viewer, so an analysis can be revisited or cited without re-running the computation. Sessions,
111 +token ledgers, and cost estimates are persisted per user, supporting both continuity and the
112 +operational analytics discussed next.
added paper/sections/robustness.tex +87 −0
@@ -0,0 +1,87 @@
1 +% ============================================================================
2 +\section{Performance, Reliability, and Security}
3 +\label{sec:evaluation}
4 +% ============================================================================
5 +
6 +This section discusses the engineering properties that make VQuant usable in production:
7 +its performance characteristics, cost discipline, reliability and security measures, and the
8 +limitations that bound the contribution. We frame these as the practical counterparts to the
9 +methodology of Section~\ref{sec:methodology}.
10 +
11 +\subsection{Performance and the streaming experience}
12 +\label{subsec:performance}
13 +
14 +The dominant cost in an agentic system is not raw computation but \emph{round trips}: every
15 +model invocation and every external request adds latency. VQuant's design attacks this on three
16 +fronts (Table~\ref{tab:robustness}). The single-call paradigm of Section~\ref{subsec:onecall}
17 +collapses what would be three or more model round trips---fetch, analyze, plot---into one,
18 +which is the platform's largest latency saving for analytically intensive queries. Execution
19 +batching overlaps independent tool calls within a turn while bounding instantaneous provider
20 +load. And end-to-end streaming decouples \emph{perceived} latency from \emph{total} latency: the
21 +user sees reasoning, text, tool progress, and figures appear incrementally, so a report that
22 +takes tens of seconds to complete begins responding within a second. This last property is why
23 +the streaming architecture of Section~\ref{subsec:frontend} is a performance feature and not
24 +merely a cosmetic one.
25 +
26 +\input{tables/robustness}
27 +
28 +\subsection{Cost discipline}
29 +\label{subsec:cost}
30 +
31 +Because model usage is metered by token, cost control is a first-order concern. VQuant estimates
32 +token counts locally with a tokenizer before each call, which both drives the
33 +context-management trigger of Algorithm~\ref{alg:context} and yields accurate per-session
34 +accounting. The adaptive-summarization mechanism directly limits cost growth in long sessions by
35 +preventing the unbounded accumulation of history, and truncating oversized tool results removes
36 +payload bloat that would otherwise be re-sent on every turn. The user-facing model selector
37 +(Table~\ref{tab:models}) lets users match model capability to query difficulty, routing simple
38 +lookups to a fast, inexpensive tier and reserving the flagship model for the hardest analyses.
39 +
40 +\subsection{Authentication, limits, and bring-your-own-keys}
41 +\label{subsec:auth}
42 +
43 +VQuant supports both local accounts and third-party single sign-on, with sessions persisted in
44 +the same store used in either deployment environment. Usage is governed by daily limits that
45 +differ for anonymous and authenticated users, enforced through per-user counters in the data
46 +layer. A notable feature is \emph{bring-your-own-keys}: a user may supply personal API
47 +credentials for the model provider, the market-data provider, and the web-research services;
48 +when present, these are used in place of the platform defaults and exempt the user from the
49 +daily cap. This design cleanly separates the platform's orchestration value from the cost of the
50 +underlying APIs, and it lets power users operate at their own expense and rate limits.
51 +
52 +\subsection{Reliability and security}
53 +\label{subsec:security}
54 +
55 +Several measures harden the system. All request bodies are validated against schemas at the
56 +boundary, so malformed or untyped input is rejected uniformly before reaching business logic.
57 +Database access is mediated by an object-relational mapper that parameterizes queries,
58 +mitigating injection. The front end escapes rendered content and parses Markdown through a safe
59 +pipeline, limiting cross-site scripting. Secrets are injected at runtime rather than committed,
60 +and the bring-your-own-keys path keeps user credentials out of shared configuration. At the
61 +model layer, the system prompt includes a guardrail that responds to attempts to extract the
62 +platform's own implementation with a refusal rather than disclosure, providing a measure of
63 +protection for the orchestration logic itself. Finally, the platform records analytics
64 +events---active users, query rates, tool-usage frequency, model selection, and
65 +document-generation breakdowns---giving operators the observability needed to detect anomalies
66 +and capacity-plan.
67 +
68 +\subsection{Limitations and threats to validity}
69 +\label{subsec:limitations}
70 +
71 +We close with an honest accounting of what this paper does and does not establish. First, the
72 +contribution is \emph{architectural and methodological}; we do not provide a controlled
73 +empirical evaluation of report quality, latency, or cost against baseline agents, and the
74 +operational figures in Table~\ref{tab:robustness} are indicative rather than benchmarked.
75 +Second, the platform inherits the limitations of its dependencies: the accuracy of any report is
76 +bounded by the correctness and timeliness of the upstream market-data provider, and the model's
77 +synthesis can still contain interpretive errors even when every number is computed
78 +deterministically. The strict separation of reasoning from computation contains numerical
79 +hallucination but does not eliminate the risk of a flawed \emph{narrative} around correct
80 +numbers. Third, the quantitative methods rest on classical modeling assumptions---log-normal
81 +prices, constant parameters over the estimation window, normally distributed returns in the
82 +parametric VaR---that may be violated in practice; the platform exposes these methods as tools
83 +and does not, by itself, certify their appropriateness for a given asset. Fourth, the
84 +single-call paradigm trades some robustness for speed: a single failed execution forfeits an
85 +entire analysis, whereas a decomposed agent can recover at a finer granularity. We regard the
86 +design as the right default for interactive use but note the trade-off. These limitations
87 +delineate a clear agenda for evaluation, which we sketch in the conclusion.
added paper/sections/titlepage.tex +77 −0
@@ -0,0 +1,77 @@
1 +% ============================================================================
2 +% Title Page
3 +% ============================================================================
4 +\thispagestyle{empty}
5 +
6 +\begin{center}
7 +
8 +% --- Logo ---
9 +\includegraphics[width=3.5cm]{uq_logo.jpg}
10 +
11 +\vspace{0.6cm}
12 +
13 +{\footnotesize\textsc{Université du Québec en Outaouais}}\\[0.15cm]
14 +{\footnotesize\textsc{Département des sciences administratives}}
15 +
16 +\vspace{0.8cm}
17 +
18 +{\footnotesize\textsc{Working Paper No.~\WPnumber}}
19 +
20 +\vspace{1.2cm}
21 +
22 +% --- Title ---
23 +{\LARGE\bfseries \WPtitle\par}
24 +
25 +\ifx\WPsubtitle\empty\else
26 + \vspace{0.3cm}
27 + {\large\itshape \WPsubtitle\par}
28 +\fi
29 +
30 +\vspace{1.2cm}
31 +
32 +% --- Author ---
33 +{\large \WPauthor}\\[0.3cm]
34 +{\normalsize \WPaffiliation}\\[0.15cm]
35 +{\normalsize \href{mailto:\WPemail}{\WPemail}}\\[0.15cm]
36 +{\small \WPaddress}
37 +
38 +\vspace{0.8cm}
39 +
40 +% --- Date & Version ---
41 +{\normalsize \WPdate}\\[0.1cm]
42 +{\small Version~\WPversion}
43 +
44 +\end{center}
45 +
46 +\vfill
47 +
48 +\newpage
49 +
50 +% ============================================================================
51 +% Abstract Page
52 +% ============================================================================
53 +\thispagestyle{empty}
54 +
55 +\vspace*{1cm}
56 +
57 +\noindent\rule{\textwidth}{0.4pt}
58 +\vspace{0.3cm}
59 +
60 +\noindent\textbf{Abstract}
61 +
62 +\vspace{0.15cm}
63 +
64 +\noindent\WPabstract
65 +
66 +\vspace{0.4cm}
67 +
68 +\noindent\textbf{Keywords:} \WPkeywords
69 +
70 +\vspace{0.15cm}
71 +
72 +\noindent\textbf{JEL Classification:} \WPjel
73 +
74 +\vspace{0.3cm}
75 +\noindent\rule{\textwidth}{0.4pt}
76 +
77 +\newpage
added paper/tables/events.tex +31 −0
@@ -0,0 +1,31 @@
1 +\begin{table}[htbp]
2 +\centering
3 +\caption{The streaming event protocol. The server parses the provider's Server-Sent Event stream
4 +and dispatches on each event's type; it then re-emits its own typed events to the client. This is
5 +the mechanism by which reasoning, text, tool calls, and computed artifacts are surfaced
6 +incrementally.}
7 +\label{tab:events}
8 +\begin{threeparttable}
9 +\begin{tabular}{@{}lll@{}}
10 +\toprule
11 +Provider event & Sub-type & Server action \\
12 +\midrule
13 +\texttt{message\_start} & --- & read input/output token usage \\
14 +\texttt{message\_delta} & --- & update running output-token count \\
15 +\texttt{content\_block\_start}& \texttt{tool\_use} & open a new tool call (name, id) \\
16 +\texttt{content\_block\_delta}& \texttt{text\_delta} & append to answer; forward to client \\
17 +\texttt{content\_block\_delta}& \texttt{thinking\_delta} & forward reasoning on a separate channel \\
18 +\texttt{content\_block\_delta}& \texttt{input\_json\_delta} & concatenate partial tool-argument JSON \\
19 +\texttt{content\_block\_stop} & --- & parse accumulated JSON into tool arguments \\
20 +\texttt{message\_stop} & --- & reconcile tokens; resolve the call \\
21 +\bottomrule
22 +\end{tabular}
23 +\begin{tablenotes}[flushleft]
24 +\footnotesize
25 +\item \textit{Notes.} The client (Section~\ref{subsec:frontend}) performs the symmetric
26 +operation: it reads the server's stream, splits on newlines retaining the trailing partial line,
27 +and dispatches the server's own event types (text, thinking, tools, tool results, sources,
28 +figures, specialized results, done) to dedicated renderers.
29 +\end{tablenotes}
30 +\end{threeparttable}
31 +\end{table}
added paper/tables/models.tex +27 −0
@@ -0,0 +1,27 @@
1 +\begin{table}[htbp]
2 +\centering
3 +\caption{User-selectable model tier. The orchestration service enables adaptive extended
4 +thinking only for models that support it, and applies a uniform per-response generation cap.
5 +The default is a reasoning-augmented model with a very large context window; alternatives let
6 +users trade off capability, latency, and cost per query.}
7 +\label{tab:models}
8 +\begin{threeparttable}
9 +\begin{tabular}{@{}llcc@{}}
10 +\toprule
11 +Role in platform & Model family & Adaptive thinking & Typical use \\
12 +\midrule
13 +Default & Reasoning-augmented (1M ctx) & Yes & Comprehensive reports \\
14 +High capability & Flagship reasoning & Yes & Hardest analyses \\
15 +Balanced & Mid-tier reasoning & Yes & Moderate queries \\
16 +Low latency & Fast tier & No & Simple lookups \\
17 +\bottomrule
18 +\end{tabular}
19 +\begin{tablenotes}[flushleft]
20 +\footnotesize
21 +\item \textit{Notes.} Per-response generation is capped at 64{,}000 tokens. Adaptive thinking
22 +lets the model allocate a variable budget of private reasoning before responding; its summary is
23 +streamed to the client and shown in a collapsible panel. Context-window sizes and per-token
24 +prices are determined by the model provider and abstracted away from the orchestration logic.
25 +\end{tablenotes}
26 +\end{threeparttable}
27 +\end{table}
added paper/tables/robustness.tex +30 −0
@@ -0,0 +1,30 @@
1 +\begin{table}[htbp]
2 +\centering
3 +\caption{Operational characteristics of the platform. Latencies are indicative order-of-magnitude
4 +figures for the corresponding subsystems rather than benchmarked measurements; they motivate the
5 +streaming and single-call design choices discussed in the text.}
6 +\label{tab:robustness}
7 +\begin{threeparttable}
8 +\begin{tabular}{@{}lll@{}}
9 +\toprule
10 +Dimension & Mechanism & Indicative characteristic \\
11 +\midrule
12 +First-token latency & SSE streaming & sub-second perceived response \\
13 +Tool concurrency & batched execution & $\leq 5$ tools / batch, 500\,ms spacing \\
14 +Context window & adaptive summarization & effectively unbounded history \\
15 +Generation cap & per-response limit & 64{,}000 tokens \\
16 +Python analysis & sandboxed subprocess & seconds per execution \\
17 +PDF rendering & headless browser & several seconds \\
18 +Slide compilation & two-pass \LaTeX{} & roughly ten seconds \\
19 +Cost control & local token estimation & per-session accounting \\
20 +Rate-limit safety & inter-batch delay & bounded provider load \\
21 +\bottomrule
22 +\end{tabular}
23 +\begin{tablenotes}[flushleft]
24 +\footnotesize
25 +\item \textit{Notes.} Figures characterize the subsystems qualitatively to explain design
26 +trade-offs; a controlled performance evaluation is left to future work
27 +(Section~\ref{sec:conclusion}).
28 +\end{tablenotes}
29 +\end{threeparttable}
30 +\end{table}
added paper/tables/tools.tex +36 −0
@@ -0,0 +1,36 @@
1 +\begin{table}[htbp]
2 +\centering
3 +\caption{Taxonomy of the tool catalogue exposed to the model. VQuant defines more than two
4 +hundred tools through a schema-driven function-calling protocol. Counts are approximate and
5 +group conceptually related endpoints; the financial families are backed by a market-data
6 +provider exposing over 265 endpoints, wrapped by roughly 230 typed server functions.}
7 +\label{tab:tools}
8 +\begin{threeparttable}
9 +\begin{tabular}{@{}lll@{}}
10 +\toprule
11 +Family & Count & Representative tools \\
12 +\midrule
13 +Company fundamentals & 40+ & profile, income statement, balance sheet, cash flow, ratios \\
14 +Market data & 30+ & quote, historical / intraday prices, market movers, batch quote \\
15 +Technical analysis & 8+ & RSI, MACD, EMA/SMA, ADX, CCI, stochastic, Williams \%R \\
16 +Analyst and ratings & 20+ & estimates, price targets, upgrades/downgrades, rating history \\
17 +Insider and institutional & 15+ & insider trades, 13F filings, congressional/senate trading \\
18 +Economic and macro & 15+ & treasury rates, indicators, calendar, COT reports \\
19 +Forex and crypto & 15+ & FX and crypto quotes, lists, historical series, commodities \\
20 +SEC and compliance & 25+ & filings by form type, company notes, call transcripts \\
21 +Events and calendars & 10+ & earnings, dividends, splits, IPO calendar and disclosures \\
22 +ESG and alternative & 20+ & ESG scores, social sentiment, headcount, executive pay \\
23 +Options & 4 & option chain, prices, Greeks, volatility surface \\
24 +Advanced analysis & 7 & Monte Carlo, Black--Scholes, custom Python, bulk download \\
25 +Web research & 6 & scrape, crawl, extract; AI / semantic / engine search \\
26 +\bottomrule
27 +\end{tabular}
28 +\begin{tablenotes}[flushleft]
29 +\footnotesize
30 +\item \textit{Notes.} The system prompt instructs the model to select tools according to query
31 +complexity (Section~\ref{subsec:routing}); the most powerful entries---Monte Carlo simulation,
32 +option pricing, and arbitrary Python execution---are described in detail in
33 +Section~\ref{sec:capabilities}.
34 +\end{tablenotes}
35 +\end{threeparttable}
36 +\end{table}
added paper/uq_logo.jpg +0 −0

Binary file not shown.