User Journey: Inspect a surface's slices
Table of Contents
This page documents a user journey: A trader or quant inspects a candidate surface's smiles across tenors and its mesh, and checks the calendar and butterfly arbitrage between them.
A user journey describes what one person is trying to do, before anything is built. It is a design document that outlives any sprint, so it names the screens, the entity fields each screen shows, and the operations and messages each step needs.
1. Goal
"I want to see the smiles this surface produces at each tenor, the mesh they make together, and whether the surface has an arbitrage in it." The journey is done when the person has read the smile at each tenor of interest, seen the mesh, and read the calendar and butterfly arbitrage checks. The person does not publish here.
2. Actor and trigger
The actor is the trader or the quant. The trader owns the candidate surface; the quant owns the model and reads the same screen. Neither decides to publish here: an approver does that in a different journey. The trigger is a calibration just run, a smile that looks odd at one tenor, a mesh that folds, or a pricing question about an expiry and a strike. The journey starts at a candidate surface and ends when the person leaves it, still a candidate.
This journey reads and diagnoses; it changes nothing. It is the surface-shaped check the maker runs before the candidate goes to a second pair of eyes.
3. Steps
- Open the candidate surface. The person opens Curves and surfaces and
selects the candidate surface. The system reads the
market_seriesrow and its =derivation_kind=/config/version, which says the surface is derived and by which recipe. - Read the surface. The person chooses Read surface. There is no surface
read:
marketdata.v1.curve_snapshot.getis keyed by anoresmd_uriand reconstructs curve or grid points, and it has no surface shape. The system lists the surface series row and the quotes it holds, and marks the surface itself as not served. See What is missing. - Read the smiles across tenors. The person picks a set of tenors and reads the smile at each. Each smile is a slice: the vol at a fixed expiry across strikes, from the low-strike put wing through the at-the-money point to the high-strike call wing. There is no slice read, so no smile can be drawn. See What is missing.
- Overlay the quotes on a smile. The person reads each raw quote of that
tenor against the fitted smile. The quotes come from
marketdata.v1.market_observations.list_by_series_id, one row peroresmd_uri, but the fitted smile does not exist to overlay them on. - Read the mesh. The person reads the mesh: the vol across expiry and strike at once, either as a grid or as a shaded total-variance view. The mesh needs the surface read of step 2 and a mesh read, and neither exists. See What is missing.
- Check calendar arbitrage. The person checks that total variance does not fall as expiry grows, at a fixed strike. No operation returns total variance along an expiry axis and no check runs, so the screen states the check it needs and marks it as absent. See What is missing.
- Check butterfly arbitrage. The person checks that the risk-neutral density implied by each smile is non-negative, which fails when a smile is too concave. No operation returns a density or a butterfly check, so the screen states the check it needs and marks it as absent. See What is missing.
- Leave. The person returns to the list. The candidate surface is unchanged; the person did not write or publish anything.
Every read here would be server-side and synchronous, so the journey carries no state of its own.
4. Screens and wireframes
One screen. The surface and the tenor picker sit at the top, the smiles and the mesh sit in the middle, and the two arbitrage checks sit at the foot, so the person reads the slices, then the whole surface, then its faults.
Figure 1: Surface slices: the smiles across tenors, the surface mesh, and the calendar and butterfly arbitrage checks.
5. Prototype
A static page at doc/prototypes/market_data/inspect-a-surfaces-slices/index.html: mock data only, no backend,
no build step and no session. It argues that a surface is read a slice at a time, and the arbitrage checks are what make the slices trustworthy.
- Variants
- a one slice at a tenor, b the mesh, c the arbitrage report
- States
- clean, butterfly (a negative implied density);
?tenor=picks the slice - Source
doc/prototypes/market_data/inspect-a-surfaces-slices/index.html- Open
/OreStudio/doc/prototypes/market_data/inspect-a-surfaces-slices/once the site is built, or the file directly
6. Entities composed
| Entity | What it contributes | Model |
|---|---|---|
market_series |
The surface identity: the oresmd_uri, its asset class, and its =derivation_kind=/config/version |
ores.marketdata.market_series |
market_observation |
The quotes each smile is calibrated from and checked against, one per oresmd_uri and observation_datetime |
ores.marketdata.market_observation |
observation_lineage |
The provenance of each derived surface point: which config/version and which source series it read | ores.marketdata.observation_lineage |
market_series_asset_class |
The asset class the surface list filters on | ores.marketdata.market_series_asset_class |
tenor |
The expiry axis labels the slices are named by | ores.refdata.tenor |
currency |
The currency the surface is quoted in | ores.refdata.currency |
There is no surface model and no slice model, so the smiles, the mesh and the two arbitrage checks have no entity to compose. The screen can read the series row and its quotes only; see What is missing.
7. Operations and messages
| Step | Operation | Subject | Status |
|---|---|---|---|
| Open the candidate surface | List the series that may be a surface | marketdata.v1.market_series.list |
exists |
| Open the candidate surface | Read one series | marketdata.v1.market_series.get |
exists |
| Read the surface | Read the surface | marketdata.v1.surface.get |
missing |
| Read the smiles | Read one smile (slice) | marketdata.v1.surface-slice.get |
missing |
| Overlay the quotes | List the observations of one series | marketdata.v1.market_observations.list_by_series_id |
exists |
| Read the mesh | Read the surface mesh | marketdata.v1.surface-mesh.get |
missing |
| Check calendar arbitrage | Read the calendar-arbitrage check | marketdata.v1.surface.arbitrage |
missing |
| Check butterfly arbitrage | Read the butterfly-arbitrage check | marketdata.v1.surface.arbitrage |
missing |
| Read the recipe lineage | Read the lineage of a derived point | marketdata.v1.observation_lineages.list |
exists |
| Check the change trail | Read the series' history | marketdata.v1.history.get |
exists |
No surface subject exists. Every surface read above is a candidate subject, not
a subject the server serves today. Only the series and observation reads, the
lineage read and the generic history read are real. The generic history read is
marketdata.v1.history.get with entity_type ores.marketdata.market_series;
market_series and observation_lineage register history providers.
8. What is missing
- There is no surface read. The subject
marketdata.v1.surface.getwould have to be added to return the fitted surface for anoresmd_uriand an as-of. Until then the screen shows the series row and marks the surface panel as not served. A surface model is the precondition: there is no table that carries the surface's axes, its quoting convention or its parameterisation. - There is no slice read. The subject
marketdata.v1.surface-slice.getwould have to be added to return the smile at one expiry: the vol at each strike, with the strike labels. Until then no smile can be drawn and the screen shows the raw quotes of that tenor alone. A strike-label vocabulary does not exist, so a strike axis cannot yet be labelled. - There is no mesh read. The subject
marketdata.v1.surface-mesh.getwould have to be added, or the surface read extended, to return the vol across expiry and strike as a grid. Until then the mesh panel is empty and labelled. - There is no arbitrage check of any kind. No operation exposes a residual,
a slice, a total variance or a density, so neither the calendar check nor
the butterfly check can run. The candidate is a subject such as
marketdata.v1.surface.arbitrage, returning the total variance along an expiry axis and the implied density along a smile. Until then the screen names both checks and marks them as absent, and it does not compute them on the client, because the client has no fitted surface to check. - The surface has no typed identity at the wire. Every read is keyed by the
oresmd_uristring, so a caller cannot ask for "the USD swaption surface" without knowing the URI spelling, and a slice cannot be addressed by expiry and strike. The candidate is a typed surface and slice read,marketdata.v1.surfaces.*. Until then the screen shows the URI as the identity. - A read cannot be taken as of a time in the past. The snapshot read always
reads now, so the person cannot inspect the surface as of the instant it
was calibrated. The candidate is an
as_ofparameter on the surface read. Until then the screen reads the current surface only.
9. Related journeys
- Calibrate or refresh a surface — build the candidate surface these slices come from.
- Adjust a curve or surface by hand — correct a smile where the market is thin.
- Check a curve's fit — the curve-shaped sibling of this check.
- Ask for a publish to be approved — send a sound surface to a second pair of eyes.
- Watch a curve or surface evolve — see how the published surface moved over the day.
10. Related knowledge
11. See also
- Market data journeys
- Author a surface's framework — set the axes and the model the slices are read in.
- Decide a publish — the approver reads a similar picture before deciding.
- User Journeys