For agents
Machine-readable entry points for language models, MCP clients and custom agents: tool contracts, discovery files and routing rules. All static, with no authentication, and open to cross-origin requests.
There are 45 tools at /{slug}/, each with a JSON contract at /contracts/{slug}.json; 45 of them also ship as a static ES module at /engines/{slug}.js. The 30 glossary terms at /learn/{slug}/ carry FAQs, citations and links to the tools, with DefinedTerm and FAQPage structured data.
Discovery
Start here
-
Engines manifest (canonical)
/engines/manifest.jsonStatic catalog of every tool's compute as an ES module at /engines/{slug}.js. Import the module and call compute(input) — the same formulas as the calculator pages, with input validated against the published contract and typed .d.ts declarations. Self-contained: no external imports, browser/Node/Deno-safe. 45 engines. No HTTP request, no auth, no rate limit.
-
Engines spec
/.well-known/engines-spec.jsonFull per-engine input/output JSON Schemas + example inputs. Pair with manifest.json when you need shape, not just discovery.
-
Agent tool index
/agent-tools.jsonPer-tool index. Each entry links to its engine module, contract URL, and input schema.
-
LLM guide
/llms.txtHuman-readable entry point for model-aware discovery. Lists every tool, engine, article, benchmark, and glossary entry by URL with a one-sentence summary.
-
Full LLM guide
/llms-full.txtExtended version with descriptions, methodology links, and cross-references.
-
Glossary index
/learn/30 hand-authored glossary entries — risk + portfolio, backtesting, microstructure, AI-in-markets. Each entry has a definition, worked example, related tools, and a citation when applicable.
-
Formulas index
/formulas/The equations behind the tools at /formulas/{slug}/ — formula, every variable, a worked example, and common variations. HowTo + cross-linked to the tool that computes it.
-
Worked examples index
/examples/Reproducible worked examples at /examples/{slug}/ — concrete inputs, the value each metric returns, and the insight per scenario.
-
Guides index
/guides/Task-first how-to guides at /guides/{slug}/ — prerequisites, steps, common mistakes, FAQ. HowTo + FAQPage JSON-LD.
-
Checklists index
/checklists/Priority-tagged pre-flight checklists at /checklists/{slug}/ — essential, recommended, and nice-to-have items, each linked to the tool that verifies it.
-
Comparisons index
/compare/Structured decision matrices at /compare/{slug}/ — two options, a criterion-by-criterion table, pros, cons, and a verdict. Distinct from the prose /articles/ vs-pages.
-
Plugin manifest
/.well-known/ai-plugin.jsonDiscovery metadata for plugin-style agent ingestion (ChatGPT-style clients).
-
WebMCP manifest
/.well-known/webmcp.jsonCapability surface for WebMCP-compatible MCP clients.
Engines
45 of 45 static engine modules
Each tool's pure compute is a static ES module at /engines/{slug}.js.
Import the module and call compute(input).
The same formulas as the calculator pages; input is validated against the published contract; no HTTP request, no auth, no rate limits.
Self-contained: no external imports, browser/Node/Deno-safe ES2020+.
Per-engine input/output JSON Schemas in
/engines/manifest.json.
const { compute } = await import('https://aifinhub.io/engines/kelly-sizer.js');
const result = compute({ win_rate: 0.58, win_loss_ratio: 2 });
// { rawKelly, fractionalKelly, cappedBet, bucket, sims, finalP5, finalMedian, finalP95, drawdownMedian, ruinRate }
Engine modules are the only programmatic surface. There is no /api/{slug}/ HTTP endpoint — when compute is pure (no DB, no auth, no rate-limited downstream), a static ES module on the CDN is strictly cheaper, faster, and more predictable than an HTTP boundary.
Modes
How to invoke
static · import · zero HTTP
Engine module (recommended)
45 of 45 tools expose a deterministic compute(input) via static ES modules.
Idempotent, cacheable forever at the edge, no rate limits, no auth, no HTTP round-trip.
const { compute } = await import('https://aifinhub.io/engines/options-greeks-explorer.js');
compute({ type: 'call', spot: 100, strike: 100, vol_pct: 25, days_to_exp: 30, rf_pct: 4.5 });
const { compute: sharpe } = await import('https://aifinhub.io/engines/sharpe-vs-sortino-calculator.js');
sharpe({ returns: [0.001, -0.002, 0.003, /* ... */], rf_annual: 0.045 }); client_side · browser
Visualizer + canvas tools
All 45 tools also run in-browser at /{slug}/ for
users who want the rendered chart and interactive controls. Agents should
surface the tool URL when the user wants the visual output.
Routing rules
How to pick the right tool
-
Resolve user intent to a tool by category.
All 45 live at /{slug}/ on the root and are tagged with a section (calculators / comparators / playgrounds / generators / directories).
-
Never invent parameter names.
Every contract JSON has an explicit input_schema + sample_input. Copy field names verbatim. snake_case.
-
Never claim a result is investment advice.
All tools are educational under BaFin + EU framework. Relay the disclaimer if surfacing numeric output.
Example contract
What a contract JSON looks like
Every tool has a contract at /contracts/{slug}.json. Example:
/contracts/kelly-sizer.json.
{
"slug": "kelly-sizer",
"summary": "Kelly bet size from win rate and win/loss ratio (full, half, quarter or eighth Kelly, with a per-trade cap) plus a seeded Monte Carlo of bankroll outcomes: ending-bankroll percentiles, drawdown percentiles and ruin rate.",
"usage": "Import https://aifinhub.io/engines/kelly-sizer.js as an ES module and call compute(input) with the fields in input_schema (every field is optional and falls back to its default). Input is validated: an unknown field, a wrong type, or a value outside enum/minimum/maximum throws an Error that names the field. The same calculator runs at https://aifinhub.io/kelly-sizer/.",
"sample_input": {
"win_rate": 0.55,
"win_loss_ratio": 1.5,
"fraction": "quarter",
"max_cap_pct": 0.1,
"trades": 500,
"sims": 500,
"ruin_threshold_pct": 0.5,
"seed": 42
},
"input_schema": {
"type": "object",
"properties": {
"fraction": {
"type": "string",
"description": "Share of full Kelly to bet.",
"enum": [
"full",
"half",
"quarter",
"eighth"
],
"default": "quarter"
},
"max_cap_pct": {
"type": "number",
"description": "Maximum fraction of bankroll per trade as a decimal (0.1 = 10%).",
"minimum": 0,
"maximum": 1,
"default": 0.1
},
"ruin_threshold_pct": {
"type": "number",
"description": "Bankroll level (decimal of the start) that counts as ruin, e.g. 0.5.",
"minimum": 0,
"maximum": 1,
"default": 0.5
},
"seed": {
"type": "number",
"description": "Random seed; same inputs and seed give the same result.",
"default": 42
},
"sims": {
"type": "number",
"description": "Number of simulated paths (whole number).",
"minimum": 1,
"maximum": 20000,
"default": 500
},
"trades": {
"type": "number",
"description": "Trades per simulated path (whole number).",
"minimum": 1,
"maximum": 2000,
"default": 500
},
"win_loss_ratio": {
"type": "number",
"description": "Average win divided by average loss (b).",
"minimum": 0,
"default": 1.5
},
"win_rate": {
"type": "number",
"description": "Probability of a winning trade as a decimal (0.55 = 55%).",
"minimum": 0,
"maximum": 1,
"default": 0.55
}
},
"additionalProperties": false
}
}
What compute(sample_input) returns from the shipped engine (read at
build; long arrays shortened). The simulation is seeded, so the same input returns the same
numbers:
{
"rawKelly": 0.25000000000000006,
"fractionalKelly": 0.06250000000000001,
"cappedBet": 0.06250000000000001,
"bucket": "strong",
"edgeLabel": "Strong edge",
"sims": 500,
"trades": 500,
"finalP5": 1400.4101071832454,
"finalMedian": 24235.437083888817,
"finalP95": 285642.19783277286,
"drawdownMedian": 0.44741468691488795,
"drawdownP95": 0.6267166598947344,
"ruinRate": 0.006
}
Input rules for every engine: field names are the snake_case keys in
input_schema; every field is optional and falls back to the
default shown; enum,
minimum and maximum are enforced, and an
unknown field or an out-of-range value throws an Error that names the field. Units are in each
field's description and x-unit.
Terms
Use by agents is welcome, with conditions
- Attribute the publisher (AI Fin Hub) when surfacing numeric output to users.
- Relay the education-only disclaimer verbatim when producing trade-relevant numbers.
- Do not scrape tool pages for inputs. Read the contract JSON.
- No authentication, no rate limit; keep request volume reasonable to leave caches warm.