SPB Git

spb/spboucher.ai Public

spboucher.ai — personal website of Simon-Pierre Boucher.

TypeScript 93.4% HTML 5.5% CSS 1%

Research: UQO working paper series (WP2–WP9) · Teaching: ULaval GSF course slides · Apps: 7 new projects

- Research: new UQO Working Paper Series section — WP2, WP3, WP5, WP7, WP9
  with descriptions; private-repo PDFs served locally from /papers/,
  WP3 linked to its public GitHub repo
- Teaching: ULaval course material cards (GSF3100, GSF6053 W2022,
  GSF6053 H25) — all slides, lecture notes, proofs, Stata labs,
  exercises & solutions linked as PDFs
- Apps: CoinExplorer, LLM Index, OS Vault (DMG), Forge Studio (DMG),
  AIR, Ultra-Sharp Agent Skills, Neural Networks Book + app icons

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 5 days ago (Aug 6, 2026) parent e4e885c

Showing 9 changed files with +473 and −1

modified app/research/page.tsx +104 −1
@@ -24,6 +24,55 @@ export const metadata: Metadata = {
24 24 "Publications, working papers, and conference presentations by Simon-Pierre Boucher — financial econometrics, commodity markets, monetary policy, and high-frequency finance.",
25 25 };
26 26
27 +const uqoWorkingPapers = [
28 + {
29 + num: "UQO Working Paper No. 2",
30 + pages: "53 pages",
31 + title:
32 + "Decoding Real Estate Descriptions: Semantic Embeddings and Hedonic Pricing of Residential Properties in Quebec",
33 + description:
34 + "Adds sentence-transformer embeddings of listing descriptions to hedonic models of 17,087 Quebec houses — lifting adjusted R² from 0.452 to 0.511 beyond structural attributes alone.",
35 + pdf: "/papers/wp2_uqo.pdf",
36 + },
37 + {
38 + num: "UQO Working Paper No. 3",
39 + pages: "60 pages",
40 + title:
41 + "Hedonic Housing Price Models for the United States: A Multi-Method Comparison of Parametric, Quantile, and Machine Learning Approaches",
42 + description:
43 + "OLS, quantile regression, and gradient-boosting (XGBoost + SHAP) approaches compared on 788,842 Zillow listings covering all 50 states and DC.",
44 + pdf: "https://github.com/spboucher-ai/wp3-hedonic-housing-us/blob/main/paper/main.pdf",
45 + repo: "https://github.com/spboucher-ai/wp3-hedonic-housing-us",
46 + },
47 + {
48 + num: "UQO Working Paper No. 5",
49 + pages: "51 pages",
50 + title:
51 + "Airbnb, Residential Rents, and Housing Market Pressure: A Hedonic and Spatial Econometric Analysis",
52 + description:
53 + "Hedonic, spatial, quantile, and machine-learning evidence from 8,303 Quebec rental listings and 3,456 Airbnb listings — each active Airbnb within 500 m is associated with roughly 0.4% higher asking rent.",
54 + pdf: "/papers/wp5_uqo.pdf",
55 + },
56 + {
57 + num: "UQO Working Paper No. 7",
58 + pages: "29 pages",
59 + title:
60 + "The Options-Implied Information Content for Cross-Asset Return and Volatility Prediction: Evidence from 3.8 Billion Option Contracts",
61 + description:
62 + "Options-implied moments forecast returns and volatility on a panel of 264,383 ticker-days (69 tickers, 2010–2025); a kurtosis long/short strategy delivers a Sharpe ratio of 2.33.",
63 + pdf: "/papers/wp7_uqo.pdf",
64 + },
65 + {
66 + num: "UQO Working Paper No. 9",
67 + pages: "26 pages",
68 + title:
69 + "A Grand Hedonic Model of the Canadian Housing Market: Decomposing the Value of Structure and Location",
70 + description:
71 + "140,931 MLS listings with 1,153 neighbourhood (FSA) fixed effects — location alone adds ~30 points of R² (46% → 77%), valuing held-out homes with a 15.8% median absolute error (OOS R² = 0.764).",
72 + pdf: "/papers/wp9_uqo.pdf",
73 + },
74 +];
75 +
27 76 const workingPapers = [
28 77 {
29 78 title:
@@ -193,11 +242,65 @@ export default function ResearchPage() {
193 242 </div>
194 243 </section>
195 244
245 + {/* UQO working paper series */}
246 + <section className="mt-12">
247 + <Reveal>
248 + <h2 className="text-xl font-semibold tracking-tight">
249 + UQO Working Paper Series
250 + </h2>
251 + <p className="mt-2 max-w-3xl text-sm text-muted-foreground">
252 + Applied econometrics research produced at the Département des
253 + sciences administratives, UQO — hedonic pricing, housing markets,
254 + and derivatives. Each paper is backed by a fully reproducible
255 + pipeline.
256 + </p>
257 + </Reveal>
258 + <div className="mt-4 space-y-4">
259 + {uqoWorkingPapers.map((paper, i) => (
260 + <Reveal key={paper.num} delay={i * 0.08}>
261 + <Card>
262 + <CardHeader>
263 + <Badge variant="secondary" className="w-fit">
264 + {paper.num} · {paper.pages}
265 + </Badge>
266 + <CardTitle className="text-lg leading-snug">
267 + {paper.title}
268 + </CardTitle>
269 + <CardDescription>{paper.description}</CardDescription>
270 + </CardHeader>
271 + <CardContent className="flex flex-wrap gap-4">
272 + <a
273 + href={paper.pdf}
274 + target="_blank"
275 + rel="noopener noreferrer"
276 + className="inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline"
277 + >
278 + <FileText className="h-4 w-4" aria-hidden="true" />
279 + Paper PDF
280 + </a>
281 + {paper.repo && (
282 + <a
283 + href={paper.repo}
284 + target="_blank"
285 + rel="noopener noreferrer"
286 + className="inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline"
287 + >
288 + <Github className="h-4 w-4" aria-hidden="true" />
289 + Code &amp; data repository
290 + </a>
291 + )}
292 + </CardContent>
293 + </Card>
294 + </Reveal>
295 + ))}
296 + </div>
297 + </section>
298 +
196 299 {/* Working papers */}
197 300 <section className="mt-12">
198 301 <Reveal>
199 302 <h2 className="text-xl font-semibold tracking-tight">
200 Working Papers
303 + Earlier Working Papers
201 304 </h2>
202 305 </Reveal>
203 306 <div className="mt-4 space-y-4">
modified app/teaching/page.tsx +293 −0
@@ -108,6 +108,211 @@ const uqoCourses: UqoCourse[] = [
108 108 },
109 109 ];
110 110
111 +const GH_RAW = "https://raw.githubusercontent.com/spboucher-ai";
112 +
113 +interface MaterialGroup {
114 + title: string;
115 + kind: "pills" | "list";
116 + links: { label: string; file: string; topic?: string }[];
117 +}
118 +
119 +interface UlavalCourse {
120 + code: string;
121 + title: string;
122 + term: string;
123 + repoName: string;
124 + description: string;
125 + groups: MaterialGroup[];
126 +}
127 +
128 +const ulavalCourses: UlavalCourse[] = [
129 + {
130 + code: "GSF-3100",
131 + title: "Capital Markets (Marché des capitaux)",
132 + term: "Undergraduate · F2021–W2023",
133 + repoName: "GSF3100",
134 + description:
135 + "Fixed income and capital markets — LaTeX Beamer slides for every section of the course.",
136 + groups: [
137 + {
138 + title: "Slides — 13 section decks (PDF)",
139 + kind: "pills",
140 + links: [
141 + { label: "01", file: "Section 1/GSF3100_S01.pdf" },
142 + { label: "02", file: "Section 2/GSF3100_S02.pdf" },
143 + { label: "03", file: "Section 3/GSF3100_S03.pdf" },
144 + { label: "04", file: "Section 4/GSF3100_S04.pdf" },
145 + { label: "05", file: "Section 5/GSF3100_S05.pdf" },
146 + { label: "06", file: "Section 6/GSF3100_S6.pdf" },
147 + { label: "07", file: "Section 7/GSF3100_S7.pdf" },
148 + { label: "08", file: "Section 8/GSF3100_S08.pdf" },
149 + { label: "9a", file: "Section 9/a/GSF3100_S09a.pdf" },
150 + { label: "9b", file: "Section 9/b/GSF3100_S09b.pdf" },
151 + { label: "9c", file: "Section 9/c/GSF3100_S09c.pdf" },
152 + { label: "10a", file: "Section 10/a/GSF3100_S10a.pdf" },
153 + { label: "10b", file: "Section 10/b/GSF3100_S10b.pdf" },
154 + ],
155 + },
156 + ],
157 + },
158 + {
159 + code: "GSF-6053",
160 + title: "Financial Econometrics I",
161 + term: "Graduate · W2022",
162 + repoName: "GSF6053",
163 + description:
164 + "OLS, MLE, hypothesis testing, and time-series econometrics — session slides plus Stata lab sessions.",
165 + groups: [
166 + {
167 + title: "Slides — sessions 2–12 (PDF)",
168 + kind: "pills",
169 + links: Array.from({ length: 11 }, (_, i) => {
170 + const n = i + 2;
171 + return {
172 + label: String(n).padStart(2, "0"),
173 + file: `Séance ${n}/GSF6053_S${n}.pdf`,
174 + };
175 + }),
176 + },
177 + {
178 + title: "Stata labs (PDF)",
179 + kind: "list",
180 + links: [
181 + { label: "Stata session 02", file: "STATA_S02/GSF6053_STATA_02.pdf" },
182 + { label: "Stata session 03", file: "STATA_S03/GSF6053_STATA_03.pdf" },
183 + ],
184 + },
185 + ],
186 + },
187 + {
188 + code: "GSF-6053",
189 + title: "Financial Econometrics I",
190 + term: "Graduate · W2025",
191 + repoName: "GSF6053_H25",
192 + description:
193 + "Full W2025 edition — lecture slides, typed lecture notes, formal proofs, and 14 exercise sets with complete solutions.",
194 + groups: [
195 + {
196 + title: "Lecture slides (PDF)",
197 + kind: "list",
198 + links: [
199 + {
200 + label: "S1 — Introduction",
201 + file: "PDF/GSF6053_H25_Séance1_Introduction.pdf",
202 + },
203 + {
204 + label: "S1 — Statistics review",
205 + file: "PDF/GSF6053_H25_Séance1_Révision.pdf",
206 + },
207 + { label: "S1 — OLS (MCO)", file: "PDF/GSF6053_H25_Séance1_MCO.pdf" },
208 + {
209 + label: "S2 — Maximum likelihood (MLE)",
210 + file: "PDF/GSF6053_H25_Séance2_MLE.pdf",
211 + },
212 + {
213 + label: "S3 — Hypothesis tests & ANOVA",
214 + file: "PDF/GS6053_H25_Séance3_Tests_ANOVA.pdf",
215 + },
216 + {
217 + label: "S4 — Extensions of the linear model",
218 + file: "PDF/GSF6053_H25_Séance4_Extensions_Modèle_Linéaire.pdf",
219 + },
220 + {
221 + label: "S5 — Heteroskedasticity",
222 + file: "PDF/GSF6053_H25_Séance5_Hétéroscédasticité.pdf",
223 + },
224 + {
225 + label: "S6 — Autocorrelation",
226 + file: "PDF/GSF6053_H25_Séance6_Autocorrélation.pdf",
227 + },
228 + ],
229 + },
230 + {
231 + title: "Lecture notes (PDF)",
232 + kind: "list",
233 + links: [
234 + { label: "Introduction", file: "PDF/GSF6053_H25_NOTE_INTRO.pdf" },
235 + {
236 + label: "Prerequisites",
237 + file: "PDF/GSF6053_H25_NOTE_PRÉALABLE.pdf",
238 + },
239 + { label: "OLS (MCO)", file: "PDF/GSF6053_H25_NOTE_MCO.pdf" },
240 + { label: "MLE", file: "PDF/GSF6053_H25_NOTE_MLE.pdf" },
241 + {
242 + label: "Hypothesis testing",
243 + file: "PDF/GSF6053_H25_NOTE_Test_hypothèse.pdf",
244 + },
245 + { label: "ANOVA", file: "PDF/GSF6053_H25_NOTE_ANOVA.pdf" },
246 + { label: "GLS (MCG)", file: "PDF/GSF6053_H25_NOTE_MCG.pdf" },
247 + {
248 + label: "Heteroskedasticity",
249 + file: "PDF/GSF6053_H25_NOTE_HETEROSCEDASTICITE.pdf",
250 + },
251 + { label: "White test", file: "PDF/GSF6053_H25_NOTE_WHITE_TEST.pdf" },
252 + {
253 + label: "Breusch–Pagan test",
254 + file: "PDF/GSF6053_H25_Note_Breusch_Pagan.pdf",
255 + },
256 + {
257 + label: "Autocorrelation",
258 + file: "PDF/GSF6053_H25_NOTE_AUTOCORÉLATION.pdf",
259 + },
260 + ],
261 + },
262 + {
263 + title: "Formal proofs (PDF)",
264 + kind: "list",
265 + links: [
266 + {
267 + label: "OLS — summation form",
268 + file: "PDF/GSF6053_H25_preuve_MCO_sommation.pdf",
269 + },
270 + {
271 + label: "OLS — matrix form",
272 + file: "PDF/GSF6053_H25_preuve_MCO_matriciel.pdf",
273 + },
274 + { label: "GLS", file: "PDF/GSF6053_H25_preuve_MCG.pdf" },
275 + { label: "MLE", file: "PDF/GSF6053_H25_preuve_MLE.pdf" },
276 + {
277 + label: "Cramér–Rao bound",
278 + file: "PDF/GSF6053_H25_preuve_cramer_rao.pdf",
279 + },
280 + {
281 + label: "Cochrane–Orcutt",
282 + file: "PDF/GSF6053_H25_preuve_cochrane_orcutt.pdf",
283 + },
284 + {
285 + label: "Prais–Winsten",
286 + file: "PDF/GSF6053_H25_preuve_prais_winsten.pdf",
287 + },
288 + ],
289 + },
290 + {
291 + title: "Exercise sets 1–14 (PDF)",
292 + kind: "pills",
293 + links: Array.from({ length: 14 }, (_, i) => {
294 + const n = String(i + 1).padStart(3, "0");
295 + return {
296 + label: String(i + 1).padStart(2, "0"),
297 + file: `PDF/GSF6053_H25_EXO_${n}.pdf`,
298 + };
299 + }),
300 + },
301 + {
302 + title: "Solutions 1–14 (PDF)",
303 + kind: "pills",
304 + links: Array.from({ length: 14 }, (_, i) => {
305 + const n = String(i + 1).padStart(3, "0");
306 + return {
307 + label: String(i + 1).padStart(2, "0"),
308 + file: `PDF/GSF6053_H25_SOL_${n}.pdf`,
309 + };
310 + }),
311 + },
312 + ],
313 + },
314 +];
315 +
111 316 const courses = [
112 317 {
113 318 code: "GSF-3100",
@@ -333,6 +538,94 @@ export default function TeachingPage() {
333 538 </CardContent>
334 539 </Card>
335 540 </Reveal>
541 +
542 + <Reveal className="mt-8">
543 + <h3 className="text-lg font-semibold tracking-tight">
544 + Course Material — Université Laval
545 + </h3>
546 + <p className="mt-2 max-w-3xl text-sm text-muted-foreground">
547 + Complete material from courses previously taught at Université
548 + Laval — LaTeX Beamer slides, lecture notes, formal proofs, Stata
549 + labs, and exercise sets with solutions — openly available on
550 + GitHub.
551 + </p>
552 + </Reveal>
553 + <div className="mt-4 space-y-4">
554 + {ulavalCourses.map((course, i) => (
555 + <Reveal key={course.repoName} delay={i * 0.08}>
556 + <Card>
557 + <CardHeader>
558 + <div className="flex flex-wrap items-center gap-2">
559 + <Badge className="w-fit font-mono">{course.code}</Badge>
560 + <Badge variant="secondary" className="w-fit">
561 + {course.term}
562 + </Badge>
563 + </div>
564 + <CardTitle className="text-lg leading-snug">
565 + {course.title}
566 + </CardTitle>
567 + <CardDescription>{course.description}</CardDescription>
568 + </CardHeader>
569 + <CardContent className="flex flex-col gap-4">
570 + {course.groups.map((group) => (
571 + <div key={group.title}>
572 + <p className="inline-flex items-center gap-2 text-sm font-medium">
573 + <Presentation
574 + className="h-4 w-4 text-primary"
575 + aria-hidden="true"
576 + />
577 + {group.title}
578 + </p>
579 + {group.kind === "pills" ? (
580 + <div className="mt-2 flex flex-wrap gap-1.5">
581 + {group.links.map((link) => (
582 + <a
583 + key={link.file}
584 + href={encodeURI(
585 + `${GH_RAW}/${course.repoName}/main/${link.file}`,
586 + )}
587 + target="_blank"
588 + rel="noopener noreferrer"
589 + aria-label={`${course.code} — ${group.title} — ${link.label} (PDF)`}
590 + className="inline-flex h-8 min-w-9 items-center justify-center rounded-full border border-border/70 px-2 text-xs font-medium text-muted-foreground transition-colors hover:border-primary/40 hover:bg-accent hover:text-primary"
591 + >
592 + {link.label}
593 + </a>
594 + ))}
595 + </div>
596 + ) : (
597 + <div className="mt-2 flex flex-wrap gap-x-5 gap-y-1.5">
598 + {group.links.map((link) => (
599 + <a
600 + key={link.file}
601 + href={encodeURI(
602 + `${GH_RAW}/${course.repoName}/main/${link.file}`,
603 + )}
604 + target="_blank"
605 + rel="noopener noreferrer"
606 + className="text-sm text-primary hover:underline"
607 + >
608 + {link.label}
609 + </a>
610 + ))}
611 + </div>
612 + )}
613 + </div>
614 + ))}
615 + <a
616 + href={`https://github.com/spboucher-ai/${course.repoName}`}
617 + target="_blank"
618 + rel="noopener noreferrer"
619 + className="inline-flex items-center gap-2 text-sm font-medium text-primary hover:underline"
620 + >
621 + <Github className="h-4 w-4" aria-hidden="true" />
622 + Full course repository
623 + </a>
624 + </CardContent>
625 + </Card>
626 + </Reveal>
627 + ))}
628 + </div>
336 629 </section>
337 630
338 631 {/* Teaching assistant */}
modified lib/apps.ts +76 −0
@@ -55,6 +55,40 @@ export const openSourceProjects: OpenSourceProject[] = [
55 55 repo: "https://github.com/spboucher-ai/airiskindex",
56 56 demo: "https://www.airiskindex.io",
57 57 },
58 + {
59 + slug: "coinexplorer",
60 + name: "CoinExplorer",
61 + emoji: "🪙",
62 + tagline: "Self-hosted blockchain explorer",
63 + description:
64 + "Self-hosted blockchain explorer for stablecoins and major crypto — 24 chains, free public RPCs only, zero API keys. Track balances, transfers, and token supplies across EVM and non-EVM networks.",
65 + language: "Python",
66 + repo: "https://github.com/spboucher-ai/coinexplorer",
67 + demo: "https://www.coinexplorer.io",
68 + },
69 + {
70 + slug: "llmindex",
71 + name: "LLM Index",
72 + emoji: "🏆",
73 + tagline: "Live, contamination-resistant LLM ranking",
74 + description:
75 + "Discriminative, contamination-resistant, live LLM ranking — IRT 2PL and Bradley–Terry scoring across 12 domains, with full methodological transparency.",
76 + language: "TypeScript",
77 + repo: "https://github.com/spboucher-ai/llmindex",
78 + demo: "https://www.llmindex.io",
79 + },
80 + {
81 + slug: "os-vault",
82 + icon: "/icons/os-vault.png",
83 + dmg: "https://github.com/spboucher-ai/os-vault/releases/latest/download/OSVault-1.0.0.dmg",
84 + name: "OS Vault",
85 + emoji: "🔐",
86 + tagline: "Self-custody multi-chain crypto wallet",
87 + description:
88 + "Self-custody multi-chain crypto wallet for macOS — one phrase, six chain families (11 EVM chains, Bitcoin, Solana, Tron, XRPL, TON), zero API keys, and its own vault encryption.",
89 + language: "Swift",
90 + repo: "https://github.com/spboucher-ai/os-vault",
91 + },
58 92 {
59 93 slug: "metrika",
60 94 icon: "/icons/metrika.png",
@@ -77,6 +111,48 @@ export const openSourceProjects: OpenSourceProject[] = [
77 111 language: "C++",
78 112 repo: "https://github.com/spboucher-ai/forge",
79 113 },
114 + {
115 + slug: "forge-studio",
116 + icon: "/icons/forge-studio.png",
117 + dmg: "https://github.com/spboucher-ai/forge-studio/releases/latest/download/ForgeStudio-0.2.0.dmg",
118 + name: "Forge Studio",
119 + emoji: "🎛️",
120 + tagline: "macOS cockpit for Forge LLM training",
121 + description:
122 + "Native macOS cockpit for the Forge LLM training framework — SwiftUI dashboard with live loss charts, run supervision, dataset prep, checkpoints, and generation on Apple Silicon.",
123 + language: "Swift",
124 + repo: "https://github.com/spboucher-ai/forge-studio",
125 + },
126 + {
127 + slug: "air",
128 + name: "AIR",
129 + emoji: "🧾",
130 + tagline: "The language of accounting",
131 + description:
132 + "LLVM-style compiler infrastructure for accounting: LLMs emit economic events, a deterministic compiler produces balanced journal entries. Standalone hash-chained ledger, agent syscalls, and bank reconciliation.",
133 + language: "Python",
134 + repo: "https://github.com/spboucher-ai/air",
135 + },
136 + {
137 + slug: "ultra-sharp-agent-skills",
138 + name: "Ultra-Sharp Agent Skills",
139 + emoji: "⚡",
140 + tagline: "72 production-ready skills for AI agents",
141 + description:
142 + "Research-first skill-authoring system plus 72 production-ready SKILL.md skills for AI agents — documents, frontend, databases, backend, writing, and US/CA tax & accounting. Linted, trigger-tested, validated.",
143 + language: "Python",
144 + repo: "https://github.com/spboucher-ai/ultra-sharp-agent-skills",
145 + },
146 + {
147 + slug: "artificial-neural-networks-book",
148 + name: "Neural Networks Book",
149 + emoji: "📘",
150 + tagline: "ANN methods, equations & figures",
151 + description:
152 + "Artificial Neural Networks — Methods, Equations and Graphical Representations. A 119-page LaTeX book covering every architecture with rigorous equations, estimation algorithms, and native TikZ figures.",
153 + language: "LaTeX",
154 + repo: "https://github.com/spboucher-ai/artificial-neural-networks-book",
155 + },
80 156 {
81 157 slug: "zyquo-cloud-web",
82 158 icon: "/icons/zyquo-cloud-web.png",
added public/icons/forge-studio.png +0 −0

Binary file not shown.

added public/icons/os-vault.png +0 −0

Binary file not shown.

added public/papers/wp2_uqo.pdf +0 −0

Binary file not shown.

added public/papers/wp5_uqo.pdf +0 −0

Binary file not shown.

added public/papers/wp7_uqo.pdf +0 −0

Binary file not shown.

added public/papers/wp9_uqo.pdf +0 −0

Binary file not shown.