Architecture
The modules, what each one owns, and how they compose.
Four modules, each with one responsibility and no dependency on anything above it. All are plain JavaScript with no build step and no runtime dependencies, imported unchanged by the browser, the test suite and the simulations.
site/options.js pricing, Greeks, surface, implied vol solver └─ no imports site/perp.js indices, funding, scenario margin, collateral └─ imports options.js site/underwrite.js counterparty risk priced off a track record └─ no imports lib/ claims, commitments, resolution, scoring └─ no imports
One file, two runtimes
The pricing and risk modules live under site/ rather than lib/ so
that the browser can import them directly. The test suite and the simulations import the same
files. There is no second implementation to keep in sync, and therefore no possibility of the
browser and the server disagreeing about a price.
A venue whose front end and risk engine compute margin differently will eventually show a trader a number it does not honour. Sharing the module removes the failure mode rather than testing for it.
Generated figures
sim/emit.js runs the engine and writes site/data/*.json plus an ES
module for pages that need to work without a server. Pages render from that output only, so a
change in the engine is a change on the site.