aggregate_api 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aggregate_api/__init__.py +41 -0
- aggregate_api/__main__.py +154 -0
- aggregate_api/app.py +206 -0
- aggregate_api/audit.py +395 -0
- aggregate_api/bounds.py +331 -0
- aggregate_api/cache.py +319 -0
- aggregate_api/capability.py +823 -0
- aggregate_api/completion.py +219 -0
- aggregate_api/config.py +363 -0
- aggregate_api/cors.py +61 -0
- aggregate_api/examples.py +620 -0
- aggregate_api/layer_pricing.py +840 -0
- aggregate_api/library.py +94 -0
- aggregate_api/library_notes.py +96 -0
- aggregate_api/models.py +1407 -0
- aggregate_api/net.py +281 -0
- aggregate_api/pnl.py +101 -0
- aggregate_api/pricing.py +778 -0
- aggregate_api/resources.py +257 -0
- aggregate_api/routes/__init__.py +8 -0
- aggregate_api/routes/decl.py +327 -0
- aggregate_api/routes/examples.py +82 -0
- aggregate_api/routes/meta.py +282 -0
- aggregate_api/routes/objects.py +4119 -0
- aggregate_api/routes/status.py +466 -0
- aggregate_api/serializers.py +565 -0
- aggregate_api/sessions.py +353 -0
- aggregate_api/static/aggregate-api-logo-512.png +0 -0
- aggregate_api/static/aggregate-api-logo.png +0 -0
- aggregate_api/static/aggregate-api-trim.png +0 -0
- aggregate_api/static/android-chrome-192x192.png +0 -0
- aggregate_api/static/android-chrome-512x512.png +0 -0
- aggregate_api/static/apple-touch-icon.png +0 -0
- aggregate_api/static/assets/bootstrap-icons-BeopsB42.woff +0 -0
- aggregate_api/static/assets/bootstrap-icons-mSm7cUeB.woff2 +0 -0
- aggregate_api/static/assets/bootstrap-ohb1VZ53.js +5 -0
- aggregate_api/static/assets/codemirror-h62DHGGa.js +14 -0
- aggregate_api/static/assets/csv-grid.worker-DKzHGXac.js +4 -0
- aggregate_api/static/assets/echarts-B7o9sc00.js +40 -0
- aggregate_api/static/assets/echarts-gl-DG1Uf6wE.js +4282 -0
- aggregate_api/static/assets/lite-CUlcD8p4.css +1 -0
- aggregate_api/static/assets/lite-Dd2TnT4M.js +1 -0
- aggregate_api/static/assets/main-Bxhxa55v.css +9 -0
- aggregate_api/static/assets/main-CmoEiPit.js +9 -0
- aggregate_api/static/assets/tables-BHCF7qIF.js +8 -0
- aggregate_api/static/assets/tables-CxvajLr7.css +1 -0
- aggregate_api/static/favicon-16x16.png +0 -0
- aggregate_api/static/favicon-32x32.png +0 -0
- aggregate_api/static/favicon.ico +0 -0
- aggregate_api/static/index.html +912 -0
- aggregate_api/static/lite.html +83 -0
- aggregate_api/static/logo.png +0 -0
- aggregate_api/static/site.webmanifest +14 -0
- aggregate_api/static/sw.js +78 -0
- aggregate_api/status.py +536 -0
- aggregate_api/status_page.html +546 -0
- aggregate_api/tables.py +316 -0
- aggregate_api-1.0.0.dist-info/METADATA +187 -0
- aggregate_api-1.0.0.dist-info/RECORD +63 -0
- aggregate_api-1.0.0.dist-info/WHEEL +5 -0
- aggregate_api-1.0.0.dist-info/entry_points.txt +2 -0
- aggregate_api-1.0.0.dist-info/licenses/LICENSE +28 -0
- aggregate_api-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,912 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<meta name="description" content="aggregate Loss Lab (aLL): build and explore compound probability distributions from a DecL program.">
|
|
7
|
+
<meta name="theme-color" content="#ffffff">
|
|
8
|
+
<title>aggregate Loss Lab</title>
|
|
9
|
+
|
|
10
|
+
<link rel="icon" type="image/x-icon" href="./favicon.ico">
|
|
11
|
+
<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png">
|
|
12
|
+
<link rel="icon" type="image/png" sizes="16x16" href="./favicon-16x16.png">
|
|
13
|
+
<link rel="apple-touch-icon" href="./apple-touch-icon.png">
|
|
14
|
+
<link rel="manifest" href="./site.webmanifest">
|
|
15
|
+
|
|
16
|
+
<!-- The phone branch, inline and before the module script so it runs
|
|
17
|
+
before any bundle is fetched. One URL: a narrow, coarse-pointer
|
|
18
|
+
device (a phone, not a narrow desktop window and not a touch-screen
|
|
19
|
+
laptop) is sent to the lite page; `?full=1` forces the full app and
|
|
20
|
+
`?lite=1` forces lite, for desktop testing. Relative target, matching
|
|
21
|
+
`base: './'`, so it survives a sub-path deploy. -->
|
|
22
|
+
<script>
|
|
23
|
+
(function () {
|
|
24
|
+
var q = new URLSearchParams(location.search);
|
|
25
|
+
if (q.has('full')) return;
|
|
26
|
+
if (q.has('lite')
|
|
27
|
+
|| matchMedia('(max-width: 640px) and (pointer: coarse)').matches) {
|
|
28
|
+
location.replace('./lite.html' + location.search + location.hash);
|
|
29
|
+
}
|
|
30
|
+
}());
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<!-- Bootstrap, Bootstrap Icons, and our overrides are imported via
|
|
34
|
+
the JS entry point (Vite bundles them through main.js). No CDN
|
|
35
|
+
dependency at runtime. -->
|
|
36
|
+
<script type="module" crossorigin src="./assets/main-CmoEiPit.js"></script>
|
|
37
|
+
<link rel="modulepreload" crossorigin href="./assets/echarts-B7o9sc00.js">
|
|
38
|
+
<link rel="modulepreload" crossorigin href="./assets/tables-BHCF7qIF.js">
|
|
39
|
+
<link rel="modulepreload" crossorigin href="./assets/bootstrap-ohb1VZ53.js">
|
|
40
|
+
<link rel="modulepreload" crossorigin href="./assets/codemirror-h62DHGGa.js">
|
|
41
|
+
<link rel="stylesheet" crossorigin href="./assets/tables-CxvajLr7.css">
|
|
42
|
+
<link rel="stylesheet" crossorigin href="./assets/main-Bxhxa55v.css">
|
|
43
|
+
</head>
|
|
44
|
+
<body>
|
|
45
|
+
|
|
46
|
+
<!-- ============================================================
|
|
47
|
+
Header
|
|
48
|
+
============================================================ -->
|
|
49
|
+
<header class="sticky-top bg-white border-bottom shadow-sm">
|
|
50
|
+
<nav class="navbar navbar-expand-lg py-1">
|
|
51
|
+
<div class="container-fluid px-3 px-md-4" style="max-width:1280px;">
|
|
52
|
+
<a href="/" class="d-flex align-items-center text-decoration-none me-auto">
|
|
53
|
+
<img src="./logo.png" alt="aggregate Loss Lab" style="height:40px;width:auto;">
|
|
54
|
+
<div class="d-flex flex-column px-3">
|
|
55
|
+
<div class="brand-title text-dark">aggregate Loss Lab</div>
|
|
56
|
+
<div class="brand-kicker">description to distribution</div>
|
|
57
|
+
</div>
|
|
58
|
+
</a>
|
|
59
|
+
<div class="nav-meta">
|
|
60
|
+
<!-- The perspective in force, beside the versions and there
|
|
61
|
+
for the same reason: it changes what every served table
|
|
62
|
+
says, it is set from a menu two clicks away, and until
|
|
63
|
+
a75 the only way to know which reading you were looking
|
|
64
|
+
at was to open that menu and look at the tick.
|
|
65
|
+
|
|
66
|
+
Both words are always shown, the active one lit, which
|
|
67
|
+
makes the pair a readout and a control at once: they
|
|
68
|
+
carry `data-perspective`, so the click wiring and the
|
|
69
|
+
active-state sync that already serve the menu items
|
|
70
|
+
pick them up with no second code path. Ctrl+Shift+V is
|
|
71
|
+
the third way in, and moves this too. -->
|
|
72
|
+
<span class="nav-perspective" id="nav-perspective">
|
|
73
|
+
<button type="button" class="nav-persp-btn" data-perspective="raw"
|
|
74
|
+
title="Raw: the frame as computed">Raw</button><span
|
|
75
|
+
class="nav-persp-bar" aria-hidden="true">|</span><button
|
|
76
|
+
type="button" class="nav-persp-btn" data-perspective="insurer"
|
|
77
|
+
title="Insurer: the business reading">Insurer</button>
|
|
78
|
+
<span class="dot" aria-hidden="true">·</span>
|
|
79
|
+
</span>
|
|
80
|
+
<!-- The two versions that matter, in the header rather than
|
|
81
|
+
behind About. Which library built the numbers on screen
|
|
82
|
+
is the first question of any session that spans a
|
|
83
|
+
version bump, and the api one answers "did the deploy
|
|
84
|
+
take" without a round trip through a panel. Filled from
|
|
85
|
+
/v1/meta; blank until it answers, and blank if it does
|
|
86
|
+
not, since a wrong version is worse than none. -->
|
|
87
|
+
<span class="nav-versions mono" id="nav-versions" title="aggregate and api versions"></span>
|
|
88
|
+
<div class="dropdown">
|
|
89
|
+
<button type="button" class="hamburger-btn" data-bs-toggle="dropdown"
|
|
90
|
+
aria-expanded="false" aria-label="menu" title="Menu">
|
|
91
|
+
<i class="bi bi-list"></i></button>
|
|
92
|
+
<ul class="dropdown-menu dropdown-menu-end">
|
|
93
|
+
<!-- Tables: the page-wide static / interactive choice. It lives here
|
|
94
|
+
rather than on each tab because it is a preference, not a per-table
|
|
95
|
+
decision, and a switch on every table would be a lot of chrome for
|
|
96
|
+
something nobody changes twice in a session. The Overview carries a
|
|
97
|
+
second affordance for the same value, next to the tables it steers. -->
|
|
98
|
+
<li><h6 class="dropdown-header">Tables</h6></li>
|
|
99
|
+
<!-- The two statics adjacent, Interactive last
|
|
100
|
+
(author, Round 5 item 15). Full precision is a
|
|
101
|
+
third state of the one preference rather than a
|
|
102
|
+
second preference: it answers the same question
|
|
103
|
+
the other two do, how should a table read, and
|
|
104
|
+
the interactive view is already exact. Reading
|
|
105
|
+
the menu top to bottom now goes printed, printed
|
|
106
|
+
with all the digits, then the instrument.
|
|
107
|
+
|
|
108
|
+
It is the one of the three that costs a fetch.
|
|
109
|
+
Every document carries the exact values under
|
|
110
|
+
include_raw, but which of the two the static
|
|
111
|
+
walker prints is decided when the document is
|
|
112
|
+
built, so `setTableView` refetches across that
|
|
113
|
+
boundary and only across it. -->
|
|
114
|
+
<li><button type="button" class="dropdown-item menu-check-item" data-table-view="static">
|
|
115
|
+
<i class="bi bi-check2"></i><span>Static</span>
|
|
116
|
+
<small class="text-muted">book-quality, printed</small></button></li>
|
|
117
|
+
<li><button type="button" class="dropdown-item menu-check-item" data-table-view="precise">
|
|
118
|
+
<i class="bi bi-check2"></i><span>Static, full precision</span>
|
|
119
|
+
<small class="text-muted">all digits</small></button></li>
|
|
120
|
+
<li><button type="button" class="dropdown-item menu-check-item" data-table-view="interactive">
|
|
121
|
+
<i class="bi bi-check2"></i><span>Interactive</span>
|
|
122
|
+
<small class="text-muted">sort, filter, search</small></button></li>
|
|
123
|
+
<li><hr class="dropdown-divider"></li>
|
|
124
|
+
<!-- Perspective: which business reading of an
|
|
125
|
+
exhibit to serve. The library owns the
|
|
126
|
+
translation (captions, row flags, drops,
|
|
127
|
+
relabeling), so this is a passthrough on the
|
|
128
|
+
exhibit route and reaches the leaves that take
|
|
129
|
+
it: PnL Summary / Waterfall / Ledger / Tail,
|
|
130
|
+
and More Tail behavior / Dependency. -->
|
|
131
|
+
<li><h6 class="dropdown-header">Perspective</h6></li>
|
|
132
|
+
<li><button type="button" class="dropdown-item menu-check-item" data-perspective="insurer">
|
|
133
|
+
<i class="bi bi-check2"></i><span>Insurer</span>
|
|
134
|
+
<small class="text-muted">the business reading</small></button></li>
|
|
135
|
+
<li><button type="button" class="dropdown-item menu-check-item" data-perspective="raw">
|
|
136
|
+
<i class="bi bi-check2"></i><span>Raw</span>
|
|
137
|
+
<small class="text-muted">the frame as computed</small></button></li>
|
|
138
|
+
<li><hr class="dropdown-divider"></li>
|
|
139
|
+
<!-- Editor: the emacs keys, in the same checked-item
|
|
140
|
+
form as Tables above and for the same reason,
|
|
141
|
+
a preference rather than a per-build decision.
|
|
142
|
+
Deliberately NOT a `form-switch` in here: a form
|
|
143
|
+
control inside a dropdown-menu keeps the menu
|
|
144
|
+
open on click unless the menu is given
|
|
145
|
+
data-bs-auto-close="outside", and a check-style
|
|
146
|
+
item that toggles and closes is the behavior
|
|
147
|
+
Tables already has. -->
|
|
148
|
+
<li><h6 class="dropdown-header">Editor</h6></li>
|
|
149
|
+
<li><button type="button" class="dropdown-item menu-check-item" id="emacs-item">
|
|
150
|
+
<i class="bi bi-check2"></i><span>Emacs keys</span>
|
|
151
|
+
<small class="text-muted">Ctrl+A/E/K/Y, N/P, F/B/D</small></button></li>
|
|
152
|
+
<li><hr class="dropdown-divider"></li>
|
|
153
|
+
<li><button type="button" class="dropdown-item" data-bs-toggle="offcanvas" data-bs-target="#helpPanel">Help</button></li>
|
|
154
|
+
<li><button type="button" class="dropdown-item" id="dl-agg">Download models</button></li>
|
|
155
|
+
<!-- "Download plot" stood here through a130. It is
|
|
156
|
+
the chart's own Download menu now, in the strip
|
|
157
|
+
beside the picture, which is where the reader is
|
|
158
|
+
looking and which reaches every chart: the
|
|
159
|
+
handler behind this item read a hard coded trio
|
|
160
|
+
of chart handles, so the Pricing group's kappa
|
|
161
|
+
curves could never be saved from it. -->
|
|
162
|
+
<li><button type="button" class="dropdown-item" data-bs-toggle="offcanvas" data-bs-target="#aboutPanel">About</button></li>
|
|
163
|
+
</ul>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
</nav>
|
|
168
|
+
</header>
|
|
169
|
+
|
|
170
|
+
<!-- ============================================================
|
|
171
|
+
Main
|
|
172
|
+
============================================================ -->
|
|
173
|
+
<main class="container-fluid px-3 px-md-4 py-3" style="max-width:1280px;">
|
|
174
|
+
|
|
175
|
+
<!-- The lede. One sentence naming what the app is for, with the terms
|
|
176
|
+
notice at the right edge linking to the About panel's disclaimer.
|
|
177
|
+
The notice sits here, above the input, because a terms line nobody
|
|
178
|
+
passes on the way in agrees nobody to anything; it stays small and
|
|
179
|
+
grey so the pitch leads. No box around either since a162: it sits
|
|
180
|
+
directly above the input box, which is all that has to be said.
|
|
181
|
+
The hero cards that stood here through a36 are gone, and the
|
|
182
|
+
random hero build behind them went at a93: the page lands on dice
|
|
183
|
+
of dice, in the editor from the first paint. The gallery is to
|
|
184
|
+
resurface inside the Examples dropdown. -->
|
|
185
|
+
<div class="lede-box">
|
|
186
|
+
<p class="lede">Model a book of insurance, investigate tail risk,
|
|
187
|
+
allocate margin, apply and price reinsurance.</p>
|
|
188
|
+
<p class="lede-terms">Use of this site signifies agreement with the
|
|
189
|
+
<a href="#aboutPanel" data-bs-toggle="offcanvas" data-bs-target="#aboutPanel">terms</a>.</p>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<!-- Editor box (CM6 mounts into #editor-host) -->
|
|
193
|
+
<div class="editor-wrap">
|
|
194
|
+
<div class="editor-box" id="editor-box">
|
|
195
|
+
<div id="editor-host"></div>
|
|
196
|
+
</div>
|
|
197
|
+
<i class="bi bi-x-circle editor-clear" id="editor-clear" title="clear" role="button" aria-label="clear editor"></i>
|
|
198
|
+
<!-- The history walk: up, the readout, down, stacked in the
|
|
199
|
+
editor's right margin. The nav belongs with the box it
|
|
200
|
+
navigates, not on the action row, which already carries Build,
|
|
201
|
+
Examples, Reformat and a five-wide derive group.
|
|
202
|
+
|
|
203
|
+
**The arrows are drawn to match the numbering, and this is the
|
|
204
|
+
one thing a later reader could get backwards.** The counter
|
|
205
|
+
counts up, so up steps to an OLDER program and a LOWER number,
|
|
206
|
+
down to a newer one and a higher number. Stacked, the two
|
|
207
|
+
buttons draw the list they walk: oldest above, newest below,
|
|
208
|
+
the way a notebook puts earlier cells higher and a terminal
|
|
209
|
+
puts newer output lower.
|
|
210
|
+
|
|
211
|
+
Through a115 this was keys only, which on an iPad is no route
|
|
212
|
+
at all: the on-screen keyboard has no arrow keys, so the
|
|
213
|
+
readout described a control the reader had no way to operate.
|
|
214
|
+
|
|
215
|
+
The readout is where it has been since Round 5 item 14: a bare
|
|
216
|
+
`[3/4]`, here rather than on the action row, because stepping
|
|
217
|
+
back to a program you have built before and building it looks
|
|
218
|
+
like nothing happened when the strip redraws to the same words.
|
|
219
|
+
On the row it was the one `.fb-text` outside `.fb-right`, so it
|
|
220
|
+
missed the rule that makes those hints small, grey and
|
|
221
|
+
monospaced. Empty until the first build, and empty again while
|
|
222
|
+
the walk is showing a stashed draft, which is not an entry and
|
|
223
|
+
has no number.
|
|
224
|
+
|
|
225
|
+
The wrapper keeps `pointer-events: none` so the editor's right
|
|
226
|
+
margin still takes a click through the gaps; only the two
|
|
227
|
+
buttons take it back. Both are present from the first paint,
|
|
228
|
+
greyed, so nothing moves when the first program lands.
|
|
229
|
+
|
|
230
|
+
**Circled arrows, not bare ones, and that is about the set
|
|
231
|
+
rather than about the arrow.** These two sit under
|
|
232
|
+
`bi-x-circle`, and at a126 they were bare `bi-arrow-up` /
|
|
233
|
+
`bi-arrow-down` inside bordered boxes, so the margin held an
|
|
234
|
+
icon and then a widget. Same family, same weight, same optical
|
|
235
|
+
size makes the three read as one column of marks. The boxes came
|
|
236
|
+
off in the same edit; see `.hist-step`. -->
|
|
237
|
+
<div class="editor-hist" id="history-nav">
|
|
238
|
+
<button type="button" class="hist-step" id="history-prev"
|
|
239
|
+
aria-label="step back through your history" disabled>
|
|
240
|
+
<i class="bi bi-arrow-up-circle" aria-hidden="true"></i></button>
|
|
241
|
+
<span class="editor-pos" id="history-pos" aria-live="polite"></span>
|
|
242
|
+
<button type="button" class="hist-step" id="history-next"
|
|
243
|
+
aria-label="step forward through your history" disabled>
|
|
244
|
+
<i class="bi bi-arrow-down-circle" aria-hidden="true"></i></button>
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
|
|
248
|
+
<!-- Action row. One band: through a46 this was the button row over a
|
|
249
|
+
separate feedback line, and between them they held one idea. The
|
|
250
|
+
key hints and the emacs switch ride on the right; they fold away
|
|
251
|
+
below sm, since phones have no Ctrl key.
|
|
252
|
+
|
|
253
|
+
Build carries no color. The accent means selected and nothing
|
|
254
|
+
else, and Build is not a selection: it leads by weight and by
|
|
255
|
+
being first. -->
|
|
256
|
+
<div class="btnrow">
|
|
257
|
+
<button id="build-btn" class="btn btn-outline-secondary btn-build">Build</button>
|
|
258
|
+
|
|
259
|
+
<div class="dropdown">
|
|
260
|
+
<button class="btn btn-outline-secondary dropdown-toggle"
|
|
261
|
+
data-bs-toggle="dropdown" aria-expanded="false">
|
|
262
|
+
<i class="bi bi-collection me-1"></i><span class="d-none d-sm-inline"> Examples</span></button>
|
|
263
|
+
<ul id="examples-menu" class="dropdown-menu shadow-sm examples-menu">
|
|
264
|
+
<li><span class="dropdown-item-text text-muted small">loading…</span></li>
|
|
265
|
+
</ul>
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
<!-- Reformat sits outside the derive group, and before it, which
|
|
269
|
+
is where the author asked for it. Outside because it is not a
|
|
270
|
+
derivation: it rewrites the text in the box into
|
|
271
|
+
`format_program` form and builds nothing, so filing it under
|
|
272
|
+
"derive" would mislabel the one button in the row that leaves
|
|
273
|
+
the object alone. -->
|
|
274
|
+
<button id="reformat-btn" class="btn btn-outline-secondary"
|
|
275
|
+
title="rewrite the program in canonical form">Reformat</button>
|
|
276
|
+
|
|
277
|
+
<!-- The derivations. Each returns DecL that lands in the editor, so
|
|
278
|
+
you read what was built and can edit it; none of them mutates
|
|
279
|
+
an object behind a cached id. They are grouped behind one label
|
|
280
|
+
because they are a family: five peer buttons in a row said they
|
|
281
|
+
were five unrelated verbs.
|
|
282
|
+
|
|
283
|
+
They replaced the log2 and bs dropdowns that stood here, which
|
|
284
|
+
nobody used. Sharpen writes the `hints{}` clause those knobs
|
|
285
|
+
used to set, and writes it into a program you can keep, so the
|
|
286
|
+
grid is pinned by an audit that explains itself rather than by
|
|
287
|
+
a menu choice that vanishes when you reload.
|
|
288
|
+
|
|
289
|
+
Reset used to close this group and came out at a58: the history
|
|
290
|
+
walk already steps back through the programs you built, and a
|
|
291
|
+
button that undid exactly one derivation was a second, weaker
|
|
292
|
+
way to do it. GCN took its place. The walk's own buttons live in
|
|
293
|
+
the editor's right margin as of a116, so it is no longer a pair
|
|
294
|
+
of keys a phone cannot type. -->
|
|
295
|
+
<span class="derive-label">derive</span>
|
|
296
|
+
<div class="btn-group" role="group" aria-label="derive a new program">
|
|
297
|
+
<button id="sharpen-btn" class="btn btn-outline-secondary"
|
|
298
|
+
title="audit the grid and move to a better one">Sharpen</button>
|
|
299
|
+
<button id="hints-btn" class="btn btn-outline-secondary"
|
|
300
|
+
title="pin the grid this object built on into its hints{} clause, so a reference to it means one fixed thing">Hints</button>
|
|
301
|
+
<!-- The PnL split button, following the GCN shape beside it:
|
|
302
|
+
one press for the common case, a menu for the rest, and
|
|
303
|
+
no label ever changes with state. Through a182 this was
|
|
304
|
+
one button that flipped between PnL and Explode on the
|
|
305
|
+
object's kind, and the flip failed in practice: type a
|
|
306
|
+
new program over a built P&L without building, and the
|
|
307
|
+
button still said Explode and still acted on the stale
|
|
308
|
+
object. `applyPnl` in main.js now derives from the box,
|
|
309
|
+
and `renderActionRow` greys each item off its own flag:
|
|
310
|
+
`can_pnl` the main press, `can_pnl_rate` the rate pair,
|
|
311
|
+
`can_xpnl` the exploded form. -->
|
|
312
|
+
<button id="pnl-btn" class="btn btn-outline-secondary"
|
|
313
|
+
title="wrap this object in a P&L, ceded premiums as deposit amounts">PnL</button>
|
|
314
|
+
<button id="pnl-caret" type="button"
|
|
315
|
+
class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split"
|
|
316
|
+
data-bs-toggle="dropdown" aria-expanded="false"
|
|
317
|
+
aria-label="choose the P&L form"></button>
|
|
318
|
+
<ul class="dropdown-menu shadow-sm">
|
|
319
|
+
<li><button class="dropdown-item" type="button"
|
|
320
|
+
data-pnl-form="pnl" data-pnl-premium="rate">
|
|
321
|
+
PnL (rate)</button></li>
|
|
322
|
+
<li><button class="dropdown-item" type="button"
|
|
323
|
+
data-pnl-form="xpnl" data-pnl-premium="deposit">
|
|
324
|
+
xPnL</button></li>
|
|
325
|
+
<li><button class="dropdown-item" type="button"
|
|
326
|
+
data-pnl-form="xpnl" data-pnl-premium="rate">
|
|
327
|
+
xPnL (rate)</button></li>
|
|
328
|
+
</ul>
|
|
329
|
+
<!-- GCN: read the program as a pair of views. The main button
|
|
330
|
+
takes the default (gross / ceded) and the caret offers the
|
|
331
|
+
other two, which is the split-button shape the author
|
|
332
|
+
asked for: one press for the common case, a menu for the
|
|
333
|
+
rest. Greys on `can_views`, which needs an OCCURRENCE
|
|
334
|
+
cession, not merely any cession. -->
|
|
335
|
+
<button id="gcn-btn" class="btn btn-outline-secondary"
|
|
336
|
+
title="read this program as a pair of views">GCN</button>
|
|
337
|
+
<button id="gcn-caret" type="button"
|
|
338
|
+
class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split"
|
|
339
|
+
data-bs-toggle="dropdown" aria-expanded="false"
|
|
340
|
+
aria-label="choose which pair of views"></button>
|
|
341
|
+
<ul class="dropdown-menu shadow-sm">
|
|
342
|
+
<li><button class="dropdown-item" type="button" data-views="grossceded">
|
|
343
|
+
Gross / Ceded</button></li>
|
|
344
|
+
<li><button class="dropdown-item" type="button" data-views="grossnet">
|
|
345
|
+
Gross / Net</button></li>
|
|
346
|
+
<li><button class="dropdown-item" type="button" data-views="netceded">
|
|
347
|
+
Net / Ceded</button></li>
|
|
348
|
+
</ul>
|
|
349
|
+
</div>
|
|
350
|
+
|
|
351
|
+
<!-- Two rows, split by kind rather than by how often each is
|
|
352
|
+
pressed: what you do to the program on top, where you go
|
|
353
|
+
underneath. Ctrl+K and Ctrl+Shift+↑↓ stay in the help panel
|
|
354
|
+
only; this is a reminder, not a second copy of the key table.
|
|
355
|
+
|
|
356
|
+
The emacs switch used to ride here. It is a preference, not an
|
|
357
|
+
action, so it moved into the hamburger beside the Tables
|
|
358
|
+
choice. -->
|
|
359
|
+
<span class="fb-right d-none d-sm-flex">
|
|
360
|
+
<span class="fb-text">Ctrl+Enter build<span class="sep">·</span>Ctrl+Space complete</span>
|
|
361
|
+
<!-- `.mod-key` is rewritten at startup to whichever modifier
|
|
362
|
+
CodeMirror's `Mod-` resolves to here, which is Cmd on a Mac
|
|
363
|
+
and on an iPad. See `modifierName` in editor.js. -->
|
|
364
|
+
<span class="fb-text"><span class="mod-key">Ctrl</span>+↑↓ history<span class="sep">·</span>Ctrl+Shift+U tables</span>
|
|
365
|
+
</span>
|
|
366
|
+
</div>
|
|
367
|
+
|
|
368
|
+
<!-- Status strip: what is built, and whether it is OK. One line, and a
|
|
369
|
+
second that folds:
|
|
370
|
+
|
|
371
|
+
1. the object BasicBook Portfolio bs 4 log2 18 loss
|
|
372
|
+
mean 106,477 CV 0.2114 0.41s
|
|
373
|
+
2. the note library warnings, then what a derivation did,
|
|
374
|
+
then the program's own tags{} as chips with its
|
|
375
|
+
note{} running on after them
|
|
376
|
+
|
|
377
|
+
**Line one is clusters, not a run of dots.** Through a157 it was one
|
|
378
|
+
mono run at one size joined by seven `·`, so eight facts read as
|
|
379
|
+
sixteen tokens of equal weight. Labels are in the UI face and grey,
|
|
380
|
+
values in mono and dark, and three different gaps bind a label to
|
|
381
|
+
its value more tightly than to the pair beside it.
|
|
382
|
+
|
|
383
|
+
**The verdict is said only when it is not clean, and said second.**
|
|
384
|
+
The left bar and the ground already state it twice, so a third copy
|
|
385
|
+
in words on a clean build is what the reader learns to skip. On warn
|
|
386
|
+
and fail the word appears right after the name, where its position
|
|
387
|
+
does not wander with the wrap.
|
|
388
|
+
|
|
389
|
+
**The clock is four characters in the corner.** Through a157 it was
|
|
390
|
+
a line and a sentence of its own, "Calculated in 0.412 seconds",
|
|
391
|
+
for a number nobody reads.
|
|
392
|
+
|
|
393
|
+
**The note folds behind the chevron**, which carries the count so a
|
|
394
|
+
closed strip still announces a warning without spending a line on
|
|
395
|
+
its text. It folds only when there is a built object: a program
|
|
396
|
+
picked out of the Examples menu puts its note{} and tags{} here
|
|
397
|
+
before anything is built, and hiding that would be a regression in
|
|
398
|
+
the examples flow. See `syncSummaryMore` in main.js.
|
|
399
|
+
|
|
400
|
+
main.js sets `is-warn` / `is-fail` on the wrapper from the build's
|
|
401
|
+
own verdict, which tints the whole strip: hue alone is too weak for
|
|
402
|
+
a state you must not miss. -->
|
|
403
|
+
<div class="status-strip" id="status-strip">
|
|
404
|
+
<div class="summary" id="summary">
|
|
405
|
+
<div class="summary-inner" id="summary-inner">
|
|
406
|
+
<span class="text-muted">Type DecL above and press
|
|
407
|
+
<span class="mono">Ctrl+Enter</span> to build.</span>
|
|
408
|
+
</div>
|
|
409
|
+
<button class="summary-more" id="summary-more" aria-expanded="false"
|
|
410
|
+
title="what this build said about itself"><span
|
|
411
|
+
id="summary-more-text"></span><i class="bi bi-chevron-down"></i></button>
|
|
412
|
+
<span class="summary-clock" id="summary-clock"></span>
|
|
413
|
+
</div>
|
|
414
|
+
<div class="summary-note" id="summary-note"></div>
|
|
415
|
+
</div>
|
|
416
|
+
|
|
417
|
+
<!-- An identity block stood here through a119, carrying the object's
|
|
418
|
+
tags and its note. Both are on the status strip now, drawn under
|
|
419
|
+
every group rather than under Overview alone and off the build
|
|
420
|
+
response rather than a second request. See the note above the
|
|
421
|
+
Overview loaders in main.js. -->
|
|
422
|
+
|
|
423
|
+
<!-- Output navigation: seven groups, each with its own sub-tab row.
|
|
424
|
+
The groups are editorial, a judgment about how insurance work
|
|
425
|
+
proceeds, and the app authors them. Which leaves are live inside
|
|
426
|
+
one is a fact about the object, so the library computes it and
|
|
427
|
+
main.js renders each row from the capability block. Nothing here
|
|
428
|
+
says what a kind can do.
|
|
429
|
+
|
|
430
|
+
The order is the demo flow, which is the order the work happens in:
|
|
431
|
+
look at the gross book, add reinsurance, decide what to charge for
|
|
432
|
+
what is left, then read the economics of the result. Bounds is
|
|
433
|
+
orthogonal to all four and sits late; More is the specialist
|
|
434
|
+
frames. Nothing may stand between a group strip and its sub menu.
|
|
435
|
+
|
|
436
|
+
This order is written twice, here and as the key order of
|
|
437
|
+
NAV_GROUPS in nav.js, which is also what Alt+1…7 indexes.
|
|
438
|
+
Lab is last and ships hidden; see its slot below.
|
|
439
|
+
`dev/scripts/check-nav.mjs` parses this list and asserts the two
|
|
440
|
+
agree, so they cannot drift apart again. -->
|
|
441
|
+
<!-- `data-label` repeats the visible label, and must keep matching it.
|
|
442
|
+
site.css draws it as a hidden bold ghost inside the button so every
|
|
443
|
+
tab is laid out at its selected width, whether or not it is the
|
|
444
|
+
selected one. Without it, selecting a tab makes it bold, bold makes
|
|
445
|
+
it wider, and every tab to its right moves: nothing with a mouse,
|
|
446
|
+
a moving target under a thumb. -->
|
|
447
|
+
<ul class="nav nav-pills out-tabs" role="tablist">
|
|
448
|
+
<li class="nav-item"><button class="nav-link active" data-bs-toggle="pill" data-bs-target="#t-overview" data-tab="overview" data-label="Overview" type="button">Overview</button></li>
|
|
449
|
+
<li class="nav-item"><button class="nav-link" data-bs-toggle="pill" data-bs-target="#t-reinsurance" data-tab="reinsurance" data-label="Re" type="button">Re</button></li>
|
|
450
|
+
<li class="nav-item"><button class="nav-link" data-bs-toggle="pill" data-bs-target="#t-pricing" data-tab="pricing" data-label="Pricing" type="button">Pricing</button></li>
|
|
451
|
+
<li class="nav-item"><button class="nav-link" data-bs-toggle="pill" data-bs-target="#t-economics" data-tab="economics" data-label="PnL" type="button">PnL</button></li>
|
|
452
|
+
<li class="nav-item"><button class="nav-link" data-bs-toggle="pill" data-bs-target="#t-bounds" data-tab="bounds" data-label="Bounds" type="button">Bounds</button></li>
|
|
453
|
+
<li class="nav-item"><button class="nav-link" data-bs-toggle="pill" data-bs-target="#t-more" data-tab="more" data-label="More" type="button">More</button></li>
|
|
454
|
+
<!-- Lab: where documents from installed plugin packages land. In the
|
|
455
|
+
strip statically and hidden, revealed by main.js when the boot
|
|
456
|
+
manifest from /v1/meta is non-empty. Appending a seventh tab
|
|
457
|
+
from JS after that fetch resolves would shift the layout on
|
|
458
|
+
every page load, and it would break check-nav.mjs's premise
|
|
459
|
+
that the strip lists every group the app knows about: the strip
|
|
460
|
+
still does, and the manifest decides only visibility. -->
|
|
461
|
+
<li class="nav-item d-none" id="tab-lab-slot"><button class="nav-link" data-bs-toggle="pill" data-bs-target="#t-lab" data-tab="lab" data-label="Lab" type="button">Lab</button></li>
|
|
462
|
+
</ul>
|
|
463
|
+
|
|
464
|
+
<div class="tab-content">
|
|
465
|
+
<!-- Overview: the landing group. The identity block used to sit
|
|
466
|
+
here, above the sub-tab row; it moved above the group strip at
|
|
467
|
+
a47 so nothing stands between the two menu levels. -->
|
|
468
|
+
<div class="tab-pane fade show active" id="t-overview">
|
|
469
|
+
<div class="sub-tabs" id="sub-overview"></div>
|
|
470
|
+
<div id="pane-overview" class="pane"></div>
|
|
471
|
+
</div>
|
|
472
|
+
|
|
473
|
+
<!-- PnL: a P&L's ledger, its ratios, and the margin walk. The pane
|
|
474
|
+
id, the tab key and the leaf ids stay `economics`: they are in
|
|
475
|
+
stored view state and in links already shared, and this was a
|
|
476
|
+
label change. -->
|
|
477
|
+
<div class="tab-pane fade" id="t-economics">
|
|
478
|
+
<div class="sub-tabs" id="sub-economics"></div>
|
|
479
|
+
<div id="pane-economics" class="pane"></div>
|
|
480
|
+
</div>
|
|
481
|
+
|
|
482
|
+
<!-- Reinsurance: the program description names the whole structure,
|
|
483
|
+
so like the Overview identity block it sits above the row. -->
|
|
484
|
+
<div class="tab-pane fade" id="t-reinsurance">
|
|
485
|
+
<div class="sub-tabs" id="sub-reinsurance"></div>
|
|
486
|
+
<div class="reins-desc" id="reins-desc"></div>
|
|
487
|
+
<!-- Quick Re: one row, one layer, straight into the editor.
|
|
488
|
+
Author's layout, Round 5 item 11.
|
|
489
|
+
|
|
490
|
+
There is **no text box for the clause**. Through a67 the
|
|
491
|
+
row wrote a clause into a local input and that input was
|
|
492
|
+
then ceded, so the same string was transferred twice before
|
|
493
|
+
anything happened. The author's ruling: press Add re and it
|
|
494
|
+
goes into the program above, which is where you read it and
|
|
495
|
+
where you adjust it. That box is a full editor with real
|
|
496
|
+
completion, so a second, worse one beside it earned nothing.
|
|
497
|
+
|
|
498
|
+
ONE layer, or ONE generated stack, and nothing else. The
|
|
499
|
+
row read one layer only through a192, on the reasoning that
|
|
500
|
+
a second layer here meant the sugar had failed. The author
|
|
501
|
+
reversed that on 2026-10-06: a generated stack is not a
|
|
502
|
+
second hand-typed layer, it is one press producing the
|
|
503
|
+
structure an underwriter would have written over that span,
|
|
504
|
+
and the arithmetic of it (double, snap to a quote-sheet
|
|
505
|
+
number, step the share up) is mechanical. Typing a six
|
|
506
|
+
layer tower by hand is the thing that stops a reader from
|
|
507
|
+
exploring a program. So Add re writes the span as one layer
|
|
508
|
+
and Tower writes it as a stack; a multi-layer program that
|
|
509
|
+
is not a stack is still typed upstairs, which is what that
|
|
510
|
+
box is for. Two *tiers* is different again and is supported
|
|
511
|
+
either way: cede on Occ, then switch to Agg and cede again,
|
|
512
|
+
each clause authoritative for its own tier.
|
|
513
|
+
|
|
514
|
+
Attach and detach each take ONE field with two readings:
|
|
515
|
+
`50%` is a probability and a bare number is currency, so
|
|
516
|
+
there is no mode switch and no second set of boxes to keep
|
|
517
|
+
in step. The share box reads the same way. No stepper
|
|
518
|
+
arrows, per the author: `<input type=number>` refuses the
|
|
519
|
+
`%` and the dual reading is worth more than the arrows.
|
|
520
|
+
|
|
521
|
+
The row reads as a sentence, and the operator words are
|
|
522
|
+
what make it one: 100% part of, from 50% attach to 95%
|
|
523
|
+
detach. The author's wording, round 7 item 2; the earlier
|
|
524
|
+
`part of ... attach, ... detach` left the reader to supply
|
|
525
|
+
the preposition and the layer read as three separate
|
|
526
|
+
answers rather than as one cover. -->
|
|
527
|
+
<!-- `part of` is FIXED, and is no longer the DecL token it used
|
|
528
|
+
to mirror. It showed `so` over a percentage and `po` over
|
|
529
|
+
an amount; `so` and `of` were retired upstream at
|
|
530
|
+
1.0.0a249, so `po` is now the one placement keyword and the
|
|
531
|
+
`%` is what tells it a share from an amount. The row says
|
|
532
|
+
the one thing in English and `placementHead` writes the
|
|
533
|
+
token. Do not "fix" this back into sync with the clause.
|
|
534
|
+
|
|
535
|
+
See `resolveSpan`, `composeCession` and `composeTower` in
|
|
536
|
+
main.js. -->
|
|
537
|
+
<!-- The control band, one enclosure per group: the ask gets a
|
|
538
|
+
ground and a hairline and the answer sits plain underneath.
|
|
539
|
+
A wrapper rather than a class on `#reins-entry`, which
|
|
540
|
+
already carries `.tab-tools`'s --tabpad padding and would
|
|
541
|
+
otherwise be indented twice. See `.control-band` in
|
|
542
|
+
site.css. -->
|
|
543
|
+
<div class="control-band">
|
|
544
|
+
<div class="tab-tools reins-entry" id="reins-entry">
|
|
545
|
+
<div class="reins-row">
|
|
546
|
+
<span class="reins-lede">Quick Re</span>
|
|
547
|
+
<!-- The same segmented control as CoC / LR on Pricing,
|
|
548
|
+
which is what the author asked it to look like. -->
|
|
549
|
+
<div class="btn-group btn-group-sm" role="group"
|
|
550
|
+
aria-label="which tier to cede">
|
|
551
|
+
<input type="radio" class="btn-check" name="qr-basis"
|
|
552
|
+
id="qr-basis-occ" value="occurrence" checked>
|
|
553
|
+
<label class="btn btn-outline-secondary" for="qr-basis-occ">Occ</label>
|
|
554
|
+
<input type="radio" class="btn-check" name="qr-basis"
|
|
555
|
+
id="qr-basis-agg" value="aggregate">
|
|
556
|
+
<label class="btn btn-outline-secondary" for="qr-basis-agg">Agg</label>
|
|
557
|
+
</div>
|
|
558
|
+
<input id="qr-share" class="qr-field" type="text" inputmode="decimal"
|
|
559
|
+
autocomplete="off" spellcheck="false" value="100%"
|
|
560
|
+
aria-label="share or part of">
|
|
561
|
+
<span class="qr-op">placed, from</span>
|
|
562
|
+
<input id="qr-attach" class="qr-field" type="text" inputmode="decimal"
|
|
563
|
+
autocomplete="off" spellcheck="false" value="50%"
|
|
564
|
+
aria-label="attachment">
|
|
565
|
+
<span class="qr-op">attach to</span>
|
|
566
|
+
<input id="qr-detach" class="qr-field" type="text" inputmode="decimal"
|
|
567
|
+
autocomplete="off" spellcheck="false" value="95%"
|
|
568
|
+
aria-label="detachment">
|
|
569
|
+
<span class="qr-op">detach</span>
|
|
570
|
+
<button id="reins-btn" class="btn btn-primary btn-sm">Add re</button>
|
|
571
|
+
<!-- Outline, so Add re keeps the primary: one layer is
|
|
572
|
+
still the ordinary press and the stack is the one
|
|
573
|
+
you reach for deliberately. -->
|
|
574
|
+
<button id="tower-btn" class="btn btn-outline-primary btn-sm">Tower</button>
|
|
575
|
+
<!-- Both hint paragraphs folded into one tooltip, per the
|
|
576
|
+
author: the row explains itself on demand rather than
|
|
577
|
+
carrying two paragraphs nobody reads twice. -->
|
|
578
|
+
<button type="button" class="qr-help" id="qr-help"
|
|
579
|
+
data-bs-toggle="tooltip" data-bs-placement="top"
|
|
580
|
+
aria-label="how Quick Re reads these boxes"
|
|
581
|
+
title="A percentage is read as a probability, so attach 50% attaches at the median and detach 95% reaches the 95th percentile; a plain number is an amount, and the two mix freely. Quantiles are rounded to three figures, because a layer is something you write down. One clause per tier: the clause is folded into the program above, so an occurrence cession lands before the frequency clause and an aggregate one after it. Tower lays the same span out as a stack of roughly doubling layers, named Occ 1 upward, every bound snapped to a quote-sheet number, so the top of the stack reaches the detachment or the first round number above it; the share box places the bottom layer and the ladder steps up from there to 95%, since shares never fall as the attachment rises. Edit more complex structures directly in the program edit box.">?</button>
|
|
582
|
+
</div>
|
|
583
|
+
<!-- The clause Add re will write, kept current as you type.
|
|
584
|
+
Debounced, because a percentage costs a quantile lookup.
|
|
585
|
+
Populated from the defaults before anything is touched,
|
|
586
|
+
so the row says what it does without being used.
|
|
587
|
+
|
|
588
|
+
It stays on the single-layer reading even though Tower
|
|
589
|
+
sits beside it, which is the author's ruling: the one
|
|
590
|
+
layer names the bottom and the top of the program, which
|
|
591
|
+
is what you want to see while you are choosing them.
|
|
592
|
+
Tower's own clause is read where every cession is read,
|
|
593
|
+
in the program box above. Refusals from either button
|
|
594
|
+
still land here. -->
|
|
595
|
+
<p class="reins-entry-hint reins-preview" id="qr-preview"></p>
|
|
596
|
+
<!-- The last priced press, layer by layer: the standard
|
|
597
|
+
deviation load against the two distortion prices, which
|
|
598
|
+
of the three bound, and the quote that came out.
|
|
599
|
+
|
|
600
|
+
Here rather than as a sub-tab leaf, which is the
|
|
601
|
+
author's ruling of 2026-10-06. The rows belong to the
|
|
602
|
+
press and not to the object, so a leaf keyed to the
|
|
603
|
+
object would go on showing the previous book's quote
|
|
604
|
+
after a switch. This sits where the press happened, and
|
|
605
|
+
it empties whenever the row is reset. -->
|
|
606
|
+
<div id="qr-quotes" class="qr-quotes d-none"></div>
|
|
607
|
+
</div>
|
|
608
|
+
</div><!-- /.control-band. Left at the wrapper's own indent
|
|
609
|
+
rather than reindenting the forty lines above it, which
|
|
610
|
+
would bury the real change in whitespace. -->
|
|
611
|
+
<div id="pane-reinsurance" class="pane"></div>
|
|
612
|
+
</div>
|
|
613
|
+
|
|
614
|
+
<!-- Pricing: three leaves, laid out Calibrate Allocate | Evaluate.
|
|
615
|
+
|
|
616
|
+
Calibrate and Allocate share one form and one press. It fixes
|
|
617
|
+
capital with a probability or an asset level, takes one target,
|
|
618
|
+
and calibrates the standard distortion set; the two panes are
|
|
619
|
+
the receipt and the allocation of that same calibration, filled
|
|
620
|
+
from one POST. The basis group chooses which reinsurance view to
|
|
621
|
+
calibrate on; it is always present and always drawn, so the form
|
|
622
|
+
does not jump when you step from a reinsured example to a plain
|
|
623
|
+
one. The preview line under the form says what the pentagon
|
|
624
|
+
would be, kept current as you type, and is also where an
|
|
625
|
+
impossible anchor says so.
|
|
626
|
+
|
|
627
|
+
Evaluate goes the other way: the premium is already set, and
|
|
628
|
+
the panel reports the distortion in each family that values the
|
|
629
|
+
margin at zero. Its basis group names *which* premium is being
|
|
630
|
+
input, which is a narrower question than the gross versus net
|
|
631
|
+
reading the PnL group answers. Its asset anchor is what closes the
|
|
632
|
+
round trip with a calibration struck at the same level; left
|
|
633
|
+
blank it is the library's unlimited reading, which reports four
|
|
634
|
+
families rather than five. Both boxes open on the pricing in
|
|
635
|
+
hand, and are hidden for a P&L, whose ledger carries a premium
|
|
636
|
+
per row.
|
|
637
|
+
|
|
638
|
+
-->
|
|
639
|
+
<div class="tab-pane fade" id="t-pricing">
|
|
640
|
+
<div class="sub-tabs" id="sub-pricing"></div>
|
|
641
|
+
|
|
642
|
+
<!-- The pricing forms are built by `pricing-form.js` since
|
|
643
|
+
a100, into these hosts. They were three copies of one row
|
|
644
|
+
of markup, each stating its choice twice (a btn-group
|
|
645
|
+
naming the anchor and a span repeating it), and the Bounds
|
|
646
|
+
group had a fourth copy in a different spelling. One form
|
|
647
|
+
over `price_pentagon`'s signature serves every leaf that
|
|
648
|
+
asks for a price, here and under Bounds.
|
|
649
|
+
|
|
650
|
+
Four wrappers, and which of them is on screen is the leaf.
|
|
651
|
+
Calibrate and Stand-alone are two documents from one press
|
|
652
|
+
and share the first; Allocate is a second press, because a
|
|
653
|
+
decomposition off an occurrence joint is real work and is
|
|
654
|
+
not what a reader asking for a calibration ordered; Plot
|
|
655
|
+
asks the object rather than a form, so it carries no form
|
|
656
|
+
at all. -->
|
|
657
|
+
<div id="leaf-price">
|
|
658
|
+
<div class="control-band"><div id="price-form"></div></div>
|
|
659
|
+
<div id="pane-calibrate" class="pane"></div>
|
|
660
|
+
<div id="pane-standalone" class="pane d-none"></div>
|
|
661
|
+
</div>
|
|
662
|
+
|
|
663
|
+
<!-- A `Massive joint` placeholder sat here from a105 to a173,
|
|
664
|
+
greyed, waiting on the library to bring kappa to the
|
|
665
|
+
disk-backed one-sweep route. It is gone on the author's
|
|
666
|
+
ruling of 2026-09-29: a massive joint is a zarr store on
|
|
667
|
+
local disk, so it belongs to a local or VPN session and
|
|
668
|
+
never to a served app. The in-memory kappa this pane and
|
|
669
|
+
the Plot leaf draw was never the thing it was waiting
|
|
670
|
+
for. -->
|
|
671
|
+
<div id="leaf-allocate" class="d-none">
|
|
672
|
+
<div class="control-band"><div id="allocate-form"></div></div>
|
|
673
|
+
<div id="pane-allocate" class="pane"></div>
|
|
674
|
+
</div>
|
|
675
|
+
|
|
676
|
+
<div id="leaf-kappa" class="d-none">
|
|
677
|
+
<div id="pane-kappa" class="pane"></div>
|
|
678
|
+
</div>
|
|
679
|
+
|
|
680
|
+
<div id="leaf-evaluate" class="d-none">
|
|
681
|
+
<div class="control-band"><div id="evaluate-form"></div></div>
|
|
682
|
+
<div id="pane-evaluate" class="pane"></div>
|
|
683
|
+
</div>
|
|
684
|
+
|
|
685
|
+
<!-- Pr Ruin: the probability of eventual default, a teaching
|
|
686
|
+
pane. The premium half of the form is the shared pricing
|
|
687
|
+
component, the capital half is one probability box, and
|
|
688
|
+
the picture below tracks both through a debounced POST.
|
|
689
|
+
The chart pane and the stats strip are separate hosts so
|
|
690
|
+
the exhibit table redraws without touching the canvas. -->
|
|
691
|
+
<div id="leaf-ruin" class="d-none">
|
|
692
|
+
<div class="control-band"><div id="ruin-form"></div></div>
|
|
693
|
+
<div id="pane-ruin" class="pane"></div>
|
|
694
|
+
<div id="pane-ruin-stats" class="pane"></div>
|
|
695
|
+
</div>
|
|
696
|
+
</div>
|
|
697
|
+
|
|
698
|
+
<!-- Bounds: three leaves against the three classes in bounds.py.
|
|
699
|
+
|
|
700
|
+
Ordinary pricing picks a distortion and reports its number.
|
|
701
|
+
These ask the other question: hold the calibration fixed, let
|
|
702
|
+
the distortion range over everything consistent with it, and
|
|
703
|
+
report how wide the answer can be. So every leaf needs a
|
|
704
|
+
premium, which is the calibration, and none computes on
|
|
705
|
+
arrival: they are work, and a leaf that computed on the way in
|
|
706
|
+
would spend it every time you passed through. -->
|
|
707
|
+
<div class="tab-pane fade" id="t-bounds">
|
|
708
|
+
<div class="sub-tabs" id="sub-bounds"></div>
|
|
709
|
+
<!-- The hint is inside the band because it is a hint about the
|
|
710
|
+
control, and it cannot go inside `#bounds-form` itself:
|
|
711
|
+
`createPricingForm` empties its host. -->
|
|
712
|
+
<div class="control-band">
|
|
713
|
+
<div id="bounds-form"></div>
|
|
714
|
+
<span class="sub-hint" id="bounds-hint"></span>
|
|
715
|
+
</div>
|
|
716
|
+
<div id="pane-bounds" class="pane"></div>
|
|
717
|
+
</div>
|
|
718
|
+
|
|
719
|
+
<!-- More: the specialist frames. The sub-tab row is rendered by
|
|
720
|
+
main.js, since which leaves are live is per object. -->
|
|
721
|
+
<div class="tab-pane fade" id="t-more">
|
|
722
|
+
<div class="sub-tabs" id="sub-more"></div>
|
|
723
|
+
<div id="pane-more" class="pane"></div>
|
|
724
|
+
</div>
|
|
725
|
+
|
|
726
|
+
<!-- Lab. One pane, whatever the plugins registered: an exhibit
|
|
727
|
+
draws through the same envelope path as every other table leaf
|
|
728
|
+
and a chart through the same ChartDoc mount, so there is
|
|
729
|
+
nothing plugin-shaped in the markup. -->
|
|
730
|
+
<div class="tab-pane fade" id="t-lab">
|
|
731
|
+
<div class="sub-tabs" id="sub-lab"></div>
|
|
732
|
+
<div id="pane-lab" class="pane"></div>
|
|
733
|
+
</div>
|
|
734
|
+
|
|
735
|
+
</div>
|
|
736
|
+
</main>
|
|
737
|
+
|
|
738
|
+
<!-- ============================================================
|
|
739
|
+
Help offcanvas (opened by the header "?")
|
|
740
|
+
============================================================ -->
|
|
741
|
+
<div class="offcanvas offcanvas-end help-panel" tabindex="-1" id="helpPanel" aria-labelledby="helpLabel">
|
|
742
|
+
<div class="offcanvas-header">
|
|
743
|
+
<h5 class="offcanvas-title" id="helpLabel">Quick help</h5>
|
|
744
|
+
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
|
745
|
+
</div>
|
|
746
|
+
<div class="offcanvas-body help-body">
|
|
747
|
+
<p class="help-lead">The <strong>aggregate Loss Lab</strong>. Build and
|
|
748
|
+
explore compound <em>(aggregate)</em> loss distributions from simple
|
|
749
|
+
<strong>DecL</strong> programs.</p>
|
|
750
|
+
|
|
751
|
+
<h6>Try it</h6>
|
|
752
|
+
<div class="help-try">
|
|
753
|
+
<code id="help-example">agg Demo 100 claims 1000 xs 0 sev lognorm 90 cv 1.5 poisson</code>
|
|
754
|
+
<div class="mt-2 d-flex align-items-center gap-2">
|
|
755
|
+
<button id="help-load" class="btn btn-sm btn-primary">Load it</button>
|
|
756
|
+
<span class="text-muted form-gloss">then press <kbd>Ctrl</kbd>+<kbd>Enter</kbd></span>
|
|
757
|
+
</div>
|
|
758
|
+
</div>
|
|
759
|
+
|
|
760
|
+
<h6>Keys</h6>
|
|
761
|
+
<div class="help-keys">
|
|
762
|
+
<span><kbd>Ctrl</kbd>+<kbd>Enter</kbd></span><span>build</span>
|
|
763
|
+
<span><kbd>Ctrl</kbd>+<kbd>Space</kbd></span><span>autocomplete; <kbd>Tab</kbd> takes the suggestion</span>
|
|
764
|
+
<span><kbd>Ctrl</kbd>+<kbd>K</kbd></span><span>search the example library</span>
|
|
765
|
+
<span><kbd class="mod-key">Ctrl</kbd>+<kbd>↑</kbd> <kbd>↓</kbd></span><span>step through history (or the two arrows in the editor's right margin)</span>
|
|
766
|
+
<span><kbd class="mod-key">Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>↑</kbd> <kbd>↓</kbd></span><span>step through the example library (loads, does not build); the counter beside the editor says where you are, and walks whatever the Examples menu is filtered and searched down to</span>
|
|
767
|
+
<span><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>U</kbd></span><span>flip every table between static and interactive</span>
|
|
768
|
+
<span><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>V</kbd></span><span>flip every exhibit between the raw frame and the insurer reading; the pair beside the versions says which one you are on</span>
|
|
769
|
+
<span><kbd>Alt</kbd>+<kbd>1</kbd>…<kbd>6</kbd></span><span>jump to an output group, numbered in the order they are listed below</span>
|
|
770
|
+
<span><kbd>←</kbd> <kbd>→</kbd> <kbd>Home</kbd> <kbd>End</kbd></span><span>walk a group or leaf row once it has focus, skipping whatever is dark</span>
|
|
771
|
+
<span><kbd>✕</kbd></span><span>clear the editor; press it again on an empty box to clear your history</span>
|
|
772
|
+
</div>
|
|
773
|
+
<p class="small text-muted">Ctrl+Shift+V stands aside inside the program box and the
|
|
774
|
+
entry forms, where the browser claims it for paste, and works everywhere else.
|
|
775
|
+
Menu ▸ Editor ▸ Emacs keys adds Ctrl+A/E/K/Y, N/P and F/B/D in the
|
|
776
|
+
program box.</p>
|
|
777
|
+
|
|
778
|
+
<h6>Controls</h6>
|
|
779
|
+
<ul class="help-tabs">
|
|
780
|
+
<li><span class="t">Build</span>: run the program (same as Ctrl+Enter)</li>
|
|
781
|
+
<li><span class="t">Examples</span>: load a ready-made program. Type to search it,
|
|
782
|
+
or click the tag pills to narrow it; the arrow walk follows what is left on
|
|
783
|
+
screen</li>
|
|
784
|
+
<li><span class="t">Reformat</span>: rewrite the program in canonical form, keeping
|
|
785
|
+
its <code>note{}</code>, <code>hints{}</code> and <code>tags{}</code></li>
|
|
786
|
+
<li><span class="t">Sharpen</span>: audit the grid and move to a better one, writing
|
|
787
|
+
the <code>hints{}</code> clause that pins it</li>
|
|
788
|
+
<li><span class="t">Hints</span>: keep the grid you have and write it into
|
|
789
|
+
<code>hints{}</code>, so <code>agg.Name</code> elsewhere means one fixed thing</li>
|
|
790
|
+
<li><span class="t">PnL</span>: wrap what you built in a profit and loss account.
|
|
791
|
+
Once a P&L is what you are reading the button becomes
|
|
792
|
+
<span class="t">Explode</span>, which opens it back into its parts</li>
|
|
793
|
+
<li><span class="t">GCN</span>: read a program with an occurrence cession as a pair
|
|
794
|
+
of views. The button takes gross / ceded; the caret beside it offers
|
|
795
|
+
gross / net and net / ceded</li>
|
|
796
|
+
</ul>
|
|
797
|
+
<p class="small text-muted">Each derivation writes DecL into the editor, so you can
|
|
798
|
+
read what it did, edit it, and build it again anywhere. The
|
|
799
|
+
<kbd>↑</kbd> in the editor's right margin walks back through the programs you
|
|
800
|
+
built, which is how you undo one.</p>
|
|
801
|
+
|
|
802
|
+
<h6>Output groups</h6>
|
|
803
|
+
<ul class="help-tabs">
|
|
804
|
+
<li><span class="t">Overview</span>: the distribution and its tail, then the moments
|
|
805
|
+
and whether to believe them (Plot, Summary, Validation, Stats, Tail)</li>
|
|
806
|
+
<li><span class="t">Re</span>: reinsurance, ceded and net by layer, with the shape and
|
|
807
|
+
the densities the cession leaves. The Quick Re row writes one layer into the
|
|
808
|
+
program above, on the occurrence or the aggregate tier</li>
|
|
809
|
+
<li><span class="t">Pricing</span>: calibrate a distortion set to a target, price
|
|
810
|
+
the parts stand-alone, allocate one premium across them, read the kappa curves
|
|
811
|
+
behind the split, or evaluate a premium already set</li>
|
|
812
|
+
<li><span class="t">PnL</span>: a P&L's ledger, its ratios, and the margin
|
|
813
|
+
walk</li>
|
|
814
|
+
<li><span class="t">Bounds</span>: how much of a price the choice of distortion
|
|
815
|
+
decides, for the whole and for the parts</li>
|
|
816
|
+
<li><span class="t">More</span>: Density · Tail behavior · Window
|
|
817
|
+
· Dependency · Sharpen · Narrative</li>
|
|
818
|
+
</ul>
|
|
819
|
+
<p class="small text-muted">A group or a leaf greyed out is one this object cannot
|
|
820
|
+
answer; hover it to read why. Nothing is hidden, so the menu is always the same
|
|
821
|
+
shape.</p>
|
|
822
|
+
|
|
823
|
+
<h6>Tables and charts</h6>
|
|
824
|
+
<ul class="help-tabs">
|
|
825
|
+
<li><span class="t">Tables</span>: static, static at full precision, or interactive,
|
|
826
|
+
from the menu or with Ctrl+Shift+U. An interactive grid sorts, filters and
|
|
827
|
+
searches, and its toolbar copies or saves the underlying values rather than the
|
|
828
|
+
printed text</li>
|
|
829
|
+
<li><span class="t">Perspective</span>: Raw is the frame as computed, Insurer is the
|
|
830
|
+
business reading of it. The two words beside the versions are a readout and a
|
|
831
|
+
switch at once</li>
|
|
832
|
+
<li><span class="t">Charts</span>: the strip under a picture carries that panel's
|
|
833
|
+
axis readings, log x, log y, full range, reflect, return period, invert, and its
|
|
834
|
+
reference lines. Download saves the picture as a PNG</li>
|
|
835
|
+
<li><span class="t">Joint surface</span>: a relief adds contours, marginals, mesh,
|
|
836
|
+
wall grid and lights; cut cycles through the slices; a click reads that cell out
|
|
837
|
+
in the strip; double-click, or reset, puts the camera back. Download also writes
|
|
838
|
+
the drawn surface as GLB, OBJ or STL, and a SpaceMouse can fly it in Chromium</li>
|
|
839
|
+
</ul>
|
|
840
|
+
<p class="small text-muted">Menu ▸ Download models saves every program you built
|
|
841
|
+
this session as one <code>.agg</code> file.</p>
|
|
842
|
+
|
|
843
|
+
<h6>Learn more</h6>
|
|
844
|
+
<p class="help-links mb-0">
|
|
845
|
+
<a href="https://aggregate.readthedocs.io/en/latest/4_dec_Language_Reference.html" target="_blank" rel="noopener">DecL language reference</a> ·
|
|
846
|
+
<a href="https://github.com/mynl/aggregate" target="_blank" rel="noopener">aggregate library on github</a>
|
|
847
|
+
</p>
|
|
848
|
+
|
|
849
|
+
<p class="help-fair mb-0">This is a shared, free demo, so builds are
|
|
850
|
+
rate-limited. Want no limits? <code>aggregate</code> is open source, so you can
|
|
851
|
+
<a href="https://github.com/mynl/aggregate" target="_blank" rel="noopener">run it locally</a>.</p>
|
|
852
|
+
</div>
|
|
853
|
+
</div>
|
|
854
|
+
|
|
855
|
+
<!-- About panel (offcanvas from the right, like Help) -->
|
|
856
|
+
<div class="offcanvas offcanvas-end help-panel about-panel" tabindex="-1" id="aboutPanel" aria-labelledby="aboutLabel">
|
|
857
|
+
<div class="offcanvas-header">
|
|
858
|
+
<h5 class="offcanvas-title" id="aboutLabel">About</h5>
|
|
859
|
+
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
|
860
|
+
</div>
|
|
861
|
+
<div class="offcanvas-body help-body">
|
|
862
|
+
<p class="help-lead">The <strong>aggregate Loss Lab</strong> (aLL): build and
|
|
863
|
+
explore compound <em>(aggregate)</em> loss distributions in the browser,
|
|
864
|
+
powered by the open-source <code>aggregate</code> library.</p>
|
|
865
|
+
|
|
866
|
+
<h6>Versions</h6>
|
|
867
|
+
<dl class="about-versions">
|
|
868
|
+
<dt>aggregate</dt><dd id="about-aggregate" class="mono">…</dd>
|
|
869
|
+
<dt>aggregate_api</dt><dd id="about-api" class="mono">…</dd>
|
|
870
|
+
<dt>csv-grid</dt><dd id="about-grid" class="mono">…</dd>
|
|
871
|
+
<dt>greater-tables</dt><dd id="about-tables" class="mono">…</dd>
|
|
872
|
+
<dt>ECharts</dt><dd id="about-echarts" class="mono">…</dd>
|
|
873
|
+
<dt>echarts-gl</dt><dd id="about-echarts-gl" class="mono">…</dd>
|
|
874
|
+
<dt>Bootstrap</dt><dd id="about-bootstrap" class="mono">…</dd>
|
|
875
|
+
<!-- Installed plugin packages and their versions, with a
|
|
876
|
+
one-line reason for any that failed to load. A failed
|
|
877
|
+
plugin has to be visible somewhere a human looks, or an
|
|
878
|
+
empty Lab tab becomes a debugging session. -->
|
|
879
|
+
<dt>plugins</dt><dd id="about-plugins" class="mono">…</dd>
|
|
880
|
+
</dl>
|
|
881
|
+
|
|
882
|
+
<!-- The site's terms. The BSD license disclaims warranties for
|
|
883
|
+
people who copy the code; a visitor here receives a service,
|
|
884
|
+
not the code, so the service needs its own words. The lede box
|
|
885
|
+
above the editor links to this section, which is what makes
|
|
886
|
+
"use signifies agreement" point at something. -->
|
|
887
|
+
<h6>Disclaimer</h6>
|
|
888
|
+
<p>aLL is a free research and educational tool built on the open
|
|
889
|
+
source <code>aggregate</code> library (BSD 3-Clause). All results
|
|
890
|
+
are provided as is, with no warranty of any kind. Nothing on this
|
|
891
|
+
site constitutes actuarial, financial, or other professional
|
|
892
|
+
advice, and no output is an actuarial communication within the
|
|
893
|
+
meaning of ASOP 41. Verify results independently before relying
|
|
894
|
+
on them. Submitted programs and sessions may be logged to operate
|
|
895
|
+
the service; do not submit confidential data. The service is
|
|
896
|
+
offered with no promise of availability and may change or be
|
|
897
|
+
withdrawn at any time. Third-party components are used under
|
|
898
|
+
their respective MIT, BSD, and Apache 2.0 licenses.</p>
|
|
899
|
+
|
|
900
|
+
<h6>Learn more</h6>
|
|
901
|
+
<p class="help-links mb-0">
|
|
902
|
+
<a href="https://aggregate.readthedocs.io/" target="_blank" rel="noopener">documentation</a> ·
|
|
903
|
+
<a href="https://aggregate.readthedocs.io/en/latest/4_dec_Language_Reference.html" target="_blank" rel="noopener">DecL reference</a> ·
|
|
904
|
+
<a href="https://github.com/mynl/aggregate" target="_blank" rel="noopener">github</a>
|
|
905
|
+
</p>
|
|
906
|
+
</div>
|
|
907
|
+
</div>
|
|
908
|
+
|
|
909
|
+
<!-- Vite entry point. main.js imports Bootstrap JS + icons, the
|
|
910
|
+
editor, and wires up the UI. -->
|
|
911
|
+
</body>
|
|
912
|
+
</html>
|